harec

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

commit f89dd7c11cb28821d40d8081f0806b979b723d79
parent 5b2bea4b8b7a9176c560fef287b5493ff70b68b7
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Fri, 13 Aug 2021 09:15:32 +0000

insert: implement auto-deref

Signed-off-by: Eyal Sawady <ecs@d2evs.net>

Diffstat:
Msrc/check.c | 9+++++++--
Msrc/gen.c | 5+++--
Mtests/28-insert.ha | 9++++++---
3 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/src/check.c b/src/check.c @@ -1651,12 +1651,17 @@ check_expr_insert(struct context *ctx, assert(expr->insert.expr->type == EXPR_ACCESS && expr->insert.expr->access.type == ACCESS_INDEX); const struct type *sltype = expr->insert.expr->access.array->result; - if (type_dealias(sltype)->storage != STORAGE_SLICE) { + sltype = type_dereference(sltype); + if (!sltype) { + return error(aexpr->access.array->loc, expr, errors, + "Cannot dereference nullable pointer for insert"); + } + if (sltype->storage != STORAGE_SLICE) { return error(aexpr->insert.expr->loc, expr, errors, "cannot insert into non-slice type %s", type_storage_unparse(type_dealias(sltype)->storage)); } - if (type_dealias(sltype)->flags & TYPE_CONST) { + if (sltype->flags & TYPE_CONST) { return error(aexpr->insert.expr->loc, expr, errors, "insert must operate on a mutable slice"); } diff --git a/src/gen.c b/src/gen.c @@ -1669,11 +1669,12 @@ gen_expr_insert(struct gen_context *ctx, const struct expression *expr) && objexpr->access.type == ACCESS_INDEX); const struct expression *arrayexpr = objexpr->access.array; - struct gen_value slice = gen_expr_access_addr(ctx, arrayexpr); + struct gen_value slice = gen_expr(ctx, arrayexpr); + slice = gen_autoderef(ctx, slice); struct gen_value index = gen_expr(ctx, objexpr->access.index); struct qbe_value qindex = mkqval(ctx, &index); - const struct type *sltype = type_dealias(arrayexpr->result); + const struct type *sltype = type_dereference(arrayexpr->result); const struct type *mtype = type_dealias(sltype)->array.members; enum qbe_instr load = load_for_type(ctx, &builtin_type_size); diff --git a/tests/28-insert.ha b/tests/28-insert.ha @@ -20,7 +20,8 @@ fn basics() void = { let x: []int = alloc([], 9); defer free(x); append(x, 1, 2, 3, 4, 5, 6); - insert(x[2], 7, 8, 9); + let y = &x; + insert(y[2], 7, 8, 9); assert(sleq(x, [1, 2, 7, 8, 9, 3, 4, 5, 6])); }; @@ -33,8 +34,10 @@ fn variadic() void = { let x: []int = []; defer free(x); - append(x, 1, 2, 3, 4, 5, 6); - insert(x[2], 7, 8, 9, [10, 11, 12]...); + let y = &x; + let z = &y; + append(y, 1, 2, 3, 4, 5, 6); + insert(z[2], 7, 8, 9, [10, 11, 12]...); assert(sleq(x, [1, 2, 7, 8, 9, 10, 11, 12, 3, 4, 5, 6])); };