diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-10 20:25:59 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-10 20:25:59 -0400 |
commit | 960583df2ff6f8baa205d0e1a5dd07667978b92a (patch) | |
tree | c29ae43b79035ea62eaf423c83626752d5ac8bef | |
parent | 7c60a43619f1155b11ce116254197482b1d446ce (diff) |
fixed varargs lookup
-rw-r--r-- | instance_table.c | 1 | ||||
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | test.toc | 10 | ||||
-rw-r--r-- | types.c | 49 |
4 files changed, 31 insertions, 32 deletions
diff --git a/instance_table.c b/instance_table.c index 85bb71d..571a529 100644 --- a/instance_table.c +++ b/instance_table.c @@ -318,6 +318,7 @@ static Instance *instance_table_adda(Allocator *a, HashTable *h, Value v, Type * for (U64 i = 0; i < h->cap; ++i) { /* re-hash */ if (old_occupied[i]) { + /* OPTIM: keep hashes around */ U64 index = val_hash(old_data[i]->val, t) % new_cap; while (new_occupied[index]) { ++index; @@ -8,8 +8,7 @@ /* TODO: -variadic fns -const varargs +fix compile time non-const varargs varargs only exist in decls. not a type of its own don't allow default varargs don't allow semiconst varargs @@ -1,9 +1,9 @@ #include "std/io.toc"; -f ::= fn(x :: ..) int { +f ::= fn(x : ..) int { total := 0; for a := x { - total += a; + total += a as int; } total }; @@ -12,5 +12,9 @@ main ::= fn() { puti(f(1,2,3)); puti(f(1,2,3,4,5,6)); puti(f(1,2,3,4)); + puti(f(1,7,3)); + puti(f(1,2,4,4,5,6)); + puti(f(1,2,-7.3,4.656)); -}; + puti(f(7.3,4.656)); +};
\ No newline at end of file @@ -1619,6 +1619,7 @@ static Status types_expr(Typer *tr, Expression *e) { arr_set_lena(&sub->stmts, total_nstmts, tr->allocr); Copier copier = copier_create(tr->allocr, sub); if (has_val) { + /* TODO: don't put a decl in each block, just put one at the start */ sub->stmts[0].flags = 0; sub->stmts[0].kind = STMT_DECL; sub->stmts[0].where = e->where; @@ -2314,30 +2315,26 @@ static Status types_expr(Typer *tr, Expression *e) { Expression *arg = &arg_exprs[i]; bool is_const = fn_type->constness && arg_is_const(arg, fn_type->constness[i]); bool is_vararg = has_varargs && i == nparams-1; + Copier cop = copier_create(tr->allocr, tr->block); if (is_vararg) { - if (is_const) { - /* add type */ - Value *v = typer_arr_add(tr, &table_index.tuple); - Type *type = typer_arr_add(tr, &table_index_type.tuple); - memset(type, 0, sizeof *type); - type->kind = TYPE_BUILTIN; - type->flags = TYPE_IS_RESOLVED; - type->builtin = BUILTIN_TYPE; - v->type = &arg->type; - /* add value */ - v = typer_arr_add(tr, &table_index.tuple); - type = typer_arr_add(tr, &table_index_type.tuple); - *type = arg->type; - *v = arg->val; - } else { - /* just add type */ - Value *v = typer_arr_add(tr, &table_index.tuple); - Type *type = typer_arr_add(tr, &table_index_type.tuple); - memset(type, 0, sizeof *type); - type->kind = TYPE_BUILTIN; - type->flags = TYPE_IS_RESOLVED; - type->builtin = BUILTIN_TYPE; - v->type = &arg->type; + /* create one additional table index member for varargs */ + Value *varargs_val = typer_arr_add(tr, &table_index.tuple); + Type *varargs_type = typer_arr_add(tr, &table_index_type.tuple); + memset(varargs_type, 0, sizeof *varargs_type); + varargs_type->flags = TYPE_IS_RESOLVED; + varargs_type->kind = TYPE_BUILTIN; + varargs_type->builtin = BUILTIN_VARARGS; + varargs_val->varargs = NULL; + for (; i < narg_exprs; ++i) { + arg = &arg_exprs[i]; + VarArg *varg = typer_arr_add(tr, &varargs_val->varargs); + varg->type = copy_type_(&cop, &arg->type); + if (is_const) { + copy_val(tr->allocr, &varg->val, &arg->val, varg->type); + } else { + /* use zero value everywhere */ + varg->val = val_zero(varg->type); + } } } else if (is_const) { assert(arg->kind == EXPR_VAL); @@ -2351,12 +2348,10 @@ static Status types_expr(Typer *tr, Expression *e) { } Value *v = typer_arr_add(tr, &table_index.tuple); Type *type = typer_arr_add(tr, &table_index_type.tuple); - *type = arg->type; + copy_type(&cop, type, &arg->type); copy_val(tr->allocr, v, &arg->val, type); } } - - bool instance_already_exists; c->instance = instance_table_adda(tr->allocr, &original_fn->instances, table_index, &table_index_type, &instance_already_exists); if (instance_already_exists) { @@ -2377,8 +2372,8 @@ static Status types_expr(Typer *tr, Expression *e) { tr->block = prev_block; arr_remove_lasta(&err_ctx->instance_stack, tr->allocr); if (!success) return false; - arr_cleara(&table_index_type.tuple, tr->allocr); } + } free(order); *t = *ret_type; |