From 6fe4515f37bfe6ab12c85c4fa2f0242a922245cd Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Wed, 18 Mar 2020 14:30:54 -0400 Subject: defer seems to be working with functions now --- cgen.c | 10 ++++++++-- main.c | 8 ++++++-- parse.c | 10 ++++++++-- test.toc | 32 +++++++++----------------------- toc.c | 1 + types.c | 4 ++++ 6 files changed, 36 insertions(+), 29 deletions(-) diff --git a/cgen.c b/cgen.c index 5641d6f..1cfbff8 100644 --- a/cgen.c +++ b/cgen.c @@ -1821,7 +1821,11 @@ static void cgen_fn(CGenerator *g, FnExpr *f, Value *compile_time_args) { } cgen_block(g, &f->body, NULL, CGEN_BLOCK_NOBRACES); + Block *prev = g->block; + g->block = &f->body; + /* cgen_ret needs to think it's in the function body */ cgen_ret(g, &f->body, f->body.ret_expr); + g->block = prev; cgen_writeln(g, "}"); g->fn = prev_fn; @@ -1980,8 +1984,10 @@ static void cgen_ret(CGenerator *g, Block *returning_from, Expression *ret_expr) } else { cgen_set(g, NULL, "*ret__", &ret, NULL); } - cgen_write(g, " return;"); - } else if (f->ret_type.kind != TYPE_VOID) { + cgen_writeln(g, " return;"); + } else if (f->ret_type.kind == TYPE_VOID) { + cgen_writeln(g, "return;"); + } else { cgen_writeln(g, "return ret_;"); } } diff --git a/main.c b/main.c index f50b9ac..d1caf33 100644 --- a/main.c +++ b/main.c @@ -8,9 +8,12 @@ /* TODO: -defer -make sure defer works with for +make sure defer works with for, break, continue make sure you can't return a #C() (because of the current defer system) +switch to: + static void + foo() { +get rid of angle brackets for tuple types - just check if a TYPE_EXPR which is an EXPR_TUPLE is returned use &&, || start making a standard library... (printf; stringbuilder would be nice to have) @@ -23,6 +26,7 @@ switch to / add as an alternative: libffi X ::= newtype(int); or something any odd number of "s for a string --- +error on x ::= {return; 3} #returns_code (struct body is a block, to be evaluated at compile time, which returns the actual statements) - struct varargs macros diff --git a/parse.c b/parse.c index 37bf68e..4fc10e3 100644 --- a/parse.c +++ b/parse.c @@ -2448,17 +2448,23 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { return false; } goto success; - case KW_DEFER: + case KW_DEFER: { if (p->block == NULL) { tokr_err(t, "You can't defer something at global scope."); return false; } - s->kind = STMT_DEFER; ++t->token; + s->kind = STMT_DEFER; + Token *deferred_start = t->token; s->defer = parser_malloc(p, sizeof *s->defer); if (!parse_stmt(p, s->defer, was_a_statement)) return false; + if (!*was_a_statement) { + err_print(token_location(p->file, deferred_start), "Empty defer"); + return false; + } goto success; + } default: break; } } else if (t->token->kind == TOKEN_DIRECT) { diff --git a/test.toc b/test.toc index 790a115..9a5bfd8 100644 --- a/test.toc +++ b/test.toc @@ -1,27 +1,13 @@ -#include "std/mem.toc", mem; #include "std/io.toc", io; -calculation ::= fn() int { - total := 0; - i := mem.new(int); - *i = 3; - ns := mem.news(int, 10); - for n, i := &ns { - if i % 2 == 0 { - *n = i; - } - } - for n := ns { - total += n; - } - total += *i; - mem.del(i); - mem.dels(ns); - total -} - main ::= fn() { - io.puti(calculation()); - x ::= calculation(); - io.puti(x); + defer io.puts("second"); + defer io.puts("third"); + { + defer io.puts("there"); + io.puts("hey"); + } + io.puts("FIRST"); + return; + io.puts("first"); } diff --git a/toc.c b/toc.c index 6c1932d..dd9bd46 100644 --- a/toc.c +++ b/toc.c @@ -92,6 +92,7 @@ static void print_token(Token *t); static void print_type(Type *t); static void print_block(Block *b); static void print_decl(Declaration *d); +static void print_stmt(Statement *s); static void print_block_location(Block *b); diff --git a/types.c b/types.c index 9766997..f2b7db1 100644 --- a/types.c +++ b/types.c @@ -3402,6 +3402,10 @@ static Status types_stmt(Typer *tr, Statement *s) { err_print(s->where, "You can't defer a defer!"); return false; } + if (s->defer->kind == STMT_DECL) { + err_print(s->where, "Deferring a declaration doesn't make sense!"); + return false; + } break; } s->flags |= STMT_TYPED; -- cgit v1.2.3