diff options
-rw-r--r-- | allocator.c | 2 | ||||
-rw-r--r-- | eval.c | 68 | ||||
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | test.toc | 14 | ||||
-rw-r--r-- | types.h | 3 |
5 files changed, 49 insertions, 41 deletions
diff --git a/allocator.c b/allocator.c index 0443103..acfe7a8 100644 --- a/allocator.c +++ b/allocator.c @@ -25,7 +25,7 @@ static void *err_malloc(size_t bytes); static void *err_calloc(size_t n, size_t sz); static void *err_realloc(void *prev, size_t new_size); #ifdef TOC_DEBUG -#define NO_ALLOCATOR 1 /* useful for debugging; valgrind checks writing past the end of a malloc, but that won't work with an allocator */ +/* #define NO_ALLOCATOR 1 /\* useful for debugging; valgrind checks writing past the end of a malloc, but that won't work with an allocator *\/ */ #endif /* number of bytes a page hold, not including the header */ #define PAGE_BYTES (16384 - sizeof(Page)) @@ -7,13 +7,12 @@ static bool types_block(Typer *tr, Block *b); static bool types_decl(Typer *tr, Declaration *d); static bool type_resolve(Typer *tr, Type *t, Location where); -static bool eval_block(Evaluator *ev, Block *b, Type *t, Value *v); +static bool eval_block(Evaluator *ev, Block *b, Value *v); static bool eval_expr(Evaluator *ev, Expression *e, Value *v); static Value get_builtin_val(BuiltinVal val); static void evalr_create(Evaluator *ev, Typer *tr, Allocator *allocr) { ev->returning = NULL; - ev->to_free = NULL; ev->typer = tr; ev->enabled = true; ev->allocr = allocr; @@ -21,11 +20,6 @@ static void evalr_create(Evaluator *ev, Typer *tr, Allocator *allocr) { } static void evalr_free(Evaluator *ev) { - typedef void *VoidPtr; - arr_foreach(ev->to_free, VoidPtr, f) { - free(*f); - } - arr_clear(&ev->to_free); ffmgr_free(&ev->ffmgr); } @@ -1145,8 +1139,9 @@ static bool eval_ident(Evaluator *ev, Identifier ident, Value *v, Location where static Value *decl_add_val(Declaration *d) { Value **valpp = arr_add(&d->val_stack); Value *valp = *valpp = err_malloc(sizeof *valp); - if (d->type.kind == TYPE_TUPLE) + if (d->type.kind == TYPE_TUPLE) { valp->tuple = err_malloc(arr_len(d->idents) * sizeof *valp->tuple); + } return valp; } @@ -1308,12 +1303,12 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { Value cond; if (!eval_expr(ev, i->cond, &cond)) return false; if (val_truthiness(&cond, &i->cond->type)) { - if (!eval_block(ev, &i->body, &e->type, v)) return false; + if (!eval_block(ev, &i->body, v)) return false; } else if (i->next_elif) { if (!eval_expr(ev, i->next_elif, v)) return false; } } else { - if (!eval_block(ev, &i->body, &e->type, v)) return false; + if (!eval_block(ev, &i->body, v)) return false; } } break; case EXPR_WHILE: { @@ -1326,7 +1321,7 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { if (!val_truthiness(&cond, cond_type)) break; } - if (!eval_block(ev, &w->body, &e->type, v)) return false; + if (!eval_block(ev, &w->body, v)) return false; } } break; case EXPR_FOR: { @@ -1345,7 +1340,7 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { index_val = NULL; } if (fo->value) { - value_val = fo->value ? &for_valp->tuple[1] : for_valp; + value_val = fo->index ? &for_valp->tuple[1] : for_valp; } else { value_val = NULL; } @@ -1375,12 +1370,13 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { boolt.kind = TYPE_BUILTIN; boolt.builtin = BUILTIN_BOOL; Value cont; + eval_numerical_bin_op(lhs, &fo->type, step_is_negative ? BINARY_GE : BINARY_LE, rhs, &fo->range.to->type, &cont, &boolt); if (!cont.boolv) break; } if (value_val) *value_val = x; - if (!eval_block(ev, &fo->body, &e->type, v)) return false; + if (!eval_block(ev, &fo->body, v)) return false; if (index_val) { ++index_val->i64; } @@ -1423,14 +1419,19 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { value_val->ptr = ptr; else eval_deref(value_val, ptr, &fo->type); - if (!eval_block(ev, &fo->body, &e->type, v)) + if (!eval_block(ev, &fo->body, v)) return false; ++index_val->i64; } } + arr_remove_last(&fo->val_stack); + if (fo->index && fo->value) { + free(for_valp->tuple); + } + free(for_valp); } break; case EXPR_BLOCK: - if (!eval_block(ev, &e->block, &e->type, v)) return false; + if (!eval_block(ev, &e->block, v)) return false; break; case EXPR_LITERAL_BOOL: v->boolv = e->booll; @@ -1457,7 +1458,6 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { case EXPR_TUPLE: { size_t i, n = arr_len(e->tuple); v->tuple = err_malloc(n * sizeof *v->tuple); - *(void **)arr_add(&ev->to_free) = v->tuple; for (i = 0; i < n; ++i) { if (!eval_expr(ev, &e->tuple[i], &v->tuple[i])) return false; @@ -1551,7 +1551,7 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { ++idx; } } - if (!eval_block(ev, &fn->body, &e->type, v)) { + if (!eval_block(ev, &fn->body, v)) { return false; } if (fn->ret_decls) { @@ -1569,9 +1569,6 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { Value *element = arr_add(&tuple); Type *type = decl_type_at_index(d, i); copy_val(NULL, element, &this_one, type); - void *to_free = val_ptr_to_free(element, type); - if (to_free) - *(void **)arr_add(&ev->to_free) = to_free; ++i; } } @@ -1587,6 +1584,11 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { *v = ev->ret_val; ev->returning = false; } + arr_foreach(fn->params, Declaration, p) { + /* remove value */ + arr_remove_last(&p->val_stack); + } + } break; case EXPR_SLICE: { SliceExpr *s = &e->slice; @@ -1709,10 +1711,17 @@ static bool eval_stmt(Evaluator *ev, Statement *stmt) { return true; } -/* t is the type of the block. */ -static bool eval_block(Evaluator *ev, Block *b, Type *t, Value *v) { - void **prev_to_free = ev->to_free; - ev->to_free = NULL; +static void eval_exit_stmts(Statement *stmts) { + arr_foreach(stmts, Statement, s) { + if (s->kind == STMT_DECL && !(s->decl->flags & DECL_IS_CONST)) { + arr_remove_last(&s->decl->val_stack); + } else if (s->kind == STMT_INCLUDE) { + eval_exit_stmts(s->inc.stmts); + } + } +} + +static bool eval_block(Evaluator *ev, Block *b, Value *v) { arr_foreach(b->stmts, Statement, stmt) { if (!eval_stmt(ev, stmt)) return false; @@ -1724,15 +1733,8 @@ static bool eval_block(Evaluator *ev, Block *b, Type *t, Value *v) { return false; /* make a copy so that r's data isn't freed when we exit the block */ copy_val(NULL, v, &r, &b->ret_expr->type); - void *free_ptr = val_ptr_to_free(v, t); - if (free_ptr) - *(void **)arr_add(&prev_to_free) = free_ptr; - } - typedef void *VoidPtr; - arr_foreach(ev->to_free, VoidPtr, f) { - free(*f); } - arr_clear(&ev->to_free); - ev->to_free = prev_to_free; + eval_exit_stmts(b->stmts); + return true; } @@ -18,9 +18,10 @@ /* TODO: -fix eval recursion make sure that you can't access runtime things from eval big leak check with tuples (see "TODO: tuples allocated here will never be freed!") +just make the ffmgr use the allocr +--- struct parameters - to allow circular dependencies in types foo, _ := bar(); nice syntax for #including something into a namespace @@ -1,8 +1,14 @@ -factorial ::= fn(x: int) int { - if x < 2 { 1 } - else { x * factorial(x-1) } +x := 10; + +twotothe ::= fn(x: int) int { + total := 1; + for i := 0..x-1 { + total += twotothe(i); + x += 1; + } + total }; main ::= fn() { - a ::= factorial(10); + a ::= twotothe(10); };
\ No newline at end of file @@ -809,7 +809,7 @@ typedef struct Declaration { /* for eval, for non-constant decls.: */ /* the pointers to values need to be fixed, which is why this isn't just Value *. */ - /* OPTIM: some freeable block array of values somewhere which we can just use a pointer to? */ + /* OPTIM: some block array of values somewhere which we can just use a pointer to, which is freed when the block is exited? */ Value **val_stack; }; } Declaration; @@ -888,7 +888,6 @@ typedef struct Evaluator { struct Typer *typer; bool returning; Value ret_val; - void **to_free; /* an array of data to free for this scope. */ bool enabled; ForeignFnManager ffmgr; } Evaluator; |