diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-12-11 19:15:43 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-12-11 19:15:43 -0500 |
commit | 4792c78ad79404c64decc5af780f1c979a4e7f14 (patch) | |
tree | 90b78304534dc92c5816341f0c7eb7b96a11deb6 | |
parent | 91573bf993dc595dcbc1f83c28c4f7ee66ac334b (diff) |
more infer
-rw-r--r-- | infer.c | 39 | ||||
-rw-r--r-- | test.toc | 9 | ||||
-rw-r--r-- | types.c | 42 |
3 files changed, 32 insertions, 58 deletions
@@ -1,16 +1,29 @@ -/* infers */ -static bool infer_expr(Typer *tr, Expression *e, Declaration *decls, - Expression *exprs) { - e->kind = EXPR_VAL; - Value *val = &e->val; - val->type = malloc(sizeof *val->type); - memset(val->type, 0, sizeof *val->type); - val->type->kind = TYPE_BUILTIN; - val->type->builtin = BUILTIN_I64; - val->type->flags = TYPE_IS_RESOLVED; - memset(&e->type, 0, sizeof e->type); - e->type.kind = TYPE_TYPE; - e->type.flags = TYPE_IS_RESOLVED; +/* infers the expression of decls[idx], according to the types of the other decls */ +static bool infer_expr(Typer *tr, size_t idx, Declaration *decls) { + Declaration *decl = decls + idx; + if (decl->flags & DECL_HAS_EXPR) return true; /* already did it */ + + decl->expr.kind = EXPR_VAL; + decl->expr.type.flags = TYPE_IS_RESOLVED; + decl->expr.type.kind = TYPE_TYPE; + decl->expr.val.type = calloc(1,sizeof (Type)); + decl->expr.val.type->kind = TYPE_BUILTIN; + decl->expr.val.type->builtin = BUILTIN_I64; + decl->expr.val.type->flags = TYPE_IS_RESOLVED; + + decl->type = decl->expr.type; + decl->flags |= DECL_FOUND_TYPE; + decl->flags |= DECL_HAS_EXPR; + return true; +} + +/* infers ALL of the expressions in the declarations */ +static bool infer_exprs_in_decls(Typer *tr, Declaration *decls) { + for (size_t idx = 0; idx < arr_len(decls); ++idx) { + if (decls[idx].flags & DECL_INFER) + if (!infer_expr(tr, idx, decls)) + return false; + } return true; } @@ -1,8 +1,7 @@ -P ::= struct { - x, y:int; +f ::= fn(t::=, x :t) t { + x + 1 }; + main ::= fn() { - p:P; - x::="y"; - p[x]; + f(13); };
\ No newline at end of file @@ -1203,7 +1203,8 @@ static bool types_expr(Typer *tr, Expression *e) { U64 *which_are_const = &which_are_const_val->u64; *which_are_const = 0; int semi_const_index = 0; - + if (!infer_exprs_in_decls(tr, fn->params)) + return false; /* eval compile time arguments */ for (i = 0; i < nparams; ++i) { bool should_be_evald = arg_is_const(&arg_exprs[i], fn_type->constness[i]); @@ -1230,45 +1231,6 @@ static bool types_expr(Typer *tr, Expression *e) { if (!(param_decl->flags & DECL_ANNOTATES_TYPE)) { param_decl->type = *type; } - } else if (param_decl->flags & DECL_INFER) { - arg_exprs[i].kind = EXPR_VAL; - arg_exprs[i].flags = EXPR_FOUND_TYPE; - { - for (Declaration *p = fn->params; p < param_decl; ++p) { - if (p->flags & DECL_FOUND_VAL) - if (!add_ident_decls(&fn->body, p, SCOPE_CHECK_REDECL)) { - for (Declaration *q = fn->params; q < p; ++q) - if (q->flags & DECL_FOUND_VAL) - remove_ident_decls(&fn->body, q); - return false; - } - } - } - bool success = infer_expr(tr, &arg_exprs[i], fn->params, arg_exprs); - for (Declaration *p = fn->params; p < param_decl; ++p) { - if (p->flags & DECL_FOUND_VAL) - remove_ident_decls(&fn->body, p); - } - if (!success) return false; - copy_val(tr->allocr, ¶m_decl->val, &arg_exprs[i].val, &arg_exprs[i].type); - - - if (param_decl->flags & DECL_ANNOTATES_TYPE) { - if (!type_resolve(tr, ¶m_decl->type, param_decl->where)) - return false; - Type *expected = &arg_exprs[i].type; - Type *got = ¶m_decl->type; - if (!type_eq(expected, got)) { - char *estr = type_to_str(expected); - char *gstr = type_to_str(got); - err_print(param_decl->where, "Expected annotated type %s for this argument, but it was annotated as %s.", estr, gstr); - free(estr); free(gstr); - return false; - } - } - param_decl->type = arg_exprs[i].type; - param_decl->flags |= DECL_FOUND_VAL|DECL_FOUND_TYPE; - params_set[i] = true; } else { /* leave gap for this (default argument) */ typer_arr_add(tr, &table_index.tuple); |