diff options
-rw-r--r-- | base_cgen.c | 40 | ||||
-rw-r--r-- | cgen.c | 52 | ||||
-rw-r--r-- | out.c | 17 | ||||
-rw-r--r-- | out.h | 3 | ||||
-rw-r--r-- | test.toc | 7 | ||||
-rw-r--r-- | types_cgen.c | 2 |
6 files changed, 73 insertions, 48 deletions
diff --git a/base_cgen.c b/base_cgen.c index a247e7c..dc793f8 100644 --- a/base_cgen.c +++ b/base_cgen.c @@ -177,11 +177,15 @@ static bool cgen_type_post(CGenerator *g, Type *t) { assert(t->fn.types.len > 0); size_t nparams = t->fn.types.len-1; cgen_write(g, ")("); - for (size_t i = 0; i < nparams; i++) { - if (!cgen_type_pre(g, ¶m_types[i])) return true; - if (!cgen_type_post(g, ¶m_types[i])) return true; - cgen_write(g, ","); - cgen_write_space(g); + if (nparams) { + for (size_t i = 0; i < nparams; i++) { + if (!cgen_type_pre(g, ¶m_types[i])) return true; + if (!cgen_type_post(g, ¶m_types[i])) return true; + cgen_write(g, ","); + cgen_write_space(g); + } + } else { + cgen_write(g, "void"); } cgen_write(g, ")"); if (!cgen_type_post(g, ret_type)) return false; @@ -205,8 +209,7 @@ static bool cgen_fn_name(CGenerator *g, FnExpr *f, Location *where) { return true; } -static bool cgen_fn_header(CGenerator *g, FnExpr *f) { - CGenWritingTo writing_to_before = g->writing_to; +static bool cgen_fn_header(CGenerator *g, FnExpr *f) { if (!f->name || g->block != NULL) { cgen_write(g, "static "); /* anonymous functions only exist in this translation unit */ } @@ -214,19 +217,22 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f) { cgen_fn_name(g, f, NULL); if (!cgen_type_post(g, &f->ret_type)) return false; cgen_write(g, "("); - arr_foreach(&f->params, Param, p) { - if (p != f->params.data) { - cgen_write(g, ","); - cgen_write_space(g); + if (f->params.len) { + arr_foreach(&f->params, Param, p) { + if (p != f->params.data) { + cgen_write(g, ","); + cgen_write_space(g); + } + if (!cgen_type_pre(g, &p->type)) + return false; + cgen_ident(g, p->name, NULL); + if (!cgen_type_post(g, &p->type)) + return false; } - if (!cgen_type_pre(g, &p->type)) - return false; - cgen_ident(g, p->name, NULL); - if (!cgen_type_post(g, &p->type)) - return false; + } else { + cgen_write(g, "void"); } cgen_write(g, ")"); - g->writing_to = writing_to_before; return true; } @@ -64,24 +64,6 @@ static bool cgen_expr(CGenerator *g, Expression *e) { static bool cgen_stmt(CGenerator *g, Statement *s); -/* Generates the definition of a function, not just the identifier */ -static bool cgen_fn(CGenerator *g, FnExpr *f) { - if (!cgen_fn_header(g, f)) return false; - bool ret = true; - cgen_write_space(g); - cgen_writeln(g, "{"); - g->indent_level++; - Block *prev_block = g->block; - cgen_block_enter(g, &f->body); - arr_foreach(&f->body.stmts, Statement, s) { - if (!cgen_stmt(g, s)) - ret = false; - } - cgen_block_exit(g, prev_block); - g->indent_level--; - cgen_writeln(g, "}"); - return ret; -} static bool cgen_decl(CGenerator *g, Declaration *d) { arr_foreach(&d->idents, Identifier, ident) { @@ -121,15 +103,35 @@ static bool cgen_stmt(CGenerator *g, Statement *s) { static bool cgen_fns_in_stmt(CGenerator *g, Statement *s); +/* Generates function definition, and the definitions of all functions inside this */ +static bool cgen_fn(CGenerator *g, FnExpr *f) { + if (!cgen_fn_header(g, f)) return false; + Block *prev_block = g->block; + cgen_block_enter(g, &f->body); + bool ret = true; + cgen_write_space(g); + cgen_writeln(g, "{"); + g->indent_level++; + arr_foreach(&f->body.stmts, Statement, s) { + if (!cgen_stmt(g, s)) + ret = false; + } + g->indent_level--; + cgen_writeln(g, "}"); + if (ret) { + arr_foreach(&f->body.stmts, Statement, stmt) { + if (!cgen_fns_in_stmt(g, stmt)) ret = false; + } + } + cgen_block_exit(g, prev_block); + return ret; +} + static bool cgen_fns_in_expr(CGenerator *g, Expression *e) { switch (e->kind) { - case EXPR_FN: - if (!cgen_fn(g, &e->fn)) return false; - bool ret = true; - arr_foreach(&e->fn.body.stmts, Statement, stmt) { - ret = ret && cgen_fns_in_stmt(g, stmt); - } - return ret; + case EXPR_FN: { + return cgen_fn(g, &e->fn); + } case EXPR_CALL: return cgen_fns_in_expr(g, e->call.fn); default: return true; @@ -1,7 +1,20 @@ #include "out.h" /* toc */ -void main__() { +static void foo(void); +static void a___(void); +void main__(void) { + void (*bar)(void) = a___; + foo(); + a___(); } -void foo() { +static void foo(void) { + void (*x)(void) = a___; +} +static void a___(void) { +} + +int main(void) { + main__(); + return 0; } @@ -1,3 +1,2 @@ #include <stdint.h> -void main__(); -static void foo(); +void main__(void); @@ -1,5 +1,8 @@ main @= fn() { - foo @ int = fn() {foo();}; - + foo @ fn() = fn() {x : fn() = bar;}; + bar : fn() = fn( ){}; + + foo(); + bar(); };
\ No newline at end of file diff --git a/types_cgen.c b/types_cgen.c index 541f1b5..28db722 100644 --- a/types_cgen.c +++ b/types_cgen.c @@ -26,6 +26,8 @@ static bool cgen_types_expr(CGenerator *g, Expression *e) { case EXPR_FN: { if (e->fn.name && g->block == NULL) { /* write named function prototypes in global scope to header file */ g->writing_to = CGEN_WRITING_TO_H; + } else { + g->writing_to = CGEN_WRITING_TO_C; } if (!cgen_types_fn(g, &e->fn, e->where)) return false; |