diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-11 11:20:04 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-11 11:20:04 -0400 |
commit | 60566944cb85c60e4243475c964b88b206cfb959 (patch) | |
tree | acdd8ae14fdb83a953c9e64479ce912c5559dfe7 /decls_cgen.c | |
parent | 27319a805be7c9dfcee62efd6181dec9afc50dd4 (diff) |
more cgen (bin ops, direct c)
Diffstat (limited to 'decls_cgen.c')
-rw-r--r-- | decls_cgen.c | 76 |
1 files changed, 75 insertions, 1 deletions
diff --git a/decls_cgen.c b/decls_cgen.c index 5310981..bbdb8a3 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -1,13 +1,87 @@ +static bool cgen_decls_stmt(CGenerator *g, Statement *s); +static bool cgen_decls_block(CGenerator *g, Block *b); + static bool cgen_decls_expr(CGenerator *g, Expression *e) { + switch (e->kind) { + case EXPR_UNARY_OP: + if (!cgen_decls_expr(g, e->unary.of)) + return false; + break; + case EXPR_BINARY_OP: + if (!cgen_decls_expr(g, e->binary.lhs) + || !cgen_decls_expr(g, e->binary.rhs)) + return false; + break; + case EXPR_CAST: + if (!cgen_decls_expr(g, e->cast.expr)) + return false; + break; + case EXPR_CALL: + if (!cgen_decls_expr(g, e->call.fn)) + return false; + arr_foreach(e->call.arg_exprs, Expression, a) + if (!cgen_decls_expr(g, a)) + return false; + break; + case EXPR_BLOCK: + if (!cgen_decls_block(g, &e->block)) + return false; + break; + case EXPR_IF: + if (e->if_.cond) + if (!cgen_decls_expr(g, e->if_.cond)) + return false; + if (!cgen_decls_block(g, &e->if_.body)) + return false; + if (e->if_.next_elif) + if (!cgen_decls_expr(g, e->if_.next_elif)) + return false; + break; + case EXPR_WHILE: + if (e->while_.cond) + if (!cgen_decls_expr(g, e->while_.cond)) + return false; + if (!cgen_decls_block(g, &e->while_.body)) + return false; + break; + case EXPR_TUPLE: + arr_foreach(e->tuple, Expression, x) + if (!cgen_decls_expr(g, x)) + return false; + break; + case EXPR_FN: + e->fn.c.name = NULL; + e->fn.c.id = g->ident_counter++; + if (!cgen_fn_header(g, &e->fn, e->where)) + return false; + cgen_write(g, ";\n"); + if (!cgen_decls_block(g, &e->fn.body)) + return false; + break; + case EXPR_DIRECT: + case EXPR_NEW: + case EXPR_IDENT: + case EXPR_LITERAL_BOOL: + case EXPR_LITERAL_INT: + case EXPR_LITERAL_STR: + case EXPR_LITERAL_CHAR: + case EXPR_LITERAL_FLOAT: + break; + } return true; } static bool cgen_decls_block(CGenerator *g, Block *b) { + Block *prev = g->block; + cgen_block_enter(g, b); + arr_foreach(b->stmts, Statement, s) + cgen_decls_stmt(g, s); + cgen_block_exit(g, prev); return true; } static bool cgen_decls_decl(CGenerator *g, Declaration *d) { - if ((d->flags & DECL_FLAG_HAS_EXPR) && d->expr.kind == EXPR_FN && arr_len(d->idents) == 1) { + if (cgen_is_fn_direct(g, d)) { d->expr.fn.c.name = d->idents[0]; if (!cgen_fn_header(g, &d->expr.fn, d->where)) return false; |