diff options
-rw-r--r-- | cgen.c | 10 | ||||
-rw-r--r-- | main.c | 8 | ||||
-rw-r--r-- | parse.c | 10 | ||||
-rw-r--r-- | test.toc | 32 | ||||
-rw-r--r-- | toc.c | 1 | ||||
-rw-r--r-- | types.c | 4 |
6 files changed, 36 insertions, 29 deletions
@@ -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_;"); } } @@ -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 @@ -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) { @@ -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"); } @@ -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); @@ -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; |