harec

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

commit 5acdebf6a1c0e0a5021b0a02da5745dd5b69c0a7
parent 65fabeab00b34c85d8585483e9dea5c9dcdb7f16
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 26 Dec 2020 12:26:51 -0500

gen: implement array constants

Diffstat:
Msrc/gen.c | 33++++++++++++++++++++++++++++++---
Msrc/qtype.c | 3++-
Msrc/type_store.c | 4++++
Mtodo.txt | 4++++
4 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -254,9 +254,6 @@ gen_binding(struct gen_context *ctx, const struct expression_binding *binding = &expr->binding; while (binding) { - const struct type *type = binding->object->type; - assert(!type_is_aggregate(type)); // TODO - struct qbe_value temp = {0}; binding_alloc(ctx, binding->object, &temp, "binding.%d"); gen_expression(ctx, binding->initializer, &temp); @@ -325,6 +322,33 @@ gen_call(struct gen_context *ctx, } static void +gen_array(struct gen_context *ctx, + const struct expression *expr, + const struct qbe_value *out) +{ + assert(!expr->result->array.expandable); // TODO + + struct qbe_value offs = {0}, size = {0}; + gen_temp(ctx, &offs, + qtype_for_type(ctx, &builtin_type_size, false), + "offset.%d"); + constl(&size, 0); // XXX: ARCH + pushi(ctx->current, &offs, Q_COPY, out, NULL); + constl(&size, expr->result->array.members->size); // XXX: ARCH + offs.indirect = true; + offs.type = qtype_for_type(ctx, expr->result->array.members, true); + + struct array_constant *item = expr->constant.array; + while (item) { + gen_expression(ctx, item->value, &offs); + if (item->next) { + pushi(ctx->current, &offs, Q_ADD, &offs, &size, NULL); + } + item = item->next; + } +} + +static void gen_constant(struct gen_context *ctx, const struct expression *expr, const struct qbe_value *out) @@ -350,6 +374,9 @@ gen_constant(struct gen_context *ctx, constl(&val, 0); gen_store(ctx, out, &val); return; + case TYPE_STORAGE_ARRAY: + gen_array(ctx, expr, out); + return; default: // Moving right along break; diff --git a/src/qtype.c b/src/qtype.c @@ -120,8 +120,9 @@ qtype_for_type(struct gen_context *ctx, const struct type *type, bool extended) case TYPE_STORAGE_F64: case TYPE_STORAGE_VOID: return qtype_for_xtype(qstype_for_type(type)); - case TYPE_STORAGE_ALIAS: case TYPE_STORAGE_ARRAY: + return qtype_for_xtype(Q__AGGREGATE); + case TYPE_STORAGE_ALIAS: case TYPE_STORAGE_ENUM: case TYPE_STORAGE_SLICE: case TYPE_STORAGE_STRING: diff --git a/src/type_store.c b/src/type_store.c @@ -398,7 +398,11 @@ type_eq_type(struct type_store *store, case TYPE_STORAGE_VOID: return true; case TYPE_STORAGE_ALIAS: + assert(0); // TODO case TYPE_STORAGE_ARRAY: + return a->array.length == b->array.length + && a->array.expandable == b->array.expandable + && type_eq_type(store, a->array.members, b->array.members); case TYPE_STORAGE_ENUM: assert(0); // TODO case TYPE_STORAGE_FUNCTION: diff --git a/todo.txt b/todo.txt @@ -10,3 +10,7 @@ highest priorities, unordered except where there are obvious dependencies: This subset of features should allow us to address most of the problems with gen that v1 suffered from, and end up with a solid basis from which we can confidently implement the remainder of the features. + +general todos, includes spec updates: +- zero-length arrays & slice initializers +- allocations