summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--instance_table.c2
-rw-r--r--test.toc15
-rw-r--r--types.c34
3 files changed, 36 insertions, 15 deletions
diff --git a/instance_table.c b/instance_table.c
index 33a7eba..85bb71d 100644
--- a/instance_table.c
+++ b/instance_table.c
@@ -308,7 +308,7 @@ static bool val_eq(Value u, Value v, Type *t) {
*/
/* OPTIM: store instances in a block array (remember that the pointers need to stay valid!) */
static Instance *instance_table_adda(Allocator *a, HashTable *h, Value v, Type *t,
- bool *already_exists) {
+ bool *already_exists) {
if (h->n * 2 >= h->cap) {
U64 new_cap = h->cap * 2 + 3;
Instance **new_data = allocr_malloc(a, (size_t)new_cap * sizeof *new_data);
diff --git a/test.toc b/test.toc
index c0aca4b..6a00236 100644
--- a/test.toc
+++ b/test.toc
@@ -1,10 +1,9 @@
-main ::= fn() {
- mk_arr(z=0, 0, 0);
-
- mk_arr ::= fn(x:int, y:int, z:int) a:[3]int {
- a[0] = x;
- a[1] = y;
- a[2] = z;
- };
+f ::= fn(x: ..) int {
+ 3
+};
+main ::= fn() {
+ f(1,2,3);
};
+
+main(); \ No newline at end of file
diff --git a/types.c b/types.c
index d854445..5e387dd 100644
--- a/types.c
+++ b/types.c
@@ -1445,6 +1445,10 @@ static Status get_struct_constant(StructDef *struc, Identifier member, Expressio
}
}
+static bool fn_type_has_varargs(FnType *f) {
+ return type_is_builtin(arr_last(f->types), BUILTIN_VARARGS);
+}
+
static Status types_expr(Typer *tr, Expression *e) {
if (e->flags & EXPR_FOUND_TYPE) return true;
Type *t = &e->type;
@@ -1803,8 +1807,9 @@ static Status types_expr(Typer *tr, Expression *e) {
err_print(e->where, "Calling non-function (type %s).", type);
return false;
}
+ bool has_varargs = fn_type_has_varargs(&f->type.fn);
- if (expr_is_definitely_const(f) || type_is_builtin(&f->type, BUILTIN_TYPE)) {
+ if (expr_is_definitely_const(f) || type_is_builtin(&f->type, BUILTIN_TYPE) || has_varargs) {
Value val;
if (!eval_expr(tr->evalr, f, &val))
@@ -1989,7 +1994,8 @@ static Status types_expr(Typer *tr, Expression *e) {
c->arg_exprs = arg_exprs;
FnExpr *original_fn = NULL;
FnExpr *fn_copy = NULL;
- if (fn_type->constness) {
+
+ if (fn_type->constness || has_varargs) {
/* evaluate compile-time arguments + add an instance */
@@ -2004,7 +2010,10 @@ static Status types_expr(Typer *tr, Expression *e) {
fn_copy = typer_malloc(tr, sizeof *fn_copy);
Copier cop = copier_create(tr->allocr, fn->body.parent);
copy_fn_expr(&cop, fn_copy, fn, true);
- fn = fn_copy;
+ }
+
+ if (fn_type->constness) {
+ FnExpr *fn = fn_copy;
/* keep track of the declaration */
Declaration *param_decl = fn->params;
size_t ident_idx = 0;
@@ -2149,7 +2158,6 @@ static Status types_expr(Typer *tr, Expression *e) {
param_types = ret_type + 1;
}
- bool has_varargs = fn_decl && (fn_decl->flags & FN_EXPR_HAS_VARARGS);
/* check types of arguments */
for (size_t p = 0; p < nparams; ++p) {
@@ -2169,7 +2177,7 @@ static Status types_expr(Typer *tr, Expression *e) {
}
}
}
- if (fn_type->constness) {
+ if (fn_type->constness || has_varargs) {
Type table_index_type = {0};
Value table_index = {0};
@@ -2189,7 +2197,21 @@ static Status types_expr(Typer *tr, Expression *e) {
int semi_const_index = 0;
for (size_t i = 0; i < nparams; ++i) {
Expression *arg = &arg_exprs[i];
- if (arg_is_const(arg, fn_type->constness[i])) {
+ bool is_const = fn_type->constness && arg_is_const(arg, fn_type->constness[i]);
+ bool is_vararg = has_varargs && i == nparams-1;
+ if (is_vararg) {
+ if (is_const) {
+ /* TODO */
+ } else {
+ 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;
+ }
+ } else if (is_const) {
assert(arg->kind == EXPR_VAL);
if (fn_type->constness[i] == CONSTNESS_SEMI) {
if (semi_const_index >= 64) {