summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eval.c4
-rw-r--r--main.c3
-rw-r--r--test.toc6
-rw-r--r--types.c26
-rw-r--r--types.h3
5 files changed, 18 insertions, 24 deletions
diff --git a/eval.c b/eval.c
index 39820bc..e65079d 100644
--- a/eval.c
+++ b/eval.c
@@ -4,7 +4,7 @@
You should have received a copy of the GNU General Public License along with toc. If not, see <https://www.gnu.org/licenses/>.
*/
static bool types_block(Typer *tr, Block *b);
-static bool types_decl(Typer *tr, Declaration *d, TypesDeclFlags flags);
+static bool types_decl(Typer *tr, Declaration *d);
static bool type_resolve(Typer *tr, Type *t, Location where);
static size_t compiler_sizeof(Type *t);
static bool eval_block(Evaluator *ev, Block *b, Type *t, Value *v);
@@ -1323,7 +1323,7 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
Declaration *d = NULL;
if (is_decl) {
d = idecl->decl;
- if (!types_decl(ev->typer, d, 0)) return false;
+ if (!types_decl(ev->typer, d)) return false;
assert(d->type.flags & TYPE_IS_RESOLVED);
}
if (idecl->flags & IDECL_HAS_VAL) {
diff --git a/main.c b/main.c
index b8adf18..e45e38e 100644
--- a/main.c
+++ b/main.c
@@ -6,9 +6,6 @@
/*
TODO:
-reduce copying (don't copy body of fn_copy unless the instance doesn't
-exist yet)
-
make sure you can't have a tuple parameter (check const tuple params)
check arr.toc's Arr works @ compile time
new version of copy_val for copying types??
diff --git a/test.toc b/test.toc
index e210822..864d7a9 100644
--- a/test.toc
+++ b/test.toc
@@ -7,12 +7,16 @@ putf ::= fn(x: float) {
");
};
+foo ::= fn(x ::= 5) (int, int) {
+x, 2*x
+};
+
main ::= fn() {
puti(f(3));
puti(f(7));
puti(f(4));
- f ::= fn(x :: int) y := x + 1 { };
+ f ::= fn(x ::= foo()) y := x + 1 { };
r ::= f(3);
puti(r);
diff --git a/types.c b/types.c
index 5d13ef3..511df44 100644
--- a/types.c
+++ b/types.c
@@ -229,8 +229,7 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Location where, Type *t, U16 flags)
for (param_idx = 0; param_idx < nparams; param_idx++) {
Declaration *param = &f->params[param_idx];
if (!generic) {
- U16 types_decl_flags = 0;
- if (!types_decl(tr, param, types_decl_flags)) {
+ if (!types_decl(tr, param)) {
success = false;
goto ret;
}
@@ -296,7 +295,7 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Location where, Type *t, U16 flags)
/* find return type */
arr_foreach(f->ret_decls, Declaration, d) {
- if (!types_decl(tr, d, 0)) {
+ if (!types_decl(tr, d)) {
success = false;
goto ret;
}
@@ -405,7 +404,7 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) {
free(s);
} else {
/* let's type the declaration, and redo this (for evaling future functions) */
- if (!types_decl(tr, d, 0)) return false;
+ if (!types_decl(tr, d)) return false;
return type_of_ident(tr, where, i, t);
}
return false;
@@ -1139,6 +1138,7 @@ static bool types_expr(Typer *tr, Expression *e) {
Type table_index_type = {0};
Value table_index = {0};
FnExpr fn_copy;
+ Copier cop = copier_create(tr->allocr, tr->block);
if (fn_type->constness) {
/* evaluate compile-time arguments + add an instance */
@@ -1152,9 +1152,7 @@ static bool types_expr(Typer *tr, Expression *e) {
/* fn is the instance, original_fn is not */
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);
+ copy_fn_expr(&cop, &fn_copy, fn, false);
fn = &fn_copy;
table_index_type.flags = TYPE_IS_RESOLVED;
@@ -1256,7 +1254,10 @@ static bool types_expr(Typer *tr, Expression *e) {
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) {
+ copy_block(&cop, &fn_copy.body, &original_fn->body);
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 */
@@ -1737,7 +1738,7 @@ static bool types_block(Typer *tr, Block *b) {
return success;
}
-static bool types_decl(Typer *tr, Declaration *d, TypesDeclFlags flags) {
+static bool types_decl(Typer *tr, Declaration *d) {
bool success = true;
if (d->flags & DECL_FOUND_TYPE) return true;
Declaration **dptr = typer_arr_add(tr, &tr->in_decls);
@@ -1745,12 +1746,7 @@ static bool types_decl(Typer *tr, Declaration *d, TypesDeclFlags flags) {
if (d->flags & DECL_ANNOTATES_TYPE) {
/* type supplied */
assert(d->type.kind != TYPE_VOID); /* there's no way to annotate void */
- /*
- if it's a parameter, only partially resolve the type, so that,
- for example, fn (x @ Type, y : x) works
- */
- if (!(flags & TYPES_DECL_DONT_RESOLVE)
- && !type_resolve(tr, &d->type, d->where)) {
+ if (!type_resolve(tr, &d->type, d->where)) {
success = false;
goto ret;
}
@@ -1853,7 +1849,7 @@ static bool types_stmt(Typer *tr, Statement *s) {
}
break;
case STMT_DECL:
- if (!types_decl(tr, &s->decl, 0))
+ if (!types_decl(tr, &s->decl))
return false;
break;
case STMT_RET:
diff --git a/types.h b/types.h
index c522fb0..dd00a94 100644
--- a/types.h
+++ b/types.h
@@ -723,6 +723,3 @@ typedef struct CGenerator {
Identifiers *idents;
} CGenerator;
-typedef enum {
- TYPES_DECL_DONT_RESOLVE = 0x01 /* don't resolve the annotated type (used for parameters). */
-} TypesDeclFlags;