commit fcad12cb2d08578feab5ef01502c15c612632095
parent 95be8cc07bbd588dfd42ca1cf85e1f89ab39fa2b
Author: Drew DeVault <sir@cmpwn.com>
Date: Sat, 30 Jan 2021 13:15:14 -0500
Implement slice globals
Diffstat:
3 files changed, 57 insertions(+), 3 deletions(-)
diff --git a/src/eval.c b/src/eval.c
@@ -241,6 +241,7 @@ eval_const(struct context *ctx, struct expression *in, struct expression *out)
aconst->expand = arr->expand;
aconst->value = xcalloc(sizeof(struct expression), 1);
eval_expr(ctx, arr->value, aconst->value);
+ next = &aconst->next;
}
break;
case TYPE_STORAGE_FUNCTION:
@@ -321,14 +322,17 @@ eval_cast(struct context *ctx, struct expression *in, struct expression *out)
case TYPE_STORAGE_SIZE:
out->constant.uval = itrunc(to, in->constant.uval);
return EVAL_OK;
+ case TYPE_STORAGE_ARRAY:
+ case TYPE_STORAGE_SLICE:
+ assert(val.result->storage == TYPE_STORAGE_ARRAY);
+ out->constant = val.constant;
+ return EVAL_OK;
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
case TYPE_STORAGE_CHAR:
case TYPE_STORAGE_ENUM:
case TYPE_STORAGE_NULL:
case TYPE_STORAGE_RUNE:
- case TYPE_STORAGE_ARRAY:
- case TYPE_STORAGE_SLICE:
case TYPE_STORAGE_TAGGED_UNION:
assert(0); // TODO
case TYPE_STORAGE_ALIAS:
diff --git a/src/gen.c b/src/gen.c
@@ -2175,8 +2175,46 @@ gen_data_item(struct gen_context *ctx, struct expression *expr,
item->type = QD_VALUE;
constl(&item->value, expr->constant.string.len);
break;
- case TYPE_STORAGE_ENUM:
case TYPE_STORAGE_SLICE:
+ def = xcalloc(1, sizeof(struct qbe_def));
+ def->name = gen_name(ctx, "sldata.%d");
+ def->kind = Q_DATA;
+
+ struct qbe_data_item *subitem = &def->data.items;
+ size_t len = 0;
+ for (struct array_constant *c = constant->array;
+ c; c = c->next) {
+ gen_data_item(ctx, c->value, subitem);
+ if (c->next) {
+ subitem->next = xcalloc(1,
+ sizeof(struct qbe_data_item));
+ subitem = subitem->next;
+ }
+ ++len;
+ }
+
+ if (len != 0) {
+ qbe_append_def(ctx->out, def);
+ item->type = QD_VALUE;
+ item->value.kind = QV_GLOBAL;
+ item->value.type = &qbe_long;
+ item->value.name = strdup(def->name);
+ } else {
+ free(def);
+ item->type = QD_VALUE;
+ constl(&item->value, 0);
+ }
+
+ item->next = xcalloc(1, sizeof(struct qbe_data_item));
+ item = item->next;
+ item->type = QD_VALUE;
+ constl(&item->value, len);
+ item->next = xcalloc(1, sizeof(struct qbe_data_item));
+ item = item->next;
+ item->type = QD_VALUE;
+ constl(&item->value, len);
+ break;
+ case TYPE_STORAGE_ENUM:
case TYPE_STORAGE_STRUCT:
case TYPE_STORAGE_TAGGED_UNION:
case TYPE_STORAGE_UNION:
diff --git a/tests/11-globals.ha b/tests/11-globals.ha
@@ -8,6 +8,17 @@ fn write() void = {
assert(x == 1337);
};
+let ar: [3]int = [1, 2, 3];
+let sl: []int = [1, 2, 3];
+
+fn storage() void = {
+ assert(len(ar) == 3z);
+ assert(ar[0] == 1 && ar[1] == 2 && ar[2] == 3);
+
+ assert(len(sl) == 3z);
+ assert(sl[0] == 1 && sl[1] == 2 && sl[2] == 3);
+};
+
fn invariants() void = {
assert(rt::compile("fn test() int; let x: int = test();") != 0);
};
@@ -29,6 +40,7 @@ export fn main() void = {
// - Declare & validate globals of more types
// - Globals which are pointers to other globals
write();
+ storage();
invariants();
static_binding();
};