#pragma once #include #include #include #include #include "graph.hpp" #include "type.hpp" struct type_env; using type_env_ptr = std::shared_ptr; enum class visibility { global,local }; class type_env { private: struct variable_data { type_scheme_ptr type; visibility vis; std::optional mangled_name; variable_data() : variable_data(nullptr, visibility::local, std::nullopt) {} variable_data(type_scheme_ptr t, visibility v, std::optional n) : type(std::move(t)), vis(v), mangled_name(std::move(n)) {} }; type_env_ptr parent; std::map names; std::map type_names; public: type_env(type_env_ptr p) : parent(std::move(p)) {} type_env() : type_env(nullptr) {} void find_free(const type_mgr& mgr, std::set& into) const; void find_free_except(const type_mgr& mgr, const group& avoid, std::set& into) const; type_scheme_ptr lookup(const std::string& name) const; bool is_global(const std::string& name) const; void set_mangled_name(const std::string& name, const std::string& mangled); const std::string& get_mangled_name(const std::string& name) const; type_ptr lookup_type(const std::string& name) const; 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, const group& grp, type_mgr& mgr); }; type_env_ptr type_scope(type_env_ptr parent);