commit 344e88beffb7936c3260a38d413f5ea562f3207b
parent 62762c8f21f90bf8b52c8de1a2358c07c89323ac
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 1 Feb 2021 15:21:26 -0500
gen: implement struct globals
Diffstat:
4 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/include/expr.h b/include/expr.h
@@ -149,6 +149,7 @@ struct array_constant {
bool expand;
};
+// Invariant: these are sorted by field offset
struct struct_constant {
const struct struct_field *field;
struct expression *value;
diff --git a/src/eval.c b/src/eval.c
@@ -385,6 +385,7 @@ enum eval_result
eval_struct(struct context *ctx, struct expression *in, struct expression *out)
{
assert(in->type == EXPR_STRUCT);
+ assert(type_dealias(in->result)->storage != TYPE_STORAGE_UNION); // TODO
out->type = EXPR_CONSTANT;
size_t n = 0;
diff --git a/src/gen.c b/src/gen.c
@@ -2260,8 +2260,8 @@ gen_data_item(struct gen_context *ctx, struct expression *expr,
def->name = gen_name(ctx, "sldata.%d");
def->kind = Q_DATA;
- struct qbe_data_item *subitem = &def->data.items;
size_t len = 0;
+ struct qbe_data_item *subitem = &def->data.items;
for (struct array_constant *c = constant->array;
c; c = c->next) {
gen_data_item(ctx, c->value, subitem);
@@ -2293,8 +2293,18 @@ gen_data_item(struct gen_context *ctx, struct expression *expr,
item->type = QD_VALUE;
constl(&item->value, len);
break;
- case TYPE_STORAGE_ENUM:
case TYPE_STORAGE_STRUCT:
+ for (struct struct_constant *f = constant->_struct;
+ f; f = f->next) {
+ gen_data_item(ctx, f->value, item);
+ if (f->next) {
+ item->next = xcalloc(1,
+ sizeof(struct qbe_data_item));
+ item = item->next;
+ }
+ }
+ break;
+ case TYPE_STORAGE_ENUM:
case TYPE_STORAGE_TAGGED:
case TYPE_STORAGE_UNION:
assert(0); // TODO
diff --git a/tests/11-globals.ha b/tests/11-globals.ha
@@ -8,9 +8,11 @@ fn write() void = {
assert(x == 1337);
};
+type coords = struct { x: int, y: int };
let ar: [3]int = [1, 2, 3];
let sl: []int = [1, 2, 3];
let st: str = "Hello!";
+let su: coords = coords { y = 10, x = 20 };
fn storage() void = {
assert(len(ar) == 3z);
@@ -18,6 +20,7 @@ fn storage() void = {
assert(len(sl) == 3z);
assert(sl[0] == 1 && sl[1] == 2 && sl[2] == 3);
assert(len(st) == 6z);
+ assert(su.x == 20 && su.y == 10);
};
fn invariants() void = {