harec

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

commit fcad12cb2d08578feab5ef01502c15c612632095
parent 95be8cc07bbd588dfd42ca1cf85e1f89ab39fa2b
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 30 Jan 2021 13:15:14 -0500

Implement slice globals

Diffstat:
Msrc/eval.c | 8++++++--
Msrc/gen.c | 40+++++++++++++++++++++++++++++++++++++++-
Mtests/11-globals.ha | 12++++++++++++
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(); };