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:
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;