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:
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.