diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-11-17 13:40:59 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-11-17 13:40:59 -0500 |
commit | 6aa688daf4fbd5afd664b7687bcccebcc4eccb98 (patch) | |
tree | 7f3aee9d89dcb2df1fd0feccd43ef8dbbdd78975 | |
parent | 673b993783f99bf4317215cf967d0db534112823 (diff) |
declarations of fns with const params
-rw-r--r-- | cgen.c | 20 | ||||
-rw-r--r-- | decls_cgen.c | 45 | ||||
-rw-r--r-- | main.c | 1 | ||||
-rw-r--r-- | test.toc | 26 |
4 files changed, 48 insertions, 44 deletions
@@ -128,14 +128,6 @@ static bool cgen_defs_decl(CGenerator *g, Declaration *d); break; \ } -static inline bool fn_has_any_const_params(FnExpr *f) { - arr_foreach(f->params, Declaration, param) { - if (param->flags & DECL_IS_CONST) - return true; - } - return false; -} - static bool cgen_block_enter(CGenerator *g, Block *b) { g->block = b; Statement *stmts; @@ -418,6 +410,10 @@ static inline void cgen_fn_name(CGenerator *g, FnExpr *f) { } } +static inline void cgen_fn_instance_number(CGenerator *g, U64 instance) { + cgen_write(g, "%"PRIu64"_", instance); +} + /* unless f has const/semi-const args, instance and which_are_const can be set to 0 */ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where, U64 instance, U64 which_are_const) { bool out_param = cgen_uses_ptr(&f->ret_type); @@ -432,7 +428,7 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where, U64 instanc } cgen_fn_name(g, f); if (instance) { - cgen_write(g, "%"PRIu64, instance); + cgen_fn_instance_number(g, instance); } if (!out_param) { if (!cgen_type_post(g, &f->ret_type, where)) return false; @@ -599,7 +595,7 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, /* e.g. a, b = fn_which_returns_tuple(); */ if (!cgen_expr(g, to->call.fn)) return false; if (to->call.instance) - cgen_write(g, "%"PRIu64, to->call.instance->c.id); + cgen_fn_instance_number(g, to->call.instance->c.id); cgen_write(g, "("); bool any_args = false; Constness *constness = to->call.fn->type.fn.constness; @@ -966,7 +962,7 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { cgen_write(g, ";"); cgen_nl(g); if (!cgen_expr(g, e->call.fn)) return false; if (e->call.instance) { - cgen_write(g, "%"PRIu64, e->call.instance->c.id); + cgen_fn_instance_number(g, e->call.instance->c.id); } cgen_write(g, "("); bool any_args = false; @@ -1325,7 +1321,7 @@ static bool cgen_expr(CGenerator *g, Expression *e) { if (!cgen_expr(g, e->call.fn)) return false; if (e->call.instance) { - cgen_write(g, "%"PRIu64, e->call.instance->c.id); + cgen_fn_instance_number(g, e->call.instance->c.id); } cgen_write(g, "("); bool first_arg = true; 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; @@ -1,6 +1,5 @@ /* TODO: -declarations of things with constant params deal with typing functions with type parameters (we need to type every single instance) struct parameters @@ -7,23 +7,15 @@ puti @= fn(x: int) { // "); // }; -f@= fn(x : int, y :@ int) int { - x+y -}; + + main @= fn() { - something := f(10, 20); - puti(something); - something2 @= f(10, 20); - puti(something2); - something3 := f(10, 10+10); - puti(something3); - something4 := f(10, 23); - puti(something4); - r := 20; - something5 := f(10, r); - puti(something5); -g := f; -something6 := g(10, r); -puti(something6); + a, b := f(10, 20); + c, d := f(10, 10+10); + puti(a); puti(b); + puti(c); puti(d); +f @= fn(a: int, x @ int) (int, int) { + x * a, x + a +}; }; |