diff options
-rw-r--r-- | eval.c | 4 | ||||
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | test.toc | 6 | ||||
-rw-r--r-- | types.c | 26 | ||||
-rw-r--r-- | types.h | 3 |
5 files changed, 18 insertions, 24 deletions
@@ -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) { @@ -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?? @@ -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); @@ -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: @@ -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; |