summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-10-07 10:25:21 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-10-07 10:25:21 -0400
commitf08f00ea3bd2e1a99b35a4811c584534b1232254 (patch)
tree5b9bf1a61331baf8cf70362d72f3b2b6d214e312
parentfa60d0d8d6b1ef0e02c118de39bde740ed18496f (diff)
more eval, but there are bugs
-rw-r--r--allocator.c35
-rw-r--r--eval.c161
-rw-r--r--identifiers.c1
-rw-r--r--main.c2
-rw-r--r--scope.c51
-rw-r--r--test.toc5
-rw-r--r--toc.c1
-rw-r--r--types.c105
-rw-r--r--types.h48
9 files changed, 296 insertions, 113 deletions
diff --git a/allocator.c b/allocator.c
index 4dc05c8..793c6cc 100644
--- a/allocator.c
+++ b/allocator.c
@@ -1,22 +1,29 @@
-
+/* #define NO_ALLOCATOR 1 */
/* number of bytes a page hold, not including the header */
-#define PAGE_SIZE (16384 - sizeof(Page))
+#define PAGE_BYTES (16384 - sizeof(Page))
+#define PAGE_MAX_ALIGNS (PAGE_BYTES / sizeof(max_align_t))
static void allocr_create(Allocator *a) {
a->first = a->last = NULL;
}
static void *allocr_malloc(Allocator *a, size_t bytes) {
+ assert(bytes);
+#if NO_ALLOCATOR
+ (void)a;
+ return err_malloc(bytes);
+#else
/* position in this page to return */
- size_t pos = PAGE_SIZE;
+ size_t pos = PAGE_MAX_ALIGNS;
if (a->last)
- pos = (a->last->used + sizeof(max_align_t) - 1) / sizeof(max_align_t);
+ pos = a->last->used;
+ size_t max_aligns = (bytes + sizeof(max_align_t) - 1) / sizeof(max_align_t);
- if (pos * sizeof(max_align_t) + bytes > PAGE_SIZE) {
+ if (pos + max_aligns > PAGE_MAX_ALIGNS) {
/* make a new page for this data */
- Page *page = err_malloc(sizeof *page + (bytes > PAGE_SIZE ? bytes : PAGE_SIZE));
+ Page *page = err_malloc(sizeof *page + (bytes > PAGE_BYTES ? bytes : PAGE_BYTES));
page->next = NULL;
- page->used = bytes;
+ page->used = max_aligns;
if (a->last)
a->last->next = page;
else
@@ -24,24 +31,36 @@ static void *allocr_malloc(Allocator *a, size_t bytes) {
a->last = page;
return page->data;
} else {
- a->last->used += bytes;
+ a->last->used += max_aligns;
return &a->last->data[pos];
}
+#endif
}
static void *allocr_calloc(Allocator *a, size_t n, size_t sz) {
+#if NO_ALLOCATOR
+ (void)a;
+ return err_calloc(n, sz);
+#else
/* OPTIM: use calloc */
size_t bytes = n * sz;
void *data = allocr_malloc(a, bytes);
memset(data, 0, bytes);
return data;
+#endif
}
/* OPTIM */
static void *allocr_realloc(Allocator *a, void *data, size_t old_size, size_t new_size) {
+#if NO_ALLOCATOR
+ (void)a;
+ (void)old_size;
+ return err_realloc(data, new_size);
+#else
void *ret = allocr_malloc(a, new_size);
memcpy(ret, data, old_size);
return ret;
+#endif
}
static void allocr_free_all(Allocator *a) {
diff --git a/eval.c b/eval.c
index 82898f1..3835a3f 100644
--- a/eval.c
+++ b/eval.c
@@ -1,9 +1,11 @@
static bool eval_block(Evaluator *ev, Block *b, Value *v);
-static bool type_resolve(Typer *tr, Type *t);
+static bool eval_expr(Evaluator *ev, Expression *e, Value *v);
+static bool type_resolve(Evaluator *ev, Type *t);
+static bool block_enter(Block *b, Statement *stmts);
+static void block_exit(Block *b, Statement *stmts);
-static void evalr_create(Evaluator *ev, Typer *tr) {
+static void evalr_create(Evaluator *ev) {
allocr_create(&ev->allocr);
- ev->typer = tr;
}
static void evalr_free(Evaluator *ev) {
@@ -318,8 +320,102 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) {
}
}
+/* type is the underlying type, not the pointer type. */
static void eval_deref(Value *v, void *ptr, Type *type) {
- /* TODO */
+ switch (type->kind) {
+ case TYPE_PTR: v->ptr = *(void **)ptr; break;
+ case TYPE_ARR: v->arr = *(void **)ptr; break;
+ case TYPE_FN: v->fn = *(FnExpr **)ptr; break;
+ case TYPE_TUPLE: v->tuple = *(Value **)ptr; break;
+ case TYPE_BUILTIN:
+ switch (type->builtin) {
+ case BUILTIN_I8: v->i8 = *(I8 *)ptr; break;
+ case BUILTIN_U8: v->u8 = *(U8 *)ptr; break;
+ case BUILTIN_I16: v->i16 = *(I16 *)ptr; break;
+ case BUILTIN_U16: v->u16 = *(U16 *)ptr; break;
+ case BUILTIN_I32: v->i32 = *(I32 *)ptr; break;
+ case BUILTIN_U32: v->u32 = *(U32 *)ptr; break;
+ case BUILTIN_I64: v->i64 = *(I64 *)ptr; break;
+ case BUILTIN_U64: v->u64 = *(U64 *)ptr; break;
+ case BUILTIN_F32: v->f32 = *(F32 *)ptr; break;
+ case BUILTIN_F64: v->f64 = *(F64 *)ptr; break;
+ case BUILTIN_CHAR: v->charv = *(char *)ptr; break;
+ case BUILTIN_BOOL: v->boolv = *(bool *)ptr; break;
+ case BUILTIN_TYPE_COUNT: assert(0); break;
+ }
+ break;
+ case TYPE_VOID:
+ case TYPE_UNKNOWN:
+ assert(0);
+ break;
+ }
+}
+/* inverse of eval_deref */
+static void eval_deref_set(void *set, Value *to, Type *type) {
+ switch (type->kind) {
+ case TYPE_PTR: *(void **)set = to->ptr; break;
+ case TYPE_ARR: *(void **)set = to->arr; break;
+ case TYPE_FN: *(FnExpr **)set = to->fn; break;
+ case TYPE_TUPLE: *(Value **)set = to->tuple; break;
+ case TYPE_BUILTIN:
+ switch (type->builtin) {
+ case BUILTIN_I8: *(I8 *)set = to->i8; break;
+ case BUILTIN_U8: *(U8 *)set = to->u8; break;
+ case BUILTIN_I16: *(I16 *)set = to->i16; break;
+ case BUILTIN_U16: *(U16 *)set = to->u16; break;
+ case BUILTIN_I32: *(I32 *)set = to->i32; break;
+ case BUILTIN_U32: *(U32 *)set = to->u32; break;
+ case BUILTIN_I64: *(I64 *)set = to->i64; break;
+ case BUILTIN_U64: *(U64 *)set = to->u64; break;
+ case BUILTIN_F32: *(F32 *)set = to->f32; break;
+ case BUILTIN_F64: *(F64 *)set = to->f64; break;
+ case BUILTIN_CHAR: *(char *)set = to->charv; break;
+ case BUILTIN_BOOL: *(bool *)set = to->boolv; break;
+ case BUILTIN_TYPE_COUNT: assert(0); break;
+ }
+ break;
+ case TYPE_VOID:
+ case TYPE_UNKNOWN:
+ assert(0);
+ break;
+ }
+}
+
+static bool eval_set(Evaluator *ev, Expression *set, Value *to) {
+ switch (set->kind) {
+ case EXPR_IDENT: {
+ IdentDecl *id = ident_decl(set->ident);
+ if (!(id->flags & IDECL_FLAG_HAS_VAL)) {
+ err_print(set->where, "Cannot set value of run time variable at compile time.");
+ return false;
+ }
+ id->val = *to;
+ } break;
+ case EXPR_UNARY_OP:
+ switch (set->unary.op) {
+ case UNARY_DEREF: {
+ Value ptr;
+ if (!eval_expr(ev, set->unary.of, &ptr)) return false;
+ eval_deref_set(ptr.ptr, to, &set->type);
+ } break;
+ default: assert(0); break;
+ }
+ break;
+ case EXPR_BINARY_OP:
+ switch (set->binary.op) {
+ case BINARY_AT_INDEX:
+ /* TODO */
+ break;
+ default: break;
+ }
+ case EXPR_TUPLE:
+ /* TODO */
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ return true;
}
static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
@@ -364,6 +460,7 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
#define eval_binary_op_nums_only(op) \
val_cast(&lhs, &e->binary.lhs->type, &lhs, &e->type); \
val_cast(&rhs, &e->binary.rhs->type, &rhs, &e->type); \
+ assert(e->type.kind == TYPE_BUILTIN); \
switch (builtin) { \
eval_binary_op_nums(builtin, op); \
default: assert(0); break; \
@@ -386,12 +483,13 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
eval_binary_bool_op_one(f32, F32, op); \
eval_binary_bool_op_one(f64, F64, op);
-#define eval_binary_bool_op_nums_only(op) \
+#define eval_binary_bool_op_nums_only(op) \
val_cast(&lhs, &e->binary.lhs->type, &lhs, &e->type); \
val_cast(&rhs, &e->binary.rhs->type, &rhs, &e->type); \
+ assert(e->type.kind == TYPE_BUILTIN); \
switch (builtin) { \
eval_binary_bool_op_nums(builtin, op); \
- default: assert(0); break; \
+ default: assert(0); break; \
}
@@ -401,6 +499,9 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
Value of;
if (!eval_expr(ev, e->unary.of, &of)) return false;
switch (e->unary.op) {
+ case UNARY_DEREF:
+ eval_deref(v, of.ptr, &e->type);
+ break;
case UNARY_MINUS: {
BuiltinType builtin = e->type.builtin;
assert(e->type.kind == TYPE_BUILTIN);
@@ -409,15 +510,23 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
case UNARY_NOT:
v->boolv = !val_truthiness(v, &e->unary.of->type);
break;
+ case UNARY_DEL:
+ if (e->unary.of->type.kind == TYPE_PTR)
+ free(of.ptr);
+ else {
+ assert(e->unary.of->type.kind == TYPE_ARR);
+ free(of.arr);
+ }
+ break;
}
} break;
case EXPR_BINARY_OP: {
Value lhs, rhs;
/* TODO(eventually): short-circuiting */
- if (!eval_expr(ev, e->binary.lhs, &lhs)) return false;
+ if (e->binary.op != BINARY_SET)
+ if (!eval_expr(ev, e->binary.lhs, &lhs)) return false;
if (!eval_expr(ev, e->binary.rhs, &rhs)) return false;
BuiltinType builtin = e->type.builtin;
- assert(e->type.kind == TYPE_BUILTIN);
switch (e->binary.op) {
case BINARY_ADD:
eval_binary_op_nums_only(+); break;
@@ -439,6 +548,9 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
eval_binary_bool_op_nums_only(==); break;
case BINARY_NE:
eval_binary_bool_op_nums_only(!=); break;
+ case BINARY_SET:
+ if (!eval_set(ev, e->binary.lhs, &rhs)) return false;
+ break;
case BINARY_AT_INDEX: {
U64 index;
U64 arr_sz = e->binary.lhs->type.arr.n;
@@ -524,7 +636,9 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
case EXPR_IDENT: {
IdentDecl *idecl = ident_decl(e->ident);
Declaration *d = idecl->decl;
- if (d->flags & DECL_FLAG_CONST) {
+ if (idecl->flags & IDECL_FLAG_HAS_VAL) {
+ *v = idecl->val;
+ } else if (d->flags & DECL_FLAG_CONST) {
if (!(d->flags & DECL_FLAG_FOUND_VAL)) {
if (!eval_expr(ev, &d->expr, &d->val)) return false;
d->flags |= DECL_FLAG_FOUND_VAL;
@@ -567,22 +681,38 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
}
} break;
case EXPR_NEW:
- /* it's not strictly necessary to do the if here */
- if (!type_resolve(ev->typer, &e->new.type))
+ if (!type_resolve(ev, &e->new.type))
return false;
+ /* it's not strictly necessary to do the if here */
if (e->new.type.kind == TYPE_ARR)
- v->arr = err_malloc(compiler_sizeof(&e->new.type));
+ v->arr = err_calloc(1, compiler_sizeof(&e->new.type));
else
- v->ptr = err_malloc(compiler_sizeof(&e->new.type));
+ v->ptr = err_calloc(1, compiler_sizeof(&e->new.type));
+
break;
}
return true;
}
+static bool eval_decl(Evaluator *ev, Declaration *d) {
+ arr_foreach(d->idents, Identifier, i) {
+ IdentDecl *id = ident_decl(*i);
+ id->flags |= IDECL_FLAG_HAS_VAL;
+ assert(id->decl == d);
+ if (d->flags & DECL_FLAG_HAS_EXPR) {
+ if (!eval_expr(ev, &d->expr, &id->val))
+ return false;
+ } else {
+ id->val = (Value){0};
+ }
+ }
+ return true;
+}
+
static bool eval_stmt(Evaluator *ev, Statement *stmt) {
switch (stmt->kind) {
case STMT_DECL:
- /* TODO */
+ if (!eval_decl(ev, &stmt->decl)) return false;
break;
case STMT_EXPR: {
Value unused;
@@ -597,6 +727,7 @@ static bool eval_stmt(Evaluator *ev, Statement *stmt) {
}
static bool eval_block(Evaluator *ev, Block *b, Value *v) {
+ block_enter(b, b->stmts);
arr_foreach(b->stmts, Statement, stmt) {
if (!eval_stmt(ev, stmt))
return false;
@@ -605,5 +736,7 @@ static bool eval_block(Evaluator *ev, Block *b, Value *v) {
if (!eval_expr(ev, b->ret_expr, v))
return false;
}
+ block_exit(b, b->stmts);
+
return true;
}
diff --git a/identifiers.c b/identifiers.c
index d7ad02d..b59e67f 100644
--- a/identifiers.c
+++ b/identifiers.c
@@ -148,6 +148,7 @@ static void ident_add_decl(Identifier i, struct Declaration *d, struct Block *b)
IdentDecl *id_decl = arr_add(&i->decls);
id_decl->decl = d;
id_decl->scope = b;
+ id_decl->flags = 0;
}
static IdentDecl *ident_decl(Identifier i) {
diff --git a/main.c b/main.c
index e40b8ea..e77b6cb 100644
--- a/main.c
+++ b/main.c
@@ -72,7 +72,7 @@ int main(int argc, char **argv) {
block_enter(NULL, f.stmts); /* enter global scope */
Typer tr;
Evaluator ev;
- evalr_create(&ev, &tr);
+ evalr_create(&ev);
typer_create(&tr, &ev);
if (!types_file(&tr, &f)) {
err_fprint(TEXT_IMPORTANT("Errors occured while determining types.\n"));
diff --git a/scope.c b/scope.c
new file mode 100644
index 0000000..cc7d7db
--- /dev/null
+++ b/scope.c
@@ -0,0 +1,51 @@
+static bool add_ident_decls(Block *b, Declaration *d) {
+ bool ret = true;
+ arr_foreach(d->idents, Identifier, ident) {
+ IdentDecl **decls = &(*ident)->decls;
+ if (arr_len(*decls)) {
+ /* check that it hasn't been declared in this block */
+ IdentDecl *prev = arr_last(*decls);
+ if (prev->scope == b) {
+ err_print(d->where, "Re-declaration of identifier in the same block.");
+ info_print(prev->decl->where, "Previous declaration was here.");
+ ret = false;
+ continue;
+ }
+ }
+ ident_add_decl(*ident, d, b);
+ }
+ return ret;
+}
+
+static void remove_ident_decls(Block *b, Declaration *d) {
+ arr_foreach(d->idents, Identifier, ident) {
+ IdentTree *id_info = *ident;
+ IdentDecl **decls = &id_info->decls;
+ IdentDecl *last_decl = arr_last(*decls);
+ if (last_decl && last_decl->scope == b) {
+ arr_remove_last(decls); /* remove that declaration */
+ }
+ }
+}
+
+/* pass NULL for block for global scope */
+static bool block_enter(Block *b, Statement *stmts) {
+ bool ret = true;
+ arr_foreach(stmts, Statement, stmt) {
+ if (stmt->kind == STMT_DECL) {
+ Declaration *decl = &stmt->decl;
+ if (!add_ident_decls(b, decl))
+ ret = false;
+ }
+ }
+ return ret;
+}
+
+static void block_exit(Block *b, Statement *stmts) {
+ arr_foreach(stmts, Statement, stmt) {
+ if (stmt->kind == STMT_DECL) {
+ Declaration *decl = &stmt->decl;
+ remove_ident_decls(b, decl);
+ }
+ }
+}
diff --git a/test.toc b/test.toc
index a914b1d..c472568 100644
--- a/test.toc
+++ b/test.toc
@@ -1,6 +1,7 @@
main @= fn() {
// foo @= true;
// N, M @= 8 * if foo { 8 } else { 3} - 3, 894;
- foo @= new[3]int;
- x : [foo[0]]int;
+ // foo @= new[3]int;
+ // x : [foo[0]]int;
+ y : [{x := (439 as &u8); *x = 7; *x }]f32;
}; \ No newline at end of file
diff --git a/toc.c b/toc.c
index 94e74a8..e89c621 100644
--- a/toc.c
+++ b/toc.c
@@ -21,6 +21,7 @@
#include "identifiers.c"
#include "tokenizer.c"
#include "parse.c"
+#include "scope.c"
#include "eval.c"
#include "types.c"
diff --git a/types.c b/types.c
index 772254a..454b96d 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 type_resolve(Typer *tr, Type *t);
+static bool types_type(Typer *tr, Type *t);
static inline void *typer_malloc(Typer *tr, size_t bytes) {
return allocr_malloc(&tr->allocr, bytes);
@@ -18,59 +18,6 @@ static inline void *typer_arr_add_(Typer *tr, void **arr, size_t sz) {
#define typer_arr_add(tr, a) typer_arr_add_(tr, (void **)(a), sizeof **(a))
-static bool add_ident_decls(Block *b, Declaration *d) {
- bool ret = true;
- arr_foreach(d->idents, Identifier, ident) {
- IdentDecl **decls = &(*ident)->decls;
- if (arr_len(*decls)) {
- /* check that it hasn't been declared in this block */
- IdentDecl *prev = arr_last(*decls);
- if (prev->scope == b) {
- err_print(d->where, "Re-declaration of identifier in the same block.");
- info_print(prev->decl->where, "Previous declaration was here.");
- ret = false;
- continue;
- }
- }
- ident_add_decl(*ident, d, b);
- }
- return ret;
-}
-
-static void remove_ident_decls(Block *b, Declaration *d) {
- arr_foreach(d->idents, Identifier, ident) {
- IdentTree *id_info = *ident;
- IdentDecl **decls = &id_info->decls;
- IdentDecl *last_decl = arr_last(*decls);
- if (last_decl && last_decl->scope == b) {
- arr_remove_last(decls); /* remove that declaration */
- }
- }
-}
-
-/* pass NULL for block for global scope */
-static bool block_enter(Block *b, Statement *stmts) {
- bool ret = true;
- arr_foreach(stmts, Statement, stmt) {
- if (stmt->kind == STMT_DECL) {
- Declaration *decl = &stmt->decl;
- if (!add_ident_decls(b, decl))
- ret = false;
- }
- }
- return ret;
-}
-
-static void block_exit(Block *b, Statement *stmts) {
- /* OPTIM: figure out some way of not re-iterating over everything */
- arr_foreach(stmts, Statement, stmt) {
- if (stmt->kind == STMT_DECL) {
- Declaration *decl = &stmt->decl;
- remove_ident_decls(b, decl);
- }
- }
-}
-
static bool type_eq(Type *a, Type *b) {
if (a->kind == TYPE_UNKNOWN || b->kind == TYPE_UNKNOWN)
return true; /* allow things such as 3 + #C("5") */
@@ -177,12 +124,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 (!type_resolve(tr, &f->ret_type))
+ if (!types_type(tr, &f->ret_type) || !type_resolve(tr->evalr, &f->ret_type))
return false;
*ret_type = f->ret_type;
arr_foreach(f->params, Declaration, decl) {
if (!types_decl(tr, decl)) return false;
- if (!type_resolve(tr, &decl->type))
+ if (!types_type(tr, &decl->type) || !type_resolve(tr->evalr, &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);
@@ -271,15 +218,13 @@ 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(Typer *tr, Type *t) {
+static bool type_resolve(Evaluator *ev, Type *t) {
if (t->flags & TYPE_FLAG_RESOLVED) return true;
switch (t->kind) {
case TYPE_ARR: {
/* it's an array */
- if (!type_resolve(tr, t->arr.of)) return false; /* resolve inner type */
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;
@@ -290,7 +235,7 @@ static bool type_resolve(Typer *tr, Type *t) {
free(s);
return false;
}
- if (!eval_expr(tr->evalr, n_expr, &val))
+ if (!eval_expr(ev, n_expr, &val))
return false;
U64 size;
@@ -308,18 +253,18 @@ static bool type_resolve(Typer *tr, Type *t) {
} break;
case TYPE_FN:
arr_foreach(t->fn.types, Type, child_type) {
- if (!type_resolve(tr, child_type))
+ if (!type_resolve(ev, child_type))
return false;
}
break;
case TYPE_TUPLE:
arr_foreach(t->tuple, Type, child_type) {
- if (!type_resolve(tr, child_type))
+ if (!type_resolve(ev, child_type))
return false;
}
break;
case TYPE_PTR:
- if (!type_resolve(tr, t->ptr.of))
+ if (!type_resolve(ev, t->ptr.of))
return false;
break;
case TYPE_UNKNOWN:
@@ -331,6 +276,32 @@ static bool type_resolve(Typer *tr, Type *t) {
return true;
}
+static bool types_type(Typer *tr, Type *t) {
+ 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.of)) 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) {
@@ -542,7 +513,7 @@ static bool types_expr(Typer *tr, Expression *e) {
CastExpr *c = &e->cast;
if (!types_expr(tr, c->expr))
return false;
- if (!type_resolve(tr, &c->type))
+ if (!types_type(tr, &c->type) || !type_resolve(tr->evalr, &c->type))
return false;
Status status = type_cast_status(&c->expr->type, &c->type);
if (status != STATUS_NONE) {
@@ -561,6 +532,9 @@ static bool types_expr(Typer *tr, Expression *e) {
} 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))
+ return false;
if (e->new.type.kind == TYPE_ARR) {
*t = e->new.type;
} else {
@@ -828,6 +802,7 @@ static bool types_expr(Typer *tr, Expression *e) {
free(s);
return false;
}
+
*t = *of_type->ptr.of;
break;
case UNARY_DEL:
@@ -992,7 +967,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 (!type_resolve(tr, &d->type)) {
+ if (!types_type(tr, &d->type) || !type_resolve(tr->evalr, &d->type)) {
success = false;
goto ret;
}
diff --git a/types.h b/types.h
index 36017e2..df9d192 100644
--- a/types.h
+++ b/types.h
@@ -34,7 +34,7 @@ typedef struct {
typedef struct Page {
struct Page *next;
- size_t used;
+ size_t used; /* number of max_align_t's used, not bytes */
max_align_t data[];
} Page;
@@ -56,9 +56,31 @@ typedef struct {
ArrBlock *blocks;
} BlockArr;
+typedef union Value {
+ U8 u8;
+ U16 u16;
+ U32 u32;
+ U64 u64;
+ I8 i8;
+ I16 i16;
+ I32 i32;
+ I64 i64;
+ bool boolv;
+ char charv;
+ float f32;
+ double f64;
+ struct FnExpr *fn;
+ void *arr;
+ void *ptr;
+ union Value *tuple;
+} Value;
+
+#define IDECL_FLAG_HAS_VAL 0x01
typedef struct {
- struct Block *scope; /* NULL for file scope */
struct Declaration *decl;
+ struct Block *scope; /* NULL for file scope */
+ Value val;
+ uint16_t flags;
} IdentDecl;
/*
@@ -328,7 +350,7 @@ typedef struct {
Block body;
} WhileExpr;
-typedef struct {
+typedef struct FnExpr {
struct Declaration *params; /* declarations of the parameters to this function */
struct Declaration *ret_decls; /* array of decls, if this has named return values. otherwise, NULL */
Type ret_type;
@@ -386,25 +408,6 @@ typedef struct Argument {
Expression val;
} Argument;
-typedef union Value {
- U8 u8;
- U16 u16;
- U32 u32;
- U64 u64;
- I8 i8;
- I16 i16;
- I32 i32;
- I64 i64;
- bool boolv;
- char charv;
- float f32;
- double f64;
- FnExpr *fn;
- void *arr;
- void *ptr;
- union Value *tuple;
-} Value;
-
#define DECL_FLAG_ANNOTATES_TYPE 0x01
#define DECL_FLAG_CONST 0x02
#define DECL_FLAG_HAS_EXPR 0x04
@@ -464,7 +467,6 @@ typedef enum {
typedef struct {
Allocator allocr;
- struct Typer *typer;
} Evaluator;
typedef struct Typer {