|
|
|
@ -99,11 +99,19 @@ type_ptr ast_binop::typecheck(type_mgr& mgr, type_env_ptr& env) { |
|
|
|
|
type_ptr ftype = env->lookup(op_name(op))->instantiate(mgr); |
|
|
|
|
if(!ftype) throw type_error(std::string("unknown binary operator ") + op_name(op), loc); |
|
|
|
|
|
|
|
|
|
type_ptr return_type = mgr.new_type(); |
|
|
|
|
type_ptr arrow_one = type_ptr(new type_arr(rtype, return_type)); |
|
|
|
|
type_ptr arrow_two = type_ptr(new type_arr(ltype, arrow_one)); |
|
|
|
|
// For better type errors, we first require binary function,
|
|
|
|
|
// and only then unify each argument. This way, we can
|
|
|
|
|
// precisely point out which argument is "wrong".
|
|
|
|
|
|
|
|
|
|
mgr.unify(arrow_two, ftype); |
|
|
|
|
type_ptr return_type = mgr.new_type(); |
|
|
|
|
type_ptr second_type = mgr.new_type(); |
|
|
|
|
type_ptr first_type = mgr.new_type(); |
|
|
|
|
type_ptr arrow_one = type_ptr(new type_arr(second_type, return_type)); |
|
|
|
|
type_ptr arrow_two = type_ptr(new type_arr(first_type, arrow_one)); |
|
|
|
|
|
|
|
|
|
mgr.unify(ftype, arrow_two, loc); |
|
|
|
|
mgr.unify(first_type, ltype, left->loc); |
|
|
|
|
mgr.unify(second_type, rtype, right->loc); |
|
|
|
|
return return_type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -140,7 +148,7 @@ type_ptr ast_app::typecheck(type_mgr& mgr, type_env_ptr& env) { |
|
|
|
|
|
|
|
|
|
type_ptr return_type = mgr.new_type(); |
|
|
|
|
type_ptr arrow = type_ptr(new type_arr(rtype, return_type)); |
|
|
|
|
mgr.unify(arrow, ltype); |
|
|
|
|
mgr.unify(arrow, ltype, left->loc); |
|
|
|
|
return return_type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -190,7 +198,7 @@ type_ptr ast_case::typecheck(type_mgr& mgr, type_env_ptr& env) { |
|
|
|
|
type_env_ptr new_env = type_scope(env); |
|
|
|
|
branch->pat->typecheck(case_type, mgr, new_env); |
|
|
|
|
type_ptr curr_branch_type = branch->expr->typecheck(mgr, new_env); |
|
|
|
|
mgr.unify(branch_type, curr_branch_type); |
|
|
|
|
mgr.unify(curr_branch_type, branch_type, branch->expr->loc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
input_type = mgr.resolve(case_type, var); |
|
|
|
@ -361,7 +369,7 @@ type_ptr ast_lambda::typecheck(type_mgr& mgr, type_env_ptr& env) { |
|
|
|
|
full_type = type_ptr(new type_arr(std::move(param_type), full_type)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
mgr.unify(return_type, body->typecheck(mgr, var_env)); |
|
|
|
|
mgr.unify(return_type, body->typecheck(mgr, var_env), body->loc); |
|
|
|
|
return full_type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -433,5 +441,5 @@ void pattern_constr::typecheck(type_ptr t, type_mgr& mgr, type_env_ptr& env) con |
|
|
|
|
constructor_type = arr->right; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
mgr.unify(t, constructor_type); |
|
|
|
|
mgr.unify(constructor_type, t, loc); |
|
|
|
|
} |
|
|
|
|