commit 5acdebf6a1c0e0a5021b0a02da5745dd5b69c0a7
parent 65fabeab00b34c85d8585483e9dea5c9dcdb7f16
Author: Drew DeVault <sir@cmpwn.com>
Date: Sat, 26 Dec 2020 12:26:51 -0500
gen: implement array constants
Diffstat:
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