From 429eeee4d194820890bcbd6010765f9f7eccb21e Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Fri, 20 Mar 2020 11:48:32 -0400 Subject: compile time defer --- cgen.c | 2 +- eval.c | 9 ++++++++- main.c | 1 + test.toc | 34 ++++++++++++++++------------------ tests/defer.toc | 8 ++++---- tests/defer_expected | 4 ++++ 6 files changed, 34 insertions(+), 24 deletions(-) diff --git a/cgen.c b/cgen.c index 2a469ea..5b430fc 100644 --- a/cgen.c +++ b/cgen.c @@ -673,7 +673,7 @@ static void cgen_fn_header(CGenerator *g, FnExpr *f, U64 which_are_const) { } static inline void cgen_deferred_from_block(CGenerator *g, Block *from) { - arr_foreach_reversed(from->deferred, StatementPtr, s) { + arr_foreach(from->deferred, StatementPtr, s) { cgen_stmt(g, *s); } } diff --git a/eval.c b/eval.c index 4dfb618..b4f1008 100644 --- a/eval.c +++ b/eval.c @@ -1708,7 +1708,7 @@ static Status eval_stmt(Evaluator *ev, Statement *stmt) { case STMT_MESSAGE: break; case STMT_DEFER: - /* TODO */ + *(Statement **)arr_add(&ev->typer->block->deferred) = stmt->defer; break; } return true; @@ -1717,6 +1717,7 @@ static Status eval_stmt(Evaluator *ev, Statement *stmt) { static Status eval_block(Evaluator *ev, Block *b, Value *v) { Block *prev = ev->typer->block; ev->typer->block = b; + b->deferred = NULL; bool success = true; Statement *last_reached = arr_last(b->stmts); arr_foreach(b->stmts, Statement, stmt) { @@ -1749,6 +1750,12 @@ static Status eval_block(Evaluator *ev, Block *b, Value *v) { } } } + arr_foreach(b->deferred, StatementPtr, stmtp) { + Statement *stmt = *stmtp; + if (!eval_stmt(ev, stmt)) + return false; + } + arr_clear(&b->deferred); eval_exit_stmts(b->stmts, last_reached); ret: ev->typer->block = prev; diff --git a/main.c b/main.c index e06e818..98daee8 100644 --- a/main.c +++ b/main.c @@ -8,6 +8,7 @@ /* TODO: +compile time defer use - use with a decl, e.g. use p : Point; &&, || diff --git a/test.toc b/test.toc index b1d5e06..058d589 100644 --- a/test.toc +++ b/test.toc @@ -1,24 +1,22 @@ #include "std/io.toc", io; -s ::= struct (t :: Type, hasz ::= true) { - x, y: t; - #if hasz { - z: t; - a :: t = 3 as t; - } -} - main ::= fn() { - p: s(float); - p.x = 7; - p.y = 13; - p.z = 12; - io.puti(p.x as int); - io.puti(s(int).a as int); - q: s(int, false); - q.x = 13; - io.puti(q.x); - //io.puti(q.a); + defer io.puts("deferred from main"); + for i := 0..10 { + defer io.puti(i); + if i == 7 { + defer io.puts("break!!!"); + break; + } + if i % 2 == 0 { + defer io.puts("continue!!!"); + continue; + } + io.puts("number..."); + } + return; + io.puts("end of main"); } +main(); diff --git a/tests/defer.toc b/tests/defer.toc index 6c2a304..578668d 100644 --- a/tests/defer.toc +++ b/tests/defer.toc @@ -26,10 +26,10 @@ main ::= fn() { io.puti(same(3)); a, b := thing1(); c, d := thing2(); - io.puti(a); - io.puti(b); - io.puti(c); - io.puti(d); + e, f ::= thing1(); + g, h ::= thing2(); + io.puti(a); io.puti(b); io.puti(c); io.puti(d); + io.puti(e); io.puti(f); io.puti(g); io.puti(h); defer io.puts("deferred from main()"); for i := 1..10 { defer io.puts("deferred from for"); diff --git a/tests/defer_expected b/tests/defer_expected index e678115..1c13a6d 100644 --- a/tests/defer_expected +++ b/tests/defer_expected @@ -4,6 +4,10 @@ 6 6 6 +5 +6 +6 +6 1 deferred from for 2 -- cgit v1.2.3