summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test.toc15
-rw-r--r--types.c53
-rw-r--r--types.h1
3 files changed, 30 insertions, 39 deletions
diff --git a/test.toc b/test.toc
index 0cb9375..a6e8d36 100644
--- a/test.toc
+++ b/test.toc
@@ -14,7 +14,6 @@ Arr ::= fn (t :: Type) Type {
}
};
-// todo: test that t :: type doesn't cause problems
arr_add ::= fn(t :: Type, a : &Arr(t), x : t) {
if a.len >= a.cap {
a.cap = a.cap * 2 + 2;
@@ -33,21 +32,9 @@ arr_add ::= fn(t :: Type, a : &Arr(t), x : t) {
main ::= fn() {
arr : Arr(int);
each i := 1..100 {
- arr_add(int, &arr, i*i);
+ arr_add(int, &arr, i*i);
}
each i := 0..arr.len - 1 {
puti(arr.data[i]);
}
};
-
-// t ::= fn(x :: Type) Type { struct { t: x; } };
-// // pass the wrong thing to t, and the error is in the wrong place
-
-// f ::= fn(x: t(int)) {};
-
-// f ::= fn(t :: Type, x : t) {
-// };
-
-// main ::= fn() {
-// f(int,3);
-// }; \ No newline at end of file
diff --git a/types.c b/types.c
index 7d104e7..26e259d 100644
--- a/types.c
+++ b/types.c
@@ -1141,6 +1141,10 @@ static bool types_expr(Typer *tr, Expression *e) {
}
}
}
+ FnExpr *original_fn;
+ Type table_index_type = {0};
+ Value table_index = {0};
+ FnExpr fn_copy;
if (fn_type->constness) {
/* evaluate compile-time arguments + add an instance */
@@ -1151,14 +1155,13 @@ static bool types_expr(Typer *tr, Expression *e) {
FnExpr *fn = fn_val.fn;
/* fn is the instance, original_fn is not */
- FnExpr *original_fn = fn;
- FnExpr fn_copy;
+ original_fn = fn;
+
Copier cop = copier_create(tr->allocr, tr->block);
/* TODO: somehow don't do all of this if we've already generated this instance */
copy_fn_expr(&cop, &fn_copy, fn, true);
fn = &fn_copy;
- Type table_index_type = {0};
table_index_type.flags = TYPE_IS_RESOLVED;
table_index_type.kind = TYPE_TUPLE;
table_index_type.tuple = NULL;
@@ -1167,7 +1170,6 @@ static bool types_expr(Typer *tr, Expression *e) {
u64t->flags = TYPE_IS_RESOLVED;
u64t->kind = TYPE_BUILTIN;
u64t->builtin = BUILTIN_U64;
- Value table_index;
table_index.tuple = NULL;
/* we need to keep table_index's memory around because instance_table_add makes a copy of it to compare against. */
Value *which_are_const_val = typer_arr_add(tr, &table_index.tuple);
@@ -1216,29 +1218,15 @@ static bool types_expr(Typer *tr, Expression *e) {
param_decl++;
}
}
-
- 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) {
- c->instance->fn = fn_copy;
- /* type param declarations, etc */
- if (!type_of_fn(tr, &c->instance->fn, e->where, &f->type, TYPE_OF_FN_IS_INSTANCE))
- return false;
- /* fix parameter and return types (they were kind of problematic before, because we didn't know about the instance) */
- c->instance->c.id = original_fn->instances.n; /* let's help cgen out and assign an ID to this */
- /* type this instance */
- if (!types_fn(tr, fn = &c->instance->fn, &f->type, e->where, c->instance))
- return false;
- c->instance->fn_type = &f->type;
- arr_clear(&table_index_type.tuple);
- } else {
- fn = &c->instance->fn;
- f->type = *c->instance->fn_type;
- }
+
+ /* type param declarations, etc */
+ if (!type_of_fn(tr, &fn_copy, e->where, &f->type, TYPE_OF_FN_IS_INSTANCE))
+ return false;
+
ret_type = f->type.fn.types;
param_types = ret_type + 1;
}
-
+
/* check types of arguments */
for (size_t p = 0; p < nparams; p++) {
Expression *arg = &new_args[p];
@@ -1249,8 +1237,25 @@ static bool types_expr(Typer *tr, Expression *e) {
char *estr = type_to_str(expected);
char *gstr = type_to_str(got);
err_print(arg->where, "Expected type %s as %lu%s argument to function, but got %s.", estr, 1+(unsigned long)p, ordinals(1+p), gstr);
+ return false;
}
}
+
+
+ if (fn_type->constness) {
+ 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) {
+ c->instance->fn = fn_copy;
+ /* fix parameter and return types (they were kind of problematic before, because we didn't know about the instance) */
+ c->instance->c.id = original_fn->instances.n; /* let's help cgen out and assign an ID to this */
+ /* type this instance */
+ if (!types_fn(tr, &c->instance->fn, &f->type, e->where, c->instance))
+ return false;
+ arr_clear(&table_index_type.tuple);
+ }
+ }
+
if (!ret) return false;
*t = *ret_type;
c->arg_exprs = new_args;
diff --git a/types.h b/types.h
index 43befe1..4db0243 100644
--- a/types.h
+++ b/types.h
@@ -528,7 +528,6 @@ typedef struct FnExpr {
typedef struct Instance {
Value val; /* key into hash table */
FnExpr fn; /* the typed function */
- Type *fn_type; /* type of fn */
struct {
U64 id;
} c;