summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eval.c20
-rw-r--r--test.toc2
2 files changed, 15 insertions, 7 deletions
diff --git a/eval.c b/eval.c
index b4f1008..48a324c 100644
--- a/eval.c
+++ b/eval.c
@@ -1749,13 +1749,23 @@ static Status eval_block(Evaluator *ev, Block *b, Value *v) {
*v = r;
}
}
+
}
- arr_foreach(b->deferred, StatementPtr, stmtp) {
- Statement *stmt = *stmtp;
- if (!eval_stmt(ev, stmt))
- return false;
+ {
+ /* deal with deferred stmts */
+ /* these could overwrite ev->returning, ev->ret_val, so we should save them */
+ Block *return_block = ev->returning;
+ Value return_val = ev->ret_val;
+ ev->returning = NULL; /* if we didn't set this, the deferred stmts would immediately return */
+ arr_foreach(b->deferred, StatementPtr, stmtp) {
+ Statement *stmt = *stmtp;
+ if (!eval_stmt(ev, stmt))
+ return false;
+ }
+ arr_clear(&b->deferred);
+ ev->returning = return_block;
+ ev->ret_val = return_val;
}
- arr_clear(&b->deferred);
eval_exit_stmts(b->stmts, last_reached);
ret:
ev->typer->block = prev;
diff --git a/test.toc b/test.toc
index 058d589..1bc7c34 100644
--- a/test.toc
+++ b/test.toc
@@ -1,6 +1,5 @@
#include "std/io.toc", io;
-
main ::= fn() {
defer io.puts("deferred from main");
for i := 0..10 {
@@ -19,4 +18,3 @@ main ::= fn() {
io.puts("end of main");
}
main();
-