commit d8fb82a155425dd41f129af6d570b262ac4df763
parent 08368a2643f3d8604d7c299089dda3aa5c22dc64
Author: Jean Dao <jean@pfudke.fr>
Date: Tue, 26 Apr 2022 18:14:44 +0200
gen: support copying global struct
Signed-off-by: Jean Dao <jean@pfudke.fr>
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
2 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/src/gen.c b/src/gen.c
@@ -1744,6 +1744,26 @@ gen_const_string_at(struct gen_context *ctx,
}
static void
+gen_const_struct_at(struct gen_context *ctx,
+ const struct expression *expr, struct gen_value out)
+{
+ // TODO: Merge me into constant expressions
+ struct qbe_value base = mkqval(ctx, &out);
+
+ struct gen_value ftemp = mkgtemp(ctx, &builtin_type_void, "field.%d");
+ for (const struct struct_constant *field = expr->constant._struct;
+ field; field = field->next) {
+ assert(field->value);
+
+ struct qbe_value offs = constl(field->field->offset);
+ ftemp.type = field->value->result;
+ struct qbe_value ptr = mklval(ctx, &ftemp);
+ pushi(ctx->current, &ptr, Q_ADD, &base, &offs, NULL);
+ gen_expr_at(ctx, field->value, ftemp);
+ }
+}
+
+static void
gen_expr_const_at(struct gen_context *ctx,
const struct expression *expr, struct gen_value out)
{
@@ -1759,6 +1779,9 @@ gen_expr_const_at(struct gen_context *ctx,
case STORAGE_STRING:
gen_const_string_at(ctx, expr, out);
break;
+ case STORAGE_STRUCT:
+ gen_const_struct_at(ctx, expr, out);
+ break;
default:
abort(); // Invariant
}
diff --git a/tests/26-gen.ha b/tests/26-gen.ha
@@ -10,6 +10,14 @@ type thing = struct {
e: embedded,
};
+def THING: thing = thing{
+ offs = 0,
+ e = embedded {
+ a = 1,
+ b = 0,
+ },
+};
+
export fn main() void = {
let t = thing {
offs = 0,
@@ -21,6 +29,12 @@ export fn main() void = {
let t = t;
assert(t.e.a == 1);
+ let t2 = THING;
+ assert(t2.e.a == 1);
+
+ t2.offs = 42;
+ assert(THING.offs == 0);
+
let x: (void | int) = 10;
match (x) {
case let i: int =>