harec

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

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:
Msrc/gen.c | 23+++++++++++++++++++++++
Mtests/26-gen.ha | 14++++++++++++++
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 =>