Fix function return type checking.

This commit is contained in:
Danila Fedorin 2019-06-09 19:57:58 -07:00
parent 711c78e0f6
commit 0b544a2515
2 changed files with 7 additions and 1 deletions

View File

@ -8,6 +8,7 @@ int main() {
"data Bool = { True, False }\n" "data Bool = { True, False }\n"
"data Color = { Red, Black }\n" "data Color = { Red, Black }\n"
"data IntList = { Nil, Cons(Int, IntList) }\n" "data IntList = { Nil, Cons(Int, IntList) }\n"
"defn other x y = { 3 }\n"
"defn add x y = { x + add x x }"); "defn add x y = { x + add x x }");
} catch(lily::error& e) { } catch(lily::error& e) {
std::cout << e.message << std::endl; std::cout << e.message << std::endl;

View File

@ -248,6 +248,7 @@ namespace lily {
// Each function has an environment, which will be used // Each function has an environment, which will be used
// as base for type checking. // as base for type checking.
std::map<std::string, std::shared_ptr<type_env>> function_envs; std::map<std::string, std::shared_ptr<type_env>> function_envs;
std::map<std::string, type*> function_output_types;
auto base_env = std::make_shared<type_env>(); auto base_env = std::make_shared<type_env>();
// First step is to collect all function types. // First step is to collect all function types.
@ -261,6 +262,7 @@ namespace lily {
// Create the return type parameter // Create the return type parameter
type* return_type = type_mgr.create_type<type_parameter>(); type* return_type = type_mgr.create_type<type_parameter>();
type* current_type = return_type; type* current_type = return_type;
function_output_types[pair.first] = return_type;
// Create type parameters for every variable // Create type parameters for every variable
// We also want to place them in a local environment // We also want to place them in a local environment
@ -279,7 +281,10 @@ namespace lily {
// Now that we have collected the functions, check their bodies. // Now that we have collected the functions, check their bodies.
for(auto& pair : functions) { for(auto& pair : functions) {
pair.second.body->check(type_mgr, function_envs[pair.first]); type* body_type =
pair.second.body->check(type_mgr, function_envs[pair.first]);
if(!function_output_types[pair.first]->unify_with(body_type))
throw error("unable to unify function type");
} }
} }
} }