summaryrefslogtreecommitdiff
path: root/infer.c
diff options
context:
space:
mode:
Diffstat (limited to 'infer.c')
-rw-r--r--infer.c50
1 files changed, 33 insertions, 17 deletions
diff --git a/infer.c b/infer.c
index ff875dc..3f2291d 100644
--- a/infer.c
+++ b/infer.c
@@ -25,27 +25,43 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Expres
break;
case EXPR_CALL: {
#if 0
- /* TODO: infer from parameterized structs */
- size_t nargs = arr_len(match->struc.args);
- Declaration *param = to->struc->params;
- int ident_idx = 0;
- for (i = 0; i < nargs; ++i) {
- Expression *arg = &match->struc.args[i];
- Value val = *decl_val_at_index(param, ident_idx);
- Expression val_expr = {0};
- val_expr.kind = EXPR_VAL;
- val_expr.val = val;
- val_expr.type = *decl_type_at_index(param, ident_idx);
- val_expr.flags = EXPR_FOUND_TYPE;
- if (!infer_from_expr(tr, arg, &val_expr, &val_expr, idents, vals, types)) {
+ if (to->kind == EXPR_TYPE) {
+ /* 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};
+ if (!types_expr(tr, match->call.fn)) {
return false;
}
- ++ident_idx;
- if (ident_idx >= (int)arr_len(param->idents)) {
- ++param;
- ident_idx = 0;
+ if (type_is_builtin(&match->call.fn->type, BUILTIN_TYPE)) {
+ /* it's a parameterized struct */
+ if (!eval_expr(tr->evalr, match->call.fn, &fn_val)) {
+ return false;
+ }
+ assert(fn_val.type->kind == TYPE_STRUCT);
+
+ size_t nargs = arr_len(match->call.args);
+ Declaration *param = fn_val.type->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 val_expr = {0};
+ val_expr.kind = EXPR_VAL;
+ val_expr.val = val;
+ val_expr.type = *decl_type_at_index(param, ident_idx);
+ val_expr.flags = EXPR_FOUND_TYPE;
+ if (!infer_from_expr(tr, arg, &val_expr, &val_expr, idents, vals, types)) {
+ return false;
+ }
+ ++ident_idx;
+ if (ident_idx >= (int)arr_len(param->idents)) {
+ ++param;
+ ident_idx = 0;
+ }
+ }
}
}
+
#endif
while (to->kind == EXPR_IDENT) {