harec

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

commit 56df61bf43f74e2db69da74aba46bd7ee1c4e733
parent 063f7b1ecdf8698f0174bb922832521779b483c3
Author: Drew DeVault <sir@cmpwn.com>
Date:   Mon, 22 Feb 2021 19:29:25 -0500

all: simplify alloc expressions

I have a sneaking suspicion that I've missed something here

Diffstat:
Minclude/ast.h | 1-
Msrc/check.c | 28+++++++++++++++++++++-------
Msrc/gen.c | 2+-
Msrc/parse.c | 2--
Mtests/17-alloc.ha | 24++++++++++++------------
Mtests/19-append.ha | 10+++++-----
Mtests/22-delete.ha | 4++--
7 files changed, 41 insertions(+), 30 deletions(-)

diff --git a/include/ast.h b/include/ast.h @@ -131,7 +131,6 @@ struct ast_expression_access { struct ast_expression_alloc { struct ast_expression *expr; - struct ast_type *type; struct ast_expression *cap; }; diff --git a/src/check.c b/src/check.c @@ -188,13 +188,29 @@ check_expr_alloc(struct context *ctx, trace(TR_CHECK, "alloc"); expr->type = EXPR_ALLOC; expr->alloc.expr = xcalloc(sizeof(struct expression), 1); - expr->result = - type_store_lookup_atype(ctx->store, aexpr->alloc.type); - enum type_storage storage = type_dealias(expr->result)->storage; + const struct type *inittype = NULL; + if (hint && type_dealias(hint)->storage == STORAGE_POINTER) { + inittype = type_dealias(hint)->pointer.referent; + } else if (hint && type_dealias(hint)->storage == STORAGE_SLICE) { + inittype = hint; + } + check_expression(ctx, aexpr->alloc.expr, expr->alloc.expr, inittype); + + enum type_storage storage = + type_dealias(expr->alloc.expr->result)->storage; + if (!hint && storage == STORAGE_SLICE) { + hint = expr->alloc.expr->result; + } else if (hint) { + storage = type_dealias(hint)->storage; + } else { + hint = type_store_lookup_pointer(ctx->store, + expr->alloc.expr->result, 0); + } + expr->result = hint; + storage = type_dealias(hint)->storage; + switch (storage) { case STORAGE_POINTER: - check_expression(ctx, aexpr->alloc.expr, expr->alloc.expr, - expr->result->pointer.referent); if (aexpr->alloc.cap != NULL) { // We can't just expect(aexpr->alloc.cap != NULL) // because we want to use aexpr->alloc.cap->loc @@ -204,8 +220,6 @@ check_expr_alloc(struct context *ctx, } break; case STORAGE_SLICE: - check_expression(ctx, aexpr->alloc.expr, expr->alloc.expr, - expr->result); if (aexpr->alloc.cap != NULL) { expr->alloc.cap = xcalloc(sizeof(struct expression), 1); check_expression(ctx, aexpr->alloc.cap, expr->alloc.cap, diff --git a/src/gen.c b/src/gen.c @@ -510,7 +510,7 @@ gen_slice_alloc(struct gen_context *ctx, } else { cap = len; } - constl(&temp, expr->result->array.members->size); + constl(&temp, type_dealias(expr->result)->array.members->size); pushi(ctx->current, &size, Q_MUL, &cap, &temp, NULL); struct qbe_value ret = {0}; diff --git a/src/parse.c b/src/parse.c @@ -1276,8 +1276,6 @@ parse_allocation_expression(struct lexer *lexer) exp = mkexpr(&tok.loc); exp->type = EXPR_ALLOC; want(lexer, T_LPAREN, NULL); - exp->alloc.type = parse_type(lexer); - want(lexer, T_COMMA, NULL); exp->alloc.expr = parse_simple_expression(lexer); switch (lex(lexer, &tok)) { case T_COMMA: diff --git a/tests/17-alloc.ha b/tests/17-alloc.ha @@ -6,17 +6,17 @@ type my_struct = struct { type my_struct_ptr = *my_struct; fn allocation() void = { - let x = alloc(*int, 1234); + let x = alloc(1234); assert(*x == 1234); free(x); - let y = alloc(nullable *int, 1234); + let y: nullable *int = alloc(1234); if (y != null) { assert(*(y: *int) == 1234); }; free(y); - let z = alloc(my_struct_ptr, struct { + let z: my_struct_ptr = alloc(struct { x: int = 42, y: int = 69, }); @@ -25,15 +25,15 @@ fn allocation() void = { }; fn assignment() void = { - let x = alloc(*int, 1234); + let x = alloc(1234); *x = 4321; assert(*x == 4321); free(x); }; fn double_pointer() void = { - let x = alloc(*int, 1234); - let y = alloc(**int, x); + let x = alloc(1234); + let y = alloc(x); *x = 4321; assert(**y == 4321); **y = 1337; @@ -43,29 +43,29 @@ fn double_pointer() void = { }; fn double_alloc() void = { - let x = alloc(*int, 1234); - let y = alloc(*int, 4321); + let x = alloc(1234); + let y = alloc(4321); assert(x != y && *x != *y); free(x); free(y); }; fn slice() void = { - let x = alloc([]int, [1, 2, 3], 10); + let x: []int = alloc([1, 2, 3], 10); assert(len(x) == 3); for (let i = 0z; i < len(x); i += 1) { assert(x[i] == (i + 1): int); }; free(x); - let y = alloc([]int, [1, 2, 3]); + let y: []int = alloc([1, 2, 3]); assert(len(x) == 3); for (let i = 0z; i < len(y); i += 1) { assert(y[i] == (i + 1): int); }; free(y); - let z = alloc([]int, []); + let z: []int = alloc([]); let p = &z: *struct { data: nullable *[*]int, length: size, @@ -76,7 +76,7 @@ fn slice() void = { fn string() void = { let x = struct { - data: *[3]int = alloc(*[3]int, [1, 2, 3]), + data: *[3]int = alloc([1, 2, 3]), length: size = 3, capacity: size = 3, }; diff --git a/tests/19-append.ha b/tests/19-append.ha @@ -1,7 +1,7 @@ use rt; fn simple() void = { - let x = alloc([]int, [1, 2, 3], 6); + let x: []int = alloc([1, 2, 3], 6); append(x, 4, 5, 6); assert(len(x) == 6); assert(x[0] == 1 && x[1] == 2 && x[2] == 3 && x[3] == 4 && x[4] == 5); @@ -10,7 +10,7 @@ fn simple() void = { assert(x[0] == 1 && x[1] == 2 && x[2] == 3 && x[3] == 4 && x[4] == 5); assert(x[5] == 6 && x[6] == 7 && x[7] == 8 && x[8] == 9); - let y = alloc([][]int, [[1]], 1z); + let y: [][]int = alloc([[1]], 1z); let z = [2, 3, 4]; append(y, ...y); append(y, z); @@ -24,13 +24,13 @@ fn simple() void = { }; fn variadic() void = { - let x = alloc([]int, [1, 2], 2z); + let x: []int = alloc([1, 2], 2z); append(x, 4, ...[8, 16, 32, 64]); assert(len(x) == 7); assert(x[0] == 1 && x[1] == 2 && x[2] == 4 && x[3] == 8 && x[4] == 16); assert(x[5] == 32 && x[6] == 64); - let y = alloc([]int, [1, 2, 3], 3); + let y: []int = alloc([1, 2, 3], 3); let z = [128, 256]; append(y, ...x); append(y, ...z); @@ -47,5 +47,5 @@ export fn main() void = { variadic(); assert(rt::compile("fn test() void = append([1], 2);") != 0); - assert(rt::compile("fn test() void = { let x = alloc([]int, [1], 1z); append(x[..], 2); };") != 0); + assert(rt::compile("fn test() void = { let x: []int = alloc([1], 1z); append(x[..], 2); };") != 0); }; diff --git a/tests/22-delete.ha b/tests/22-delete.ha @@ -3,7 +3,7 @@ use rt; type my_slice = []int; fn index() void = { - let x = alloc([]int, [1, 2, 3, 4, 5]); + let x: []int = alloc([1, 2, 3, 4, 5]); let y = &x: *my_slice; delete(x[1]); @@ -17,7 +17,7 @@ fn index() void = { }; fn slice() void = { - let x = alloc([]int, [1, 2, 3, 4, 5]): my_slice; + let x: my_slice = alloc([1, 2, 3, 4, 5]); let y = &x; const s = y: *rt::slice;