summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--allocator.c2
-rw-r--r--eval.c68
-rw-r--r--main.c3
-rw-r--r--test.toc14
-rw-r--r--types.h3
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))
diff --git a/eval.c b/eval.c
index 9d73cb1..2d12773 100644
--- a/eval.c
+++ b/eval.c
@@ -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;
}
diff --git a/main.c b/main.c
index c578f87..5c31956 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/test.toc b/test.toc
index e2263b8..aa31aed 100644
--- a/test.toc
+++ b/test.toc
@@ -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
diff --git a/types.h b/types.h
index bf74d9c..64b4fc8 100644
--- a/types.h
+++ b/types.h
@@ -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;