summaryrefslogtreecommitdiff
path: root/types.c
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-10-20 11:39:21 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-10-20 11:39:21 -0400
commit89f00af3cf25d594f10aebaa7048a17bdd520c4b (patch)
treebbb22f3ffe808bca6849fd66693b094221a047fb /types.c
parentbfd0a7f6fbf22914631337b3871011f452d3fb94 (diff)
improved new; new slices
Diffstat (limited to 'types.c')
-rw-r--r--types.c78
1 files changed, 29 insertions, 49 deletions
diff --git a/types.c b/types.c
index 387edef..fda1afa 100644
--- a/types.c
+++ b/types.c
@@ -2,7 +2,7 @@ static bool types_stmt(Typer *tr, Statement *s);
static bool types_decl(Typer *tr, Declaration *d);
static bool types_expr(Typer *tr, Expression *e);
static bool types_block(Typer *tr, Block *b);
-static bool types_type(Typer *tr, Type *t);
+static bool type_resolve(Typer *tr, Type *t);
static inline void *typer_malloc(Typer *tr, size_t bytes) {
return allocr_malloc(&tr->allocr, bytes);
@@ -200,12 +200,12 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Type *t) {
t->kind = TYPE_FN;
t->fn.types = NULL;
Type *ret_type = typer_arr_add(tr, &t->fn.types);
- if (!types_type(tr, &f->ret_type) || !type_resolve(tr->evalr, &f->ret_type))
+ if (!type_resolve(tr, &f->ret_type))
return false;
*ret_type = f->ret_type;
arr_foreach(f->params, Declaration, decl) {
if (!types_decl(tr, decl)) return false;
- if (!types_type(tr, &decl->type) || !type_resolve(tr->evalr, &decl->type))
+ if (!type_resolve(tr, &decl->type))
return false;
for (size_t i = 0; i < arr_len(decl->idents); i++) {
Type *param_type = typer_arr_add(tr, &t->fn.types);
@@ -294,13 +294,16 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) {
}
/* fixes the type (replaces [5+3]int with [8]int, etc.) */
-static bool type_resolve(Evaluator *ev, Type *t) {
+static bool type_resolve(Typer *tr, Type *t) {
+ Evaluator *ev = tr->evalr;
if (t->flags & TYPE_FLAG_RESOLVED) return true;
switch (t->kind) {
case TYPE_ARR: {
/* it's an array */
Value val;
Expression *n_expr = t->arr.n_expr;
+ if (!types_expr(tr, n_expr)) return false;
+
if (n_expr->type.kind == TYPE_UNKNOWN) {
err_print(n_expr->where, "Cannot determine type of array size at compile time.");
return false;
@@ -326,27 +329,27 @@ static bool type_resolve(Evaluator *ev, Type *t) {
size = val_to_u64(&val, n_expr->type.builtin);
}
t->arr.n = (UInteger)size;
- if (!type_resolve(ev, t->arr.of))
+ if (!type_resolve(tr, t->arr.of))
return false;
} break;
case TYPE_FN:
arr_foreach(t->fn.types, Type, child_type) {
- if (!type_resolve(ev, child_type))
+ if (!type_resolve(tr, child_type))
return false;
}
break;
case TYPE_TUPLE:
arr_foreach(t->tuple, Type, child_type) {
- if (!type_resolve(ev, child_type))
+ if (!type_resolve(tr, child_type))
return false;
}
break;
case TYPE_PTR:
- if (!type_resolve(ev, t->ptr))
+ if (!type_resolve(tr, t->ptr))
return false;
break;
case TYPE_SLICE:
- if (!type_resolve(ev, t->slice))
+ if (!type_resolve(tr, t->slice))
return false;
break;
case TYPE_UNKNOWN:
@@ -358,37 +361,6 @@ static bool type_resolve(Evaluator *ev, Type *t) {
return true;
}
-static bool types_type(Typer *tr, Type *t) {
- if (t->flags & TYPE_FLAG_RESOLVED) return true;
- switch (t->kind) {
- case TYPE_ARR:
- if (!types_expr(tr, t->arr.n_expr)) return false;
- if (!types_type(tr, t->arr.of)) return false;
- break;
- case TYPE_PTR:
- if (!types_type(tr, t->ptr)) return false;
- break;
- case TYPE_SLICE:
- if (!types_type(tr, t->slice)) return false;
- break;
- case TYPE_TUPLE: {
- arr_foreach(t->tuple, Type, x)
- if (!types_type(tr, x))
- return false;
- } break;
- case TYPE_FN:
- arr_foreach(t->fn.types, Type, x)
- if (!types_type(tr, x))
- return false;
- break;
- case TYPE_UNKNOWN:
- case TYPE_BUILTIN:
- case TYPE_VOID:
- break;
- }
- return true;
-}
-
static bool type_can_be_truthy(Type *t) {
switch (t->kind) {
case TYPE_VOID:
@@ -596,7 +568,7 @@ static bool types_expr(Typer *tr, Expression *e) {
CastExpr *c = &e->cast;
if (!types_expr(tr, c->expr))
return false;
- if (!types_type(tr, &c->type) || !type_resolve(tr->evalr, &c->type))
+ if (!type_resolve(tr, &c->type))
return false;
Status status = type_cast_status(&c->expr->type, &c->type);
if (status != STATUS_NONE) {
@@ -614,14 +586,20 @@ static bool types_expr(Typer *tr, Expression *e) {
*t = c->type;
} break;
case EXPR_NEW:
- t->kind = TYPE_PTR;
- /* type the type, but don't resolve it (e.g. fn(x:int)int{(new [x]int)[0]}) */
- if (!types_type(tr, &e->new.type))
+ if (!type_resolve(tr, &e->new.type))
return false;
- if (e->new.type.kind == TYPE_ARR) {
- *t = e->new.type;
+ if (e->new.n) {
+ if (!types_expr(tr, e->new.n)) return false;
+ if (e->new.n->type.kind != TYPE_BUILTIN || !type_builtin_is_int(e->new.n->type.builtin)) {
+ char *got = type_to_str(&e->new.n->type);
+ err_print(e->where, "Expected integer as second argument to new, but got %s.", got);
+ free(got);
+ return false;
+ }
+ t->kind = TYPE_SLICE;
+ t->slice = &e->new.type;
} else {
- t->ptr = typer_malloc(tr, sizeof *t->ptr);
+ t->kind = TYPE_PTR;
t->ptr = &e->new.type;
}
break;
@@ -1003,7 +981,9 @@ static bool types_expr(Typer *tr, Expression *e) {
return false;
}
if (lhs_type->kind != TYPE_ARR) {
- err_print(e->where, "Trying to take index of non-array.");
+ char *s = type_to_str(lhs_type);
+ err_print(e->where, "Trying to take index of non-array type %s.", s);
+ free(s);
return false;
}
*t = *lhs_type->arr.of;
@@ -1054,7 +1034,7 @@ static bool types_decl(Typer *tr, Declaration *d) {
if (d->flags & DECL_FLAG_ANNOTATES_TYPE) {
/* type supplied */
assert(d->type.kind != TYPE_VOID); /* there's no way to annotate void */
- if (!types_type(tr, &d->type) || !type_resolve(tr->evalr, &d->type)) {
+ if (!type_resolve(tr, &d->type)) {
success = false;
goto ret;
}