commit 5356bf2c33b559bab2fb96b8fabb5abb00b83c1e
parent e661eb2c41179d33b9ed3ad9d9626a3c5096f6d0
Author: Armin Weigl <tb46305@gmail.com>
Date: Wed, 3 Aug 2022 19:32:45 +0200
gen_expr_const_at: implement tagged unions
Signed-off-by: Armin Weigl <tb46305@gmail.com>
Diffstat:
2 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/src/gen.c b/src/gen.c
@@ -1864,6 +1864,26 @@ gen_const_struct_at(struct gen_context *ctx,
}
static void
+gen_const_tagged_at(struct gen_context *ctx,
+ const struct expression *expr, struct gen_value out)
+{
+ struct qbe_value qout = mklval(ctx, &out);
+ const struct type *subtype = expr->constant.tagged.tag;
+ struct qbe_value id = constw(subtype->id);
+ enum qbe_instr store = store_for_type(ctx, &builtin_type_uint);
+ pushi(ctx->current, NULL, store, &id, &qout, NULL);
+ if (subtype->size == 0) {
+ return;
+ }
+
+ struct gen_value storage = mkgtemp(ctx, subtype, ".%d");
+ struct qbe_value qstor = mklval(ctx, &storage);
+ struct qbe_value offs = constl(expr->result->align);
+ pushi(ctx->current, &qstor, Q_ADD, &qout, &offs, NULL);
+ gen_expr_at(ctx, expr->constant.tagged.value, storage);
+}
+
+static void
gen_expr_const_at(struct gen_context *ctx,
const struct expression *expr, struct gen_value out)
{
@@ -1882,6 +1902,9 @@ gen_expr_const_at(struct gen_context *ctx,
case STORAGE_STRUCT:
gen_const_struct_at(ctx, expr, out);
break;
+ case STORAGE_TAGGED:
+ gen_const_tagged_at(ctx, expr, out);
+ break;
default:
abort(); // Invariant
}
diff --git a/tests/13-tagged.ha b/tests/13-tagged.ha
@@ -237,6 +237,12 @@ fn reject() void = {
) as exited != EXIT_SUCCESS);
};
+def val1: integer = 8u8;
+
+fn translation() void = {
+ assert(val1 as u8 == 8u8);
+};
+
export fn main() void = {
measurements();
storage();
@@ -248,4 +254,5 @@ export fn main() void = {
castout();
assertions();
reject();
+ translation();
};