summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-03-13 18:04:41 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-03-13 18:05:17 -0400
commit72101f2f5b80ae3c8889424351664fd651a84dec (patch)
treee58ebe75019dea8071a5dd48316e8b315aa43520
parent7bb5ac5863bdb4bc7af04ee18e81657a85aa97f2 (diff)
fixed eval returning from an include
-rw-r--r--eval.c39
-rw-r--r--test.toc7
-rw-r--r--types.c1
3 files changed, 31 insertions, 16 deletions
diff --git a/eval.c b/eval.c
index c2efc5d..b024b8b 100644
--- a/eval.c
+++ b/eval.c
@@ -1062,6 +1062,7 @@ static Value *decl_add_val(Declaration *d) {
}
static void decl_remove_val(Declaration *d) {
+ assert(arr_len(d->val_stack));
Value **valpp = arr_last(d->val_stack);
Value *valp = *valpp;
if (arr_len(d->idents) == 1 || d->type.kind == TYPE_TUPLE) {
@@ -1642,6 +1643,19 @@ static Status eval_decl(Evaluator *ev, Declaration *d) {
return true;
}
+
+static void eval_exit_stmts(Statement *stmts, Statement *last_reached) {
+ if (stmts) {
+ for (Statement *s = stmts; s <= last_reached; ++s) {
+ if (s->kind == STMT_DECL && !(s->decl->flags & DECL_IS_CONST)) {
+ Declaration *d = s->decl;
+ decl_remove_val(d);
+ }
+ /* STMT_INCLUDEs are handled by eval_stmt; don't worry */
+ }
+ }
+}
+
static Status eval_stmt(Evaluator *ev, Statement *stmt) {
switch (stmt->kind) {
case STMT_DECL:
@@ -1661,25 +1675,20 @@ static Status eval_stmt(Evaluator *ev, Statement *stmt) {
}
ev->returning = true;
} break;
- case STMT_INCLUDE:
- arr_foreach(stmt->inc.stmts, Statement, sub)
+ case STMT_INCLUDE: {
+ Statement *last_reached = arr_last(stmt->inc.stmts);
+ arr_foreach(stmt->inc.stmts, Statement, sub) {
if (!eval_stmt(ev, sub))
return false;
- break;
- }
- return true;
-}
-
-static void eval_exit_stmts(Statement *stmts, Statement *last_reached) {
- for (Statement *s = stmts; s <= last_reached; ++s) {
- if (s->kind == STMT_DECL && !(s->decl->flags & DECL_IS_CONST)) {
- Declaration *d = s->decl;
- decl_remove_val(d);
- } else if (s->kind == STMT_INCLUDE) {
- /* TODO: this doesn't work!!! */
- eval_exit_stmts(s->inc.stmts, arr_last(s->inc.stmts));
+ if (ev->returning) {
+ last_reached = sub;
+ break;
+ }
}
+ eval_exit_stmts(stmt->inc.stmts, last_reached);
+ } break;
}
+ return true;
}
static Status eval_block(Evaluator *ev, Block *b, Value *v) {
diff --git a/test.toc b/test.toc
index 4223656..52d952e 100644
--- a/test.toc
+++ b/test.toc
@@ -26,5 +26,10 @@ tprintf ::= fn(fmt :: []char, args: ..) where tprintf_valid(fmt, args.len) {
};
main ::= fn() {
- tprintf("%d %d%%\n\0", 3, 4);
+ tprintf("Hello\n\0");
+ return;
+ x := 5;
+ tprintf("%d %d%%\n\0", 3, 4);
};
+
+main(); \ No newline at end of file
diff --git a/types.c b/types.c
index d04e149..8a4d36d 100644
--- a/types.c
+++ b/types.c
@@ -2381,6 +2381,7 @@ static Status types_expr(Typer *tr, Expression *e) {
}
if (!val.boolv) {
err_print(fn_copy->condition->where, "Function where condition not satisfied. You are probably calling this function incorrectly.");
+ info_print(e->where, "Offending call is here.");
return false;
}
}