From 5521461a61b55124cee90e1bfcc946b1a029570f Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Tue, 15 Oct 2019 13:22:59 -0400 Subject: more out params, fixed anon fns --- abbrevs.txt | 1 + cgen.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++---------- out.c | 26 +++++++++++++++-- test.toc | 5 +++- types.h | 1 + 5 files changed, 108 insertions(+), 19 deletions(-) diff --git a/abbrevs.txt b/abbrevs.txt index 49d29ce..d694268 100644 --- a/abbrevs.txt +++ b/abbrevs.txt @@ -1,4 +1,5 @@ allocr - allocator +anon - anonymous arg - argument decl - declaration del - delete diff --git a/cgen.c b/cgen.c index 8bd9964..4b4b3c7 100644 --- a/cgen.c +++ b/cgen.c @@ -3,6 +3,7 @@ static bool cgen_block(CGenerator *g, Block *b); static bool cgen_expr(CGenerator *g, Expression *e); static bool cgen_type_pre(CGenerator *g, Type *t, Location where); static bool cgen_type_post(CGenerator *g, Type *t, Location where); +static bool cgen_decl(CGenerator *g, Declaration *d); static void cgen_create(CGenerator *g, FILE *out, Identifiers *ids, Evaluator *ev) { g->outc = out; @@ -11,6 +12,7 @@ static void cgen_create(CGenerator *g, FILE *out, Identifiers *ids, Evaluator *e g->evalr = ev; g->will_indent = true; g->indent_lvl = 0; + g->anon_fns = NULL; } static void cgen_block_enter(CGenerator *g, Block *b) { @@ -64,6 +66,15 @@ static inline void cgen_nl(CGenerator *g) { g->will_indent = true; } +static inline void cgen_writeln(CGenerator *g, const char *fmt, ...) { + va_list args; + cgen_indent(g); + va_start(args, fmt); + vfprintf(cgen_writing_to(g), fmt, args); + va_end(args); + cgen_nl(g); +} + /* should declaration be a direct function declaration C (as opposed to using a function pointer or not being a function) */ static bool cgen_fn_is_direct(CGenerator *g, Declaration *d) { return g->block == NULL && (d->flags & DECL_FLAG_HAS_EXPR) && d->expr.kind == EXPR_FN && arr_len(d->idents) == 1; @@ -196,6 +207,14 @@ static bool cgen_type_post(CGenerator *g, Type *t, Location where) { return true; } +static inline void cgen_fn_name(CGenerator *g, FnExpr *f) { + if (f->c.name) { + cgen_ident(g, f->c.name); + } else { + cgen_ident_id(g, f->c.id); + } +} + static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where) { bool out_param = cgen_uses_ptr(&f->ret_type); bool any_params = false; @@ -205,11 +224,7 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where) { if (!cgen_type_pre(g, &f->ret_type, where)) return false; cgen_write(g, " "); } - if (f->c.name) { - cgen_ident(g, f->c.name); - } else { - cgen_ident_id(g, f->c.id); - } + cgen_fn_name(g, f); if (!out_param) { if (!cgen_type_post(g, &f->ret_type, where)) return false; } @@ -306,6 +321,22 @@ static bool cgen_set(CGenerator *g, Expression *set_expr, const char *set_str, E cgen_nl(g); cgen_write(g, "}"); break; + case TYPE_TUPLE: + assert(set_expr); + assert(to_expr); + switch (to_expr->kind) { + case EXPR_TUPLE: + for (size_t i = 0; i < arr_len(to_expr->tuple); i++) { + cgen_set(g, &set_expr->tuple[i], NULL, &to_expr->tuple[i], NULL); + } + break; + case EXPR_CALL: + /* TODO */ + break; + default: + assert(0); break; + } + break; case TYPE_VOID: assert(0); return false; @@ -456,6 +487,13 @@ static bool cgen_expr(CGenerator *g, Expression *e) { case DIRECT_COUNT: assert(0); break; } break; + case EXPR_FN: { + if (g->block != NULL) { + Expression **eptr = arr_add(&g->anon_fns); + *eptr = e; + } + cgen_fn_name(g, &e->fn); + } break; } return true; } @@ -496,18 +534,38 @@ static void cgen_zero_value(CGenerator *g, Type *t) { } } +static bool cgen_fn(CGenerator *g, FnExpr *f, Location where) { + if (!cgen_fn_header(g, f, where)) + return false; + cgen_write(g, " "); + FnExpr *prev_fn = g->fn; + g->fn = f; + cgen_write(g, "{"); + cgen_nl(g); + arr_foreach(f->ret_decls, Declaration, d) { + cgen_decl(g, d); + } + if (!cgen_block(g, &f->body)) + return false; + if (f->ret_decls) { + if (cgen_uses_ptr(&f->ret_type)) { + } else { + cgen_write(g, "return "); + cgen_ident(g, f->ret_decls[0].idents[0]); + cgen_writeln(g, ";"); + } + } + cgen_write(g, "}"); + cgen_nl(g); + g->fn = prev_fn; + cgen_nl(g); + cgen_nl(g); + return true; +} + static bool cgen_decl(CGenerator *g, Declaration *d) { if (cgen_fn_is_direct(g, d)) { - if (!cgen_fn_header(g, &d->expr.fn, d->where)) - return false; - cgen_write(g, " "); - FnExpr *prev_fn = g->fn; - g->fn = &d->expr.fn; - if (!cgen_block(g, &d->expr.fn.body)) - return false; - g->fn = prev_fn; - cgen_nl(g); - cgen_nl(g); + cgen_fn(g, &d->expr.fn, d->where); } else if (d->flags & DECL_FLAG_CONST) { /* TODO */ } else { @@ -613,5 +671,11 @@ static bool cgen_file(CGenerator *g, ParsedFile *f) { if (!cgen_stmt(g, s)) return false; + typedef Expression *ExprPtr; + arr_foreach(g->anon_fns, ExprPtr, eptr) { + Expression *e = *eptr; + cgen_fn(g, &e->fn, e->where); + } + return true; } diff --git a/out.c b/out.c index 45a817b..1c14262 100644 --- a/out.c +++ b/out.c @@ -20,6 +20,7 @@ i64 puti(i64 i); void dbl(i64((* x)[3])); i64 foo(void); void main__(void); + void a0_(void); /* code */ int main() { main__(); @@ -27,28 +28,47 @@ int main() { } i64 puti(i64 i) { + { printf("%ld\n", i); -} +}} + void dbl(i64((* x)[3])) { + { ((*x)[0]) = (((*x)[0])*2);; ((*x)[1]) = (((*x)[1])*2);; ((*x)[2]) = (((*x)[2])*2);; -} +}} + i64 foo(void) { +i64 a = 0; + { a = 3;; if (true) { a = 4;; } else if (false) { a = (17+(1/0));; }; +}return a; } + void main__(void) { + { i64( a[3]) = {0}; (a[0]) = 1;; + (a[0]) = 5;(a[1]) = (8+(a[0]));; (dbl((&a))); + void (* asdfnahsdf)(void); { + void (* expr__)(void); expr__ = a0_;asdfnahsdf = expr__;} (puti((a[0]))); -} + (puti((foo()))); +}} + + +void a0_(void) { + { +}} + diff --git a/test.toc b/test.toc index c0ba997..ffe245d 100644 --- a/test.toc +++ b/test.toc @@ -22,6 +22,9 @@ foo @= fn() a: int { main @= fn() { a : [3]int; a[0] = 1; - dbl(&a); + a[0], a[1] = 5, 8+a[0]; + dbl(&a); + asdfnahsdf:=fn() {}; puti(a[0]); + puti(foo()); }; \ No newline at end of file diff --git a/types.h b/types.h index 9a375bd..ea7fc23 100644 --- a/types.h +++ b/types.h @@ -504,6 +504,7 @@ typedef struct { ParsedFile *file; Block *block; FnExpr *fn; /* which function are we in? (NULL for none) - not used during decls */ + Expression **anon_fns; /* array of pointers to expressions of anonymous functions */ Evaluator *evalr; Identifier main_ident; } CGenerator; -- cgit v1.2.3