harec

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

commit a60d3783c8fec5fc133cc1bddd8552e48c1399a1
parent 8c31e681ffbeb80bcb45e631ba91cf43525bb39b
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri, 15 Jan 2021 12:15:57 -0500

type store: basic tagged union assignment rules

Diffstat:
Msrc/type_store.c | 27+++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/src/type_store.c b/src/type_store.c @@ -26,6 +26,29 @@ ast_array_len(struct type_store *store, const struct ast_type *atype) return (size_t)out.constant.uval; } +static bool +tagged_assignable(struct type_store *store, + const struct type *to, + const struct type *from) +{ + if (from->storage == TYPE_STORAGE_TAGGED_UNION) { + assert(0); // TODO + } + + size_t nassignable = 0; + for (const struct type_tagged_union *tu = &to->tagged; + tu; tu = tu->next) { + if (tu->type->id == from->id) { + return true; + } + if (type_is_assignable(store, tu->type, from)) { + ++nassignable; + } + } + + return nassignable == 1; +} + bool type_is_assignable(struct type_store *store, const struct type *to, @@ -110,8 +133,6 @@ type_is_assignable(struct type_store *store, case TYPE_STORAGE_ALIAS: return type_is_assignable(store, to->alias.type, from); case TYPE_STORAGE_ENUM: - case TYPE_STORAGE_TAGGED_UNION: - assert(0); // TODO case TYPE_STORAGE_STRING: return to == &builtin_type_const_ptr_char; case TYPE_STORAGE_VOID: @@ -129,6 +150,8 @@ type_is_assignable(struct type_store *store, return from->storage == TYPE_STORAGE_ARRAY && to->array.length == SIZE_UNDEFINED && from->array.length != SIZE_UNDEFINED; + case TYPE_STORAGE_TAGGED_UNION: + return tagged_assignable(store, to, from); // The following types are only assignable from themselves, and are // handled above: case TYPE_STORAGE_BOOL: