harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit ae4c3c71a23f1b9d496c106a43aa434b2b0562f4
parent af16fa5d315b6f30b0e999e31c18d763839b7d93
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 16 Jan 2021 09:55:57 -0500

type store: implement tagged mutual assignment

Diffstat:
Msrc/type_store.c | 20+++++++++++++++++++-
Mtests/13-tagged.ha | 10++++++++++
2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/src/type_store.c b/src/type_store.c @@ -32,7 +32,22 @@ tagged_assignable(struct type_store *store, const struct type *from) { if (from->storage == TYPE_STORAGE_TAGGED_UNION) { - assert(0); // TODO + if (to->storage != TYPE_STORAGE_TAGGED_UNION) { + return false; + } + // Only assignable if 'to' is a superset of 'from' + // Invariant: type_tagged_union is sorted by type tag + const struct type_tagged_union *to_t = &to->tagged; + const struct type_tagged_union *from_t = &from->tagged; + while (to_t && from_t) { + if (to_t->type->id == from_t->type->id) { + to_t = to_t->next; + from_t = from_t->next; + } else { + from_t = from_t->next; + } + } + return from_t == NULL; } size_t nassignable = 0; @@ -171,6 +186,9 @@ static bool tagged_castable(const struct type *to, const struct type *from) { if (to->storage == TYPE_STORAGE_TAGGED_UNION) { + if (from->storage == TYPE_STORAGE_TAGGED_UNION) { + return true; + } assert(0); // TODO } diff --git a/tests/13-tagged.ha b/tests/13-tagged.ha @@ -40,9 +40,19 @@ fn operators() void = { assert(x is u64); }; +fn reduction() void = { + let a: (i8 | i16) = 42i8; + let b: (i16 | i8) = a; + let c: (i8 | i16 | i32) = a; + assert(a is i8); + assert(b is i8); + assert(c is i8); +}; + export fn main() void = { measurements(); storage(); operators(); + reduction(); // TODO: Expand this as other tagged union features become available };