hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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:
Mhare/types/+test.ha | 29+++++++++++++++++++++++++++++
Mhare/types/store.ha | 25++++++++++++++++++++++++-
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