diff --git a/code/compiler/06/ast.hpp b/code/compiler/06/ast.hpp index 3f35db3..21e1f61 100644 --- a/code/compiler/06/ast.hpp +++ b/code/compiler/06/ast.hpp @@ -58,7 +58,7 @@ struct definition { virtual void typecheck_first(type_mgr& mgr, type_env& env) = 0; virtual void typecheck_second(type_mgr& mgr, const type_env& env) const = 0; - virtual void resolve(const type_mgr& mgr) const = 0; + virtual void resolve(const type_mgr& mgr) = 0; }; using definition_ptr = std::unique_ptr; @@ -175,7 +175,7 @@ struct definition_defn : public definition { void typecheck_first(type_mgr& mgr, type_env& env); void typecheck_second(type_mgr& mgr, const type_env& env) const; - void resolve(const type_mgr& mgr) const; + void resolve(const type_mgr& mgr); }; struct definition_data : public definition { @@ -187,5 +187,5 @@ struct definition_data : public definition { void typecheck_first(type_mgr& mgr, type_env& env); void typecheck_second(type_mgr& mgr, const type_env& env) const; - void resolve(const type_mgr& mgr) const; + void resolve(const type_mgr& mgr); }; diff --git a/code/compiler/06/definition.cpp b/code/compiler/06/definition.cpp index ff1ef23..5047055 100644 --- a/code/compiler/06/definition.cpp +++ b/code/compiler/06/definition.cpp @@ -1,4 +1,5 @@ #include "ast.hpp" +#include "error.hpp" void definition_defn::typecheck_first(type_mgr& mgr, type_env& env) { return_type = mgr.new_type(); @@ -28,8 +29,16 @@ void definition_defn::typecheck_second(type_mgr& mgr, const type_env& env) const mgr.unify(return_type, body_type); } -void definition_defn::resolve(const type_mgr& mgr) const { +void definition_defn::resolve(const type_mgr& mgr) { + type_var* var; body->resolve_common(mgr); + + return_type = mgr.resolve(return_type, var); + if(var) throw type_error("ambiguously typed program"); + for(auto& param_type : param_types) { + param_type = mgr.resolve(param_type, var); + if(var) throw type_error("ambiguously typed program"); + } } void definition_data::typecheck_first(type_mgr& mgr, type_env& env) { @@ -54,7 +63,7 @@ void definition_data::typecheck_second(type_mgr& mgr, const type_env& env) const // Nothing } -void definition_data::resolve(const type_mgr& mgr) const { +void definition_data::resolve(const type_mgr& mgr) { // Nothing }