diff options
Diffstat (limited to 'decls_cgen.c')
-rw-r--r-- | decls_cgen.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/decls_cgen.c b/decls_cgen.c index 1df359d..ad547ee 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -2,23 +2,37 @@ static bool cgen_decls_stmt(CGenerator *g, Statement *s); static bool cgen_decls_block(CGenerator *g, Block *b); static bool cgen_decls_decl(CGenerator *g, Declaration *d); +static bool cgen_decls_fn_instances(CGenerator *g, Expression *e) { + assert(e->kind == EXPR_FN); + FnExpr *f = &e->fn; + FnType *type = &e->type.fn; + assert(type->constness); + Instance **data = f->instances.data; + for (U64 i = 0; i < f->instances.cap; i++) { + if (f->instances.occupied[i]) { + if (!cgen_fn_header(g, f, e->where, (*data)->c.id, (*data)->val.tuple[0].u64)) + return false; + cgen_write(g, ";"); + cgen_nl(g); + } + data++; + } + return true; +} + static bool cgen_decls_expr(CGenerator *g, Expression *e) { cgen_recurse_subexprs(g, e, cgen_decls_expr, cgen_decls_block, cgen_decls_decl); switch (e->kind) { - case EXPR_FN: - e->fn.c.name = NULL; - if (!e->fn.c.id) - e->fn.c.id = g->ident_counter++; - bool any_const = false; + case EXPR_FN: { + FnExpr *f = &e->fn; + f->c.name = NULL; + if (!f->c.id) + f->c.id = g->ident_counter++; FnType *fn_type = &e->type.fn; if (fn_type->constness) { - for (size_t i = 0; i < arr_len(fn_type->types)-1; i++) { - if (fn_type->constness[i] == CONSTNESS_YES) - any_const = true; - } - } - - if (!any_const) { + if (!cgen_decls_fn_instances(g, e)) + return false; + } else { fn_enter(&e->fn, 0); if (!cgen_fn_header(g, &e->fn, e->where, 0, 0)) return false; @@ -26,7 +40,7 @@ static bool cgen_decls_expr(CGenerator *g, Expression *e) { cgen_nl(g); fn_exit(&e->fn); } - break; + } break; default: break; } @@ -48,7 +62,10 @@ static bool cgen_decls_block(CGenerator *g, Block *b) { static bool cgen_decls_decl(CGenerator *g, Declaration *d) { if (cgen_fn_is_direct(g, d)) { d->expr.fn.c.name = d->idents[0]; - if (!fn_has_any_const_params(&d->expr.fn)) { + if (d->expr.type.fn.constness) { + if (!cgen_decls_fn_instances(g, &d->expr)) + return false; + } else { fn_enter(&d->expr.fn, 0); if (!cgen_fn_header(g, &d->expr.fn, d->where, 0, 0)) return false; |