diff --git a/code/compiler/12/definition.cpp b/code/compiler/12/definition.cpp index 551cf03..6d92133 100644 --- a/code/compiler/12/definition.cpp +++ b/code/compiler/12/definition.cpp @@ -26,8 +26,8 @@ void definition_defn::find_free(type_mgr& mgr, type_env_ptr& env) { body->find_free(mgr, var_env, free_variables); } -void definition_defn::insert_types(type_mgr& mgr) { - env->bind(name, full_type); +void definition_defn::insert_types(type_mgr& mgr, visibility v) { + env->bind(name, full_type, v); } void definition_defn::typecheck(type_mgr& mgr) { @@ -150,7 +150,7 @@ void definition_group::typecheck(type_mgr& mgr) { auto& group = *it; for(auto& def_defnn_name : group->members) { auto& def_defn = defs_defn.find(def_defnn_name)->second; - def_defn->insert_types(mgr); + def_defn->insert_types(mgr, vis); } for(auto& def_defnn_name : group->members) { auto& def_defn = defs_defn.find(def_defnn_name)->second; diff --git a/code/compiler/12/definition.hpp b/code/compiler/12/definition.hpp index a2309b5..ce86bb3 100644 --- a/code/compiler/12/definition.hpp +++ b/code/compiler/12/definition.hpp @@ -44,7 +44,7 @@ struct definition_defn { } void find_free(type_mgr& mgr, type_env_ptr& env); - void insert_types(type_mgr& mgr); + void insert_types(type_mgr& mgr, visibility v); void typecheck(type_mgr& mgr); void compile(); void declare_llvm(llvm_context& ctx); @@ -76,9 +76,11 @@ using definition_data_ptr = std::unique_ptr; struct definition_group { std::map defs_data; std::map defs_defn; - + visibility vis; type_env_ptr env; + definition_group(visibility v = visibility::local) : vis(v) {} + void find_free(type_mgr& mgr, type_env_ptr& env, std::set& into); void typecheck(type_mgr& mgr); }; diff --git a/code/compiler/12/main.cpp b/code/compiler/12/main.cpp index 2ec963c..c7d7234 100644 --- a/code/compiler/12/main.cpp +++ b/code/compiler/12/main.cpp @@ -33,10 +33,10 @@ void typecheck_program( type_ptr binop_type = type_ptr(new type_arr( int_type_app, type_ptr(new type_arr(int_type_app, int_type_app)))); - env->bind("+", binop_type); - env->bind("-", binop_type); - env->bind("*", binop_type); - env->bind("/", binop_type); + env->bind("+", binop_type, visibility::global); + env->bind("-", binop_type, visibility::global); + env->bind("*", binop_type, visibility::global); + env->bind("/", binop_type, visibility::global); std::set free; defs.find_free(mgr, env, free); @@ -44,7 +44,7 @@ void typecheck_program( for(auto& pair : defs.env->names) { std::cout << pair.first << ": "; - pair.second->print(mgr, std::cout); + pair.second.type->print(mgr, std::cout); std::cout << std::endl; } } diff --git a/code/compiler/12/parser.y b/code/compiler/12/parser.y index bae7ad0..883879c 100644 --- a/code/compiler/12/parser.y +++ b/code/compiler/12/parser.y @@ -7,7 +7,7 @@ #include "parser.hpp" #include "parsed_type.hpp" -definition_group global_defs; +definition_group global_defs(visibility::global); extern yy::parser::symbol_type yylex(); diff --git a/code/compiler/12/type_env.cpp b/code/compiler/12/type_env.cpp index 26a5a84..e0fd33f 100644 --- a/code/compiler/12/type_env.cpp +++ b/code/compiler/12/type_env.cpp @@ -4,7 +4,7 @@ void type_env::find_free(const type_mgr& mgr, std::set& into) const { if(parent != nullptr) parent->find_free(mgr, into); for(auto& binding : names) { - mgr.find_free(binding.second, into); + mgr.find_free(binding.second.type, into); } } @@ -13,13 +13,13 @@ void type_env::find_free_except(const type_mgr& mgr, const std::string& avoid, if(parent != nullptr) parent->find_free(mgr, into); for(auto& binding : names) { if(binding.first == avoid) continue; - mgr.find_free(binding.second, into); + mgr.find_free(binding.second.type, into); } } type_scheme_ptr type_env::lookup(const std::string& name) const { auto it = names.find(name); - if(it != names.end()) return it->second; + if(it != names.end()) return it->second.type; if(parent) return parent->lookup(name); return nullptr; } @@ -31,12 +31,13 @@ type_ptr type_env::lookup_type(const std::string& name) const { return nullptr; } -void type_env::bind(const std::string& name, type_ptr t) { - names[name] = type_scheme_ptr(new type_scheme(t)); +void type_env::bind(const std::string& name, type_ptr t, visibility v) { + type_scheme_ptr new_scheme(new type_scheme(std::move(t))); + names[name] = variable_data(std::move(new_scheme), v); } -void type_env::bind(const std::string& name, type_scheme_ptr t) { - names[name] = t; +void type_env::bind(const std::string& name, type_scheme_ptr t, visibility v) { + names[name] = variable_data(std::move(t), v); } void type_env::bind_type(const std::string& type_name, type_ptr t) { @@ -47,15 +48,15 @@ void type_env::bind_type(const std::string& type_name, type_ptr t) { void type_env::generalize(const std::string& name, type_mgr& mgr) { auto names_it = names.find(name); if(names_it == names.end()) throw 0; - if(names_it->second->forall.size() > 0) throw 0; + if(names_it->second.type->forall.size() > 0) throw 0; std::set free_in_type; std::set free_in_env; - mgr.find_free(names_it->second->monotype, free_in_type); + mgr.find_free(names_it->second.type->monotype, free_in_type); find_free_except(mgr, name, free_in_env); for(auto& free : free_in_type) { if(free_in_env.find(free) != free_in_env.end()) continue; - names_it->second->forall.push_back(free); + names_it->second.type->forall.push_back(free); } } diff --git a/code/compiler/12/type_env.hpp b/code/compiler/12/type_env.hpp index 9b529d2..f61a674 100644 --- a/code/compiler/12/type_env.hpp +++ b/code/compiler/12/type_env.hpp @@ -7,9 +7,21 @@ struct type_env; using type_env_ptr = std::shared_ptr; +enum class visibility { global,local }; + struct type_env { + struct variable_data { + type_scheme_ptr type; + visibility vis; + + variable_data() + : variable_data(nullptr, visibility::local) {} + variable_data(type_scheme_ptr t, visibility v) + : type(std::move(t)), vis(v) {} + }; + type_env_ptr parent; - std::map names; + std::map names; std::map type_names; type_env(type_env_ptr p) : parent(std::move(p)) {} @@ -20,8 +32,10 @@ struct type_env { std::set& into) const; type_scheme_ptr lookup(const std::string& name) const; type_ptr lookup_type(const std::string& name) const; - void bind(const std::string& name, type_ptr t); - void bind(const std::string& name, type_scheme_ptr t); + void bind(const std::string& name, type_ptr t, + visibility v = visibility::local); + void bind(const std::string& name, type_scheme_ptr t, + visibility v = visibility::local); void bind_type(const std::string& type_name, type_ptr t); void generalize(const std::string& name, type_mgr& mgr); };