summaryrefslogtreecommitdiff
path: root/decls_cgen.c
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-10-11 11:20:04 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-10-11 11:20:04 -0400
commit60566944cb85c60e4243475c964b88b206cfb959 (patch)
treeacdd8ae14fdb83a953c9e64479ce912c5559dfe7 /decls_cgen.c
parent27319a805be7c9dfcee62efd6181dec9afc50dd4 (diff)
more cgen (bin ops, direct c)
Diffstat (limited to 'decls_cgen.c')
-rw-r--r--decls_cgen.c76
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;