diff options
-rw-r--r-- | cgen.c | 18 | ||||
-rw-r--r-- | main.c | 4 | ||||
-rw-r--r-- | test.toc | 6 | ||||
-rw-r--r-- | types.c | 43 |
4 files changed, 49 insertions, 22 deletions
@@ -125,21 +125,21 @@ static bool cgen_defs_decl(CGenerator *g, Declaration *d); case EXPR_FN: { \ FnExpr *fn = &e->fn; \ if (e->type.fn.constness) { \ - Instance **data = fn->instance.data; \ - for (U64 i = 0; i < f->instances.cap; i++) { \ - if (f->instances.occupied[i]) { \ - cgen_recurse_subexprs_fn_simple(&(*data)->fn, decl_f, block_f); \ + Instance **data = fn->instances.data; \ + for (U64 i = 0; i < fn->instances.cap; i++) { \ + if (fn->instances.occupied[i]) { \ + cgen_recurse_subexprs_fn_simple((&(*data)->fn), decl_f, block_f); \ } \ data++; \ } \ } else { \ cgen_recurse_subexprs_fn_simple(fn, decl_f, block_f); \ } \ - break; \ - case EXPR_NEW: \ - if (e->new.n && !f(g, e->new.n)) \ - return false; \ - break; \ + } break; \ + case EXPR_NEW: \ + if (e->new.n && !f(g, e->new.n)) \ + return false; \ + break; \ } static bool cgen_block_enter(CGenerator *g, Block *b) { @@ -1,6 +1,8 @@ /* TODO: -deal with typing functions with type parameters (we need to type every single instance) +better errors (show where instance is) +alias type, instead of creating a new type. +make sure fn(t @ Type, x : t = 1598, y @ t = 9832) works don't cgen decls etc. in parameter initializers struct parameters @@ -11,8 +11,10 @@ putf @= fn(x: float) { main @= fn() { puti(g(int)); + puti(g()); }; -g @= fn(t @ Type) int { +g @= fn(t @= u8) int { 87347 as t as int -};
\ No newline at end of file +}; + @@ -1081,7 +1081,8 @@ static bool types_expr(Typer *tr, Expression *e) { arr_foreach(fn_decl->params, Declaration, param) { bool is_required = !(param->flags & DECL_HAS_EXPR); - long ident_idx = 0; + int ident_idx = 0; + arr_foreach(param->idents, Identifier, ident) { if (index == i) { if (is_required) { @@ -1090,15 +1091,37 @@ static bool types_expr(Typer *tr, Expression *e) { free(s); return false; } else { - assert(param->expr.kind == EXPR_VAL); /* evaluated in type_of_fn */ - new_args[i].kind = EXPR_VAL; - new_args[i].flags = param->expr.flags; - new_args[i].type = param->type.kind == TYPE_TUPLE - ? param->type.tuple[ident_idx] - : param->type; - new_args[i].val = param->type.kind == TYPE_TUPLE - ? param->expr.val.tuple[ident_idx] - : param->expr.val; + Value default_val; + if (fn_type->constness) { + /* TODO: evaluate once per decl, not once per ident */ + Expression copy; + /* make a copy of the default argument, and type and evaluate it. */ + Copier cop = {.block = tr->block, .allocr = tr->allocr}; + copy_expr(&cop, ©, ¶m->expr); + if (!types_expr(tr, ©)) + return false; + if (!eval_expr(tr->evalr, ©, &default_val)) + return false; + new_args[i].kind = EXPR_VAL; + new_args[i].flags = copy.flags; + new_args[i].type = copy.type.kind == TYPE_TUPLE + ? copy.type.tuple[ident_idx] + : copy.type; + new_args[i].val = copy.type.kind == TYPE_TUPLE + ? default_val.tuple[ident_idx] + : default_val; + } else { + /* it's already been evaluated */ + assert(param->expr.kind == EXPR_VAL); /* evaluated in type_of_fn */ + new_args[i].kind = EXPR_VAL; + new_args[i].flags = param->expr.flags; + new_args[i].type = param->type.kind == TYPE_TUPLE + ? param->type.tuple[ident_idx] + : param->type; + new_args[i].val = param->type.kind == TYPE_TUPLE + ? param->expr.val.tuple[ident_idx] + : param->expr.val; + } } } ident_idx++; |