From b6576fdcea56c89480fdf492c5aab731fa68d0c4 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Fri, 21 Feb 2020 12:43:38 -0500 Subject: started inferring struct params --- infer.c | 15 +++++++++------ main.c | 2 +- parse.c | 2 ++ test.toc | 11 ++++++----- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/infer.c b/infer.c index 3f2291d..35760fa 100644 --- a/infer.c +++ b/infer.c @@ -24,8 +24,7 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Expres } break; case EXPR_CALL: { -#if 0 - if (to->kind == EXPR_TYPE) { + if (to->kind == EXPR_TYPE && to->typeval.kind == TYPE_STRUCT) { /* maybe it's a parameterized struct? */ /* it might not be possible that it's not, but might as well keep that possibility around. */ Value fn_val = {0}; @@ -37,14 +36,19 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Expres if (!eval_expr(tr->evalr, match->call.fn, &fn_val)) { return false; } + assert(fn_val.type->kind == TYPE_STRUCT); + + I16 *order; + if (!parameterized_type_arg_order(tr, &order, match->where)) + return false; size_t nargs = arr_len(match->call.args); - Declaration *param = fn_val.type->struc->params; + Declaration *param = to->typeval.struc->params; int ident_idx = 0; for (size_t i = 0; i < nargs; ++i) { - Expression *arg = &match->call.args[i]; - Value val = *decl_val_at_index(param, ident_idx); + Expression *arg = &match->call.args[i].val; + Value val = arr_len(param->idents) > 1 ? param->val.tuple[ident_idx] : param->val; Expression val_expr = {0}; val_expr.kind = EXPR_VAL; val_expr.val = val; @@ -62,7 +66,6 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Expres } } -#endif while (to->kind == EXPR_IDENT) { Identifier i = to->ident; diff --git a/main.c b/main.c index 5addc27..886599b 100644 --- a/main.c +++ b/main.c @@ -23,7 +23,7 @@ TODO: - allow accessing parameters with . - make call_arg_param_order work more like parameterized_struct_arg_order -- inferred struct params? +- error on inferred struct param does this work: fn (a::=3, b::=2) - should either work or give an error: fn() --- diff --git a/parse.c b/parse.c index 206e59a..b7b2ce6 100644 --- a/parse.c +++ b/parse.c @@ -2543,6 +2543,8 @@ static inline Value *decl_val_at_index(Declaration *d, int i) { } static inline Type *decl_type_at_index(Declaration *d, int i) { + if (d->type.kind == TYPE_TUPLE) + assert(i < (int)arr_len(d->type.tuple)); Type *ret = d->type.kind == TYPE_TUPLE ? &d->type.tuple[i] : &d->type; assert(ret->kind != TYPE_TUPLE); return ret; diff --git a/test.toc b/test.toc index fcd6119..ff5f1d3 100644 --- a/test.toc +++ b/test.toc @@ -9,11 +9,12 @@ Thing ::= struct(t::=int, u::t=3) { that : [u]t; }; +f ::= fn(t::=,u::=,th : Thing(t,u)) { + x: t = 17 as t; + th.it = x; +}; + main ::= fn() { a: Thing(u = 172, t = u8); - b: Thing(); - c : Thing(i16); - d: Thing(u8, 428); - e: Thing(t = int, u = 3); - f: Thing(i16, 3); + f(a); }; \ No newline at end of file -- cgit v1.2.3