diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-15 13:22:59 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-15 13:22:59 -0400 |
commit | 5521461a61b55124cee90e1bfcc946b1a029570f (patch) | |
tree | bfc3ef9cc3c3cf8e0e50b69f73c8a716d4188ec3 | |
parent | c3ca8aec22cae9011fbd3a718e969634876fa858 (diff) |
more out params, fixed anon fns
-rw-r--r-- | abbrevs.txt | 1 | ||||
-rw-r--r-- | cgen.c | 94 | ||||
-rw-r--r-- | out.c | 26 | ||||
-rw-r--r-- | test.toc | 5 | ||||
-rw-r--r-- | 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 @@ -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; } @@ -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) { + { +}} + @@ -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 @@ -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; |