diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-11-19 21:49:20 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-11-19 21:49:20 -0500 |
commit | 1151e30d50b64e34356214c39beb0a62326e988c (patch) | |
tree | c432aa4003f1f388e8ce7fdf97147418a5d88141 /types.c | |
parent | 4a1f37e189f518dbde3cfc7911040df0ef748869 (diff) |
finally got type params to work
Diffstat (limited to 'types.c')
-rw-r--r-- | types.c | 43 |
1 files changed, 33 insertions, 10 deletions
@@ -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++; |