diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-31 17:54:29 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-31 18:02:32 -0400 |
commit | 11c93eafd9b19546a1190a7cf8c9d5bf70a56e58 (patch) | |
tree | d9fd3169b8347871f9aab42e187fde5406354846 | |
parent | 9e55cdb1ea5cd8318a1a0b7a9f64f09e8d8ad692 (diff) |
discovered a bug where stuff isn't typed before being eval'd. trying to fix it.
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | cgen.c | 19 | ||||
-rw-r--r-- | eval.c | 17 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | test.toc | 23 | ||||
-rw-r--r-- | types.c | 16 | ||||
-rw-r--r-- | types.h | 2 |
7 files changed, 37 insertions, 43 deletions
@@ -3,3 +3,4 @@ a.out out.c tests/**/*.c tests/**/*.bin +vgcore*
\ No newline at end of file @@ -117,12 +117,7 @@ static void cgen_ident(CGenerator *g, Identifier i) { cgen_write(g, "main__"); } else { cgen_indent(g); - IdentDecl *idecl = ident_decl(i); - if (idecl && (idecl->flags & IDECL_FLAG_CGEN_PTR)) - cgen_write(g, "(*"); fprint_ident(cgen_writing_to(g), i); - if (idecl && (idecl->flags & IDECL_FLAG_CGEN_PTR)) - cgen_write(g, ")"); } } @@ -307,21 +302,17 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where) { } cgen_write(g, "("); arr_foreach(f->params, Declaration, d) { + long idx = 0; arr_foreach(d->idents, Identifier, i) { if (d != f->params || i != d->idents) cgen_write(g, ", "); + Type *type = d->type.kind == TYPE_TUPLE ? &d->type.tuple[idx++] : &d->type; any_params = true; - if (!cgen_type_pre(g, &d->type, where)) + if (!cgen_type_pre(g, type, where)) return false; cgen_write(g, " "); - bool ptr = cgen_uses_ptr(&d->type); - if (ptr) { - IdentDecl *idecl = ident_decl(*i); - assert(idecl); - idecl->flags |= IDECL_FLAG_CGEN_PTR; - } cgen_ident(g, *i); - if (!cgen_type_post(g, &d->type, where)) + if (!cgen_type_post(g, type, where)) return false; } } @@ -469,8 +460,6 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, arr_foreach(to->call.arg_exprs, Expression, arg) { if (arg != to->call.arg_exprs) cgen_write(g, ", "); - if (cgen_uses_ptr(&arg->type)) - cgen_write(g, "&"); if (!cgen_expr(g, arg)) return false; } @@ -1,13 +1,15 @@ +static bool types_block(Typer *tr, Block *b); static size_t compiler_sizeof(Type *t); static bool eval_block(Evaluator *ev, Block *b, Type *t, Value *v); static bool eval_expr(Evaluator *ev, Expression *e, Value *v); static bool block_enter(Block *b, Statement *stmts, U32 flags); static void block_exit(Block *b, Statement *stmts); -static void evalr_create(Evaluator *ev) { +static void evalr_create(Evaluator *ev, Typer *tr) { allocr_create(&ev->allocr); ev->returning = NULL; ev->to_free = NULL; + ev->typer = tr; } static void evalr_free(Evaluator *ev) { @@ -706,7 +708,11 @@ static bool eval_set(Evaluator *ev, Expression *set, Value *to) { return true; } -static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { +static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { + if (e->type.kind == TYPE_UNKNOWN) { + err_print(e->where, "Cannot determine type of expression."); + return false; + } /* WARNING: macros ahead */ #define eval_unary_op_one(low, up, op) \ case BUILTIN_##up: \ @@ -1073,6 +1079,9 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { if (!eval_expr(ev, e->call.fn, &fnv)) return false; FnExpr *fn = fnv.fn; + /* make sure function body is typed before calling it */ + if (!types_block(ev->typer, &fn->body)) + return false; /* set parameter declaration values */ Declaration *params = fn->params; /* OPTIM (NOTE: currently needed for recursion) */ @@ -1085,9 +1094,11 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { fn_enter(fn, 0); long arg = 0; arr_foreach(params, Declaration, p) { + long idx = 0; arr_foreach(p->idents, Identifier, i) { + Type *type = p->type.kind == TYPE_TUPLE ? &p->type.tuple[idx++] : &p->type; IdentDecl *id = ident_decl(*i); - id->val = args[arg]; + val_copy(NULL, &id->val, &args[arg], type); id->flags |= IDECL_FLAG_HAS_VAL; arg++; } @@ -85,7 +85,7 @@ int main(int argc, char **argv) { Typer tr; Evaluator ev; - evalr_create(&ev); + evalr_create(&ev, &tr); typer_create(&tr, &ev); if (!block_enter(NULL, f.stmts, SCOPE_FLAG_CHECK_REDECL)) /* enter global scope */ @@ -7,15 +7,22 @@ Point @= struct { x, y : int; }; -sum34 @= fn() int { - p: Point; - x := &p.x; - *x = 3; - p.y = 4; - p.x + p.y +sum @= fn(p: &Point) int { + p.x + p.y +}; + + +somesum @= fn() int { + + p : Point; + p.x = 12389; + p.y = 29404; + total := sum(&p); + total }; main @= fn() { -X @= sum34(); -puti(sum34()); +// puti(somesum()); +foo @= somesum(); +// puti(foo); }; @@ -106,10 +106,6 @@ static bool expr_arr_must_mut(Expression *e) { err_print(e->where, "Cannot modify a constant array."); return false; } - if (d->flags & DECL_FLAG_PARAM) { - err_print(e->where, "Parameters are immutable."); - return false; - } } return true; case EXPR_CAST: case EXPR_CALL: @@ -742,7 +738,6 @@ static bool types_expr(Typer *tr, Expression *e) { err_print(e->where, "Calling non-function (type %s).", type); return false; } - Type *ret_type = f->type.fn.types; Type *param_types = ret_type + 1; Argument *args = c->args; @@ -837,8 +832,8 @@ static bool types_expr(Typer *tr, Expression *e) { } } } - c->arg_exprs = new_args; *t = *ret_type; + c->arg_exprs = new_args; break; } case EXPR_BLOCK: { @@ -959,15 +954,6 @@ static bool types_expr(Typer *tr, Expression *e) { if (!expr_must_lval(e->binary.lhs)) { return false; } - { - if (lhs->kind == EXPR_IDENT) { - Declaration *d = ident_decl(lhs->ident)->decl; - if (d->flags & DECL_FLAG_PARAM) { - err_print(e->where, "Parameters are immutable."); - return false; - } - } - } /* fallthrough */ case BINARY_ADD: @@ -95,7 +95,6 @@ typedef union Value { } Value; #define IDECL_FLAG_HAS_VAL 0x01 -#define IDECL_FLAG_CGEN_PTR 0x02 /* is a pointer being used for this identifier? */ typedef struct { struct Declaration *decl; struct Block *scope; /* NULL for file scope */ @@ -547,6 +546,7 @@ typedef enum { typedef struct { Allocator allocr; + struct Typer *typer; bool returning; Value ret_val; void **to_free; /* an array of data to free for this scope. */ |