harec

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

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:
Msrc/check.c | 6++++++
Msrc/gen.c | 19+++++++++++++++++++
Mtests/01-arrays.ha | 8++++++++
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 = {