summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c2
-rw-r--r--test.toc27
-rw-r--r--types.c16
3 files changed, 31 insertions, 14 deletions
diff --git a/main.c b/main.c
index a39d27c..2c95b63 100644
--- a/main.c
+++ b/main.c
@@ -19,8 +19,6 @@
/*
TODO:
-get ArrInt to work with inference
----
packages
---
X ::= newtype(int); or something
diff --git a/test.toc b/test.toc
index 9b414ad..566aed9 100644
--- a/test.toc
+++ b/test.toc
@@ -7,11 +7,26 @@ putf ::= fn(x: float) {
");
};
-main ::= fn() {
- Integer ::= id(int);
- x : Integer;
- puti(foo(x));
+SuperArray ::= fn(n :: int, t :: Type) Type {
+ struct {
+ data: [n]t;
+ field : t;
+ }
+};
+
+checksum ::= fn(t ::=, n ::=, x:SuperArray(n,t)) t {
+ total := 0 as t;
+ each i := 0..n-1 {
+ total += x.data[i];
+ }
+ total + x.field
};
-id ::= fn(t ::=, x :: t) t { x };
-foo ::= fn(t ::=, x : id(t)) int { 3 as t };
+Super ::= SuperArray(3, int);
+
+main ::= fn() {
+x: Super;
+x.data[0] = 3;
+x.field = 1932;
+puti(checksum(x));
+};
diff --git a/types.c b/types.c
index 34e7b08..46b51c4 100644
--- a/types.c
+++ b/types.c
@@ -191,7 +191,7 @@ enum {
TYPE_OF_FN_IS_INSTANCE = 0x01
};
-static bool type_of_fn(Typer *tr, FnExpr *f, Location where, Type *t, U16 flags) {
+static bool type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
t->kind = TYPE_FN;
t->fn.types = NULL;
t->fn.constness = NULL; /* OPTIM: constness doesn't need to be a dynamic array */
@@ -211,7 +211,6 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Location where, Type *t, U16 flags)
/* f has compile time params, but it's not an instance! */
bool generic = !(flags & TYPE_OF_FN_IS_INSTANCE) && fn_has_any_const_params(f);
-
if (generic) {
Copier cop = copier_create(tr->allocr, tr->block);
copy_fn_expr(&cop, &fn_copy, f, false);
@@ -308,6 +307,7 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Location where, Type *t, U16 flags)
f->ret_type.flags = TYPE_IS_RESOLVED;
f->ret_type.was_expr = NULL;
f->ret_type.tuple = NULL;
+ f->ret_type.where = f->ret_decls[0].where;
arr_foreach(f->ret_decls, Declaration, d) {
arr_foreach(d->idents, Identifier, i) {
*(Type *)arr_add(&f->ret_type.tuple) = d->type;
@@ -316,7 +316,7 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Location where, Type *t, U16 flags)
}
}
if (!generic) {
- if (!type_resolve(tr, &f->ret_type, where)) {
+ if (!type_resolve(tr, &f->ret_type, f->ret_type.where)) {
success = false;
goto ret;
}
@@ -398,7 +398,7 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) {
} else {
if ((d->flags & DECL_HAS_EXPR) && (d->expr.kind == EXPR_FN)) {
/* allow using a function before declaring it */
- if (!type_of_fn(tr, d->expr.fn, d->expr.where, t, 0)) return false;
+ if (!type_of_fn(tr, d->expr.fn, t, 0)) return false;
return true;
} else {
if (location_after(d->where, where)) {
@@ -514,6 +514,10 @@ static bool type_resolve(Typer *tr, Type *t, Location where) {
Value typeval;
if (!types_expr(tr, t->expr))
return false;
+ if (t->expr->type.kind != TYPE_TYPE) {
+ err_print(where, "This expression is not a type, but it's being used as one.");
+ return false;
+ }
Expression *expr = t->expr;
if (!eval_expr(tr->evalr, t->expr, &typeval))
return false;
@@ -809,7 +813,7 @@ static bool types_expr(Typer *tr, Expression *e) {
e->flags |= EXPR_FOUND_TYPE; /* even if failed, pretend we found the type */
switch (e->kind) {
case EXPR_FN: {
- if (!type_of_fn(tr, e->fn, e->where, &e->type, 0))
+ if (!type_of_fn(tr, e->fn, &e->type, 0))
return false;
if (fn_has_any_const_params(e->fn)) {
HashTable z = {0};
@@ -1374,7 +1378,7 @@ static bool types_expr(Typer *tr, Expression *e) {
}
}
/* type params, return declarations, etc */
- if (!type_of_fn(tr, &fn_copy, e->where, &f->type, TYPE_OF_FN_IS_INSTANCE))
+ if (!type_of_fn(tr, &fn_copy, &f->type, TYPE_OF_FN_IS_INSTANCE))
return false;
/* deal with default arguments */