summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-03-10 20:25:59 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2020-03-10 20:25:59 -0400
commit960583df2ff6f8baa205d0e1a5dd07667978b92a (patch)
treec29ae43b79035ea62eaf423c83626752d5ac8bef
parent7c60a43619f1155b11ce116254197482b1d446ce (diff)
fixed varargs lookup
-rw-r--r--instance_table.c1
-rw-r--r--main.c3
-rw-r--r--test.toc10
-rw-r--r--types.c49
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;
diff --git a/main.c b/main.c
index e47bf36..1cfb32e 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/test.toc b/test.toc
index 879562f..52672d8 100644
--- a/test.toc
+++ b/test.toc
@@ -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
diff --git a/types.c b/types.c
index a772bd2..0cecd09 100644
--- a/types.c
+++ b/types.c
@@ -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;