Mark some definitions as global, so as not to capture them.
This commit is contained in:
		
							parent
							
								
									a1d679a59d
								
							
						
					
					
						commit
						08503116ff
					
				@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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<definition_data>;
 | 
			
		||||
struct definition_group {
 | 
			
		||||
    std::map<std::string, definition_data_ptr> defs_data;
 | 
			
		||||
    std::map<std::string, definition_defn_ptr> 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<std::string>& into);
 | 
			
		||||
    void typecheck(type_mgr& mgr);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -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<std::string> 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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
void type_env::find_free(const type_mgr& mgr, std::set<std::string>& 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<std::string> free_in_type;
 | 
			
		||||
    std::set<std::string> 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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -7,9 +7,21 @@
 | 
			
		||||
struct type_env;
 | 
			
		||||
using type_env_ptr = std::shared_ptr<type_env>;
 | 
			
		||||
 | 
			
		||||
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<std::string, type_scheme_ptr> names;
 | 
			
		||||
    std::map<std::string, variable_data> names;
 | 
			
		||||
    std::map<std::string, type_ptr> type_names;
 | 
			
		||||
 | 
			
		||||
    type_env(type_env_ptr p) : parent(std::move(p)) {}
 | 
			
		||||
@ -20,8 +32,10 @@ struct type_env {
 | 
			
		||||
            std::set<std::string>& 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);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user