commit 64d200943c131a916ff7ee08c28725151b53b0d0
parent 51ab3fb0a32e876426b96d71a790abd6b88a4456
Author: Eyal Sawady <ecs@d2evs.net>
Date: Thu, 6 May 2021 13:23:36 -0400
hare::types: implement lookup for function types
Signed-off-by: Eyal Sawady <ecs@d2evs.net>
Diffstat:
2 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/hare/types/+test.ha b/hare/types/+test.ha
@@ -271,3 +271,32 @@ fn resolve(
assert(array.member._type as builtin == builtin::I32);
assert(array.length == SIZE_UNDEFINED);
};
+
+@test fn funcs() void = {
+ let st = store(x86_64, &resolve, null);
+ defer store_free(st);
+
+ let atype = parse_type("@noreturn fn() void");
+ defer ast::type_free(atype);
+ let htype = lookup(st, &atype)!;
+ assert(htype.sz == SIZE_UNDEFINED);
+ assert(htype.align == SIZE_UNDEFINED);
+ let f = htype._type as func;
+ assert(f.result._type as builtin == builtin::VOID);
+ assert(f.variadism == variadism::NONE);
+ assert(f.flags == func_flags::NORETURN);
+ assert(len(f.params) == 0);
+
+ let atype = parse_type("fn(foo: int, bar: str...) int");
+ defer ast::type_free(atype);
+ let htype = lookup(st, &atype)!;
+ assert(htype.sz == SIZE_UNDEFINED);
+ assert(htype.align == SIZE_UNDEFINED);
+ let f = htype._type as func;
+ assert(f.result._type as builtin == builtin::INT);
+ assert(f.variadism == variadism::HARE);
+ assert(f.flags == 0);
+ assert(len(f.params) == 2);
+ assert(f.params[0]._type as builtin == builtin::INT);
+ assert(f.params[1]._type as builtin == builtin::STR);
+};
diff --git a/hare/types/store.ha b/hare/types/store.ha
@@ -186,6 +186,7 @@ fn fromast(store: *typestore, atype: *ast::_type) (_type | deferred | error) = {
ast::builtin_type::ICONST,
ast::builtin_type::FCONST => abort(), // TODO?
},
+ f: ast::func_type => func_from_ast(store, &f)?,
p: ast::pointer_type => {
sz = store.arch._pointer;
align = store.arch._pointer;
@@ -243,7 +244,6 @@ fn fromast(store: *typestore, atype: *ast::_type) (_type | deferred | error) = {
r.2;
},
ta: ast::tagged_type => abort(), // TODO
- func: ast::func_type => abort(), // TODO
et: ast::enum_type => abort(), // TODO
};
return _type {
@@ -254,6 +254,29 @@ fn fromast(store: *typestore, atype: *ast::_type) (_type | deferred | error) = {
};
};
+fn func_from_ast(
+ store: *typestore,
+ ft: *ast::func_type,
+) (func | deferred | error) = {
+ let f = func {
+ result = lookup(store, ft.result)?,
+ variadism = switch (ft.variadism) {
+ ast::variadism::NONE => variadism::NONE,
+ ast::variadism::C => variadism::C,
+ ast::variadism::HARE => variadism::HARE,
+ },
+ flags = 0,
+ params = alloc([], len(ft.params)),
+ };
+ if (ft.attrs & ast::func_attrs::NORETURN != 0) {
+ f.flags |= func_flags::NORETURN;
+ };
+ for (let i = 0z; i < len(ft.params); i += 1) {
+ append(f.params, lookup(store, ft.params[i]._type)?);
+ };
+ return f;
+};
+
fn list_from_ast(
store: *typestore,
lt: *ast::list_type