summaryrefslogtreecommitdiff
path: root/decls_cgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'decls_cgen.c')
-rw-r--r--decls_cgen.c45
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;