commit 6e99b03605977e9b357315de51894fb1d42a995c
parent 4ca07c38df734a99ea5162bafd04b871add59be2
Author: Eyal Sawady <ecs@d2evs.net>
Date: Fri, 1 Jan 2021 13:46:06 -0500
Implement implicit dereferencing
Also update array tests
Diffstat:
3 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/src/check.c b/src/check.c
@@ -72,6 +72,12 @@ check_expr_access(struct context *ctx,
check_expression(ctx, aexpr->access.index, expr->access.index);
const struct type *atype = expr->access.array->result;
const struct type *itype = expr->access.index->result;
+ while (atype->storage == TYPE_STORAGE_POINTER) {
+ expect(&aexpr->access.array->loc,
+ !(atype->pointer.flags & PTR_NULLABLE),
+ "Cannot index nullable pointer");
+ atype = atype->pointer.referent;
+ }
expect(&aexpr->access.array->loc,
atype->storage == TYPE_STORAGE_ARRAY || atype->storage == TYPE_STORAGE_SLICE,
"Cannot index non-array, non-slice object");
diff --git a/src/gen.c b/src/gen.c
@@ -288,12 +288,31 @@ gen_expr_access_index(struct gen_context *ctx,
const struct qbe_value *out)
{
const struct type *atype = expr->access.array->result;
+ while (atype->storage == TYPE_STORAGE_POINTER) {
+ atype = atype->pointer.referent;
+ }
assert(atype->storage == TYPE_STORAGE_ARRAY); // TODO: Slices
struct qbe_value obj = {0};
gen_temp(ctx, &obj, &qbe_long, "object.%d"); // XXX: ARCH
gen_expression(ctx, expr->access.array, &obj);
+ atype = expr->access.array->result;
+ if (atype->storage == TYPE_STORAGE_POINTER) {
+ // We get one dereference for free because the array is stored
+ // indirectly
+ atype = atype->pointer.referent;
+ }
+ while (atype->storage == TYPE_STORAGE_POINTER) {
+ qval_deref(&obj);
+ struct qbe_value deref;
+ gen_loadtemp(ctx, &deref, &obj,
+ qtype_for_type(ctx, atype->pointer.referent, false),
+ type_is_signed(atype->pointer.referent));
+ obj = deref;
+ atype = atype->pointer.referent;
+ }
+
struct qbe_value index = {0};
gen_temp(ctx, &index, &qbe_long, "index.%d");
gen_expression(ctx, expr->access.index, &index);
diff --git a/tests/01-arrays.ha b/tests/01-arrays.ha
@@ -1,8 +1,16 @@
fn indexing() void = {
let x = [1, 2, 3];
+ let y = &x;
+ let z = &y;
assert(x[0] == 1);
assert(x[1] == 2);
assert(x[2] == 3);
+ assert(y[0] == 1);
+ assert(y[1] == 2);
+ assert(y[2] == 3);
+ assert(z[0] == 1);
+ assert(z[1] == 2);
+ assert(z[2] == 3);
};
fn measurements() void = {