hare

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

commit 38baece7857592b5fe4e42d0a61d4512e32d6f22
parent c71b8626b8c4e05ef86f603246abdc395c08f9d1
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 14 May 2022 13:16:05 +0200

hare::types: complete type alias implementation

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Mhare/types/+test.ha | 34++++++++++++++++++++++++++++++++++
Mhare/types/store.ha | 43+++++++++++++++++++++++++++++++++++++++++++
2 files changed, 77 insertions(+), 0 deletions(-)

diff --git a/hare/types/+test.ha b/hare/types/+test.ha @@ -336,3 +336,37 @@ fn resolve( assert(t[1].repr as builtin == builtin::VOID); assert(t[2].repr as builtin == builtin::STR); }; + +@test fn alias() void = { + let st = store(x86_64, &resolve, null); + defer store_free(st); + + const of = lookup_builtin(st, ast::builtin_type::U64); + const al = createalias(st, ["myalias"], of); + assert(al.sz == 8); + assert(al.align == 8); + assert(al.flags == 0); + assert((al.repr as alias).secondary == of); + + const atype = parse_type("myalias"); + defer ast::type_finish(atype); + const htype = lookup(st, &atype)!; + assert(htype == al); +}; + +@test fn forwardref() void = { + let st = store(x86_64, &resolve, null); + defer store_free(st); + + const atype = parse_type("myalias"); + defer ast::type_finish(atype); + const htype = lookup(st, &atype)!; + assert((htype.repr as alias).secondary == null); + + const of = lookup_builtin(st, ast::builtin_type::U64); + const al = createalias(st, ["myalias"], of); + assert(htype.sz == 8); + assert(htype.align == 8); + assert(htype.flags == 0); + assert((htype.repr as alias).secondary == of); +}; diff --git a/hare/types/store.ha b/hare/types/store.ha @@ -54,6 +54,49 @@ export fn store_free(store: *typestore) void = { free(store); }; +// Creates a new type alias. +export fn createalias( + store: *typestore, + ident: const ast::ident, + of: const *_type, +) const *_type = { + const atype: _type = _type { + flags = of.flags, + repr = alias { + id = ast::ident_dup(ident), + secondary = of, + }, + id = 0, + sz = of.sz, + align = of.align, + }; + const id = hash(&atype); + atype.id = id; + + // Fill in forward-referenced aliases + match (lookup(store, &ast::_type { + repr = ast::alias_type { + unwrap = false, + ident = ident, + }, + ... + })) { + case error => + yield; + case deferred => + yield; + case let ty: const *_type => + let ty = ty: *_type; + *ty = atype; + return ty; + }; + + // Or create a new alias + let bucket = &store.map[id % BUCKETS]; + append(bucket, atype); + return &bucket[len(bucket) - 1]; +}; + // Returned from [[lookup]] when we are unable to resolve this type, but it does // not necessarily have an error. This occurs when a type includes an unknown // forward reference.