harec

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

commit 6a7e41acb0ba1eed37d06f6fe601cec20535db6c
parent dfc768c822f78bd45cf20fbbf1a3a0dbf22a1561
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun, 22 Aug 2021 15:29:04 +0200

eval, gen: implement tagged types

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

Diffstat:
Minclude/expr.h | 6++++++
Msrc/eval.c | 15+++++++++++++--
Msrc/gen.c | 7+++++++
Mtests/11-globals.ha | 9+++++++++
4 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/include/expr.h b/include/expr.h @@ -171,6 +171,11 @@ struct tuple_constant { struct tuple_constant *next; }; +struct tagged_constant { + const struct type *tag; + struct expression *value; +}; + struct expression_constant { // If non-null, ival is an offset from this object's address const struct scope_object *object; @@ -187,6 +192,7 @@ struct expression_constant { struct array_constant *array; struct struct_constant *_struct; struct tuple_constant *tuple; + struct tagged_constant tagged; }; }; diff --git a/src/eval.c b/src/eval.c @@ -380,6 +380,7 @@ eval_cast(struct context *ctx, struct expression *in, struct expression *out) out->type = EXPR_CONSTANT; out->result = to; + const struct type *subtype; switch (to->storage) { case STORAGE_POINTER: if (from->storage == STORAGE_NULL) { @@ -431,11 +432,21 @@ eval_cast(struct context *ctx, struct expression *in, struct expression *out) ftrunc(to, (double)val.constant.uval); } return EVAL_OK; + case STORAGE_TAGGED: + subtype = tagged_select_subtype(to, from); + out->constant.tagged.value = + xcalloc(1, sizeof(struct expression)); + if (subtype) { + out->constant.tagged.tag = subtype; + *out->constant.tagged.value = val; + } else { + out->constant.tagged.tag = from; + *out->constant.tagged.value = val; + } + return EVAL_OK; case STORAGE_CHAR: case STORAGE_ENUM: case STORAGE_NULL: - case STORAGE_TAGGED: - assert(0); // TODO case STORAGE_ALIAS: assert(0); // Handled above case STORAGE_BOOL: diff --git a/src/gen.c b/src/gen.c @@ -2628,6 +2628,7 @@ gen_expr_with(struct gen_context *ctx, static struct qbe_data_item *gen_data_item(struct gen_context *, struct expression *, struct qbe_data_item *); + static void gen_function_decl(struct gen_context *ctx, const struct declaration *decl) { @@ -3035,6 +3036,12 @@ gen_data_item(struct gen_context *ctx, struct expression *expr, } break; case STORAGE_TAGGED: + item->type = QD_VALUE; + item->value = constw((uint32_t)constant->tagged.tag->id); + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + gen_data_item(ctx, constant->tagged.value, item); + break; case STORAGE_UNION: assert(0); // TODO case STORAGE_ALIAS: diff --git a/tests/11-globals.ha b/tests/11-globals.ha @@ -68,6 +68,15 @@ fn pointers() void = { assert(ptr == &val && *ptr == val); }; +type foo = (int | uint); + +let subtype: foo = 10u; + +fn tagged() void = { + assert(subtype is uint); + // TODO: subset-compat +}; + export fn main() void = { // TODO: Expand this test: // - Declare & validate globals of more types