A Hugo incarnation of the blog.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

type_env.cpp 2.9KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #include "type_env.hpp"
  2. #include "type.hpp"
  3. void type_env::find_free(const type_mgr& mgr, std::set<std::string>& into) const {
  4. if(parent != nullptr) parent->find_free(mgr, into);
  5. for(auto& binding : names) {
  6. mgr.find_free(binding.second.type, into);
  7. }
  8. }
  9. void type_env::find_free_except(const type_mgr& mgr, const group& avoid,
  10. std::set<std::string>& into) const {
  11. if(parent != nullptr) parent->find_free(mgr, into);
  12. for(auto& binding : names) {
  13. if(avoid.members.find(binding.first) != avoid.members.end()) continue;
  14. mgr.find_free(binding.second.type, into);
  15. }
  16. }
  17. type_scheme_ptr type_env::lookup(const std::string& name) const {
  18. auto it = names.find(name);
  19. if(it != names.end()) return it->second.type;
  20. if(parent) return parent->lookup(name);
  21. return nullptr;
  22. }
  23. bool type_env::is_global(const std::string& name) const {
  24. auto it = names.find(name);
  25. if(it != names.end()) return it->second.vis == visibility::global;
  26. if(parent) return parent->is_global(name);
  27. return false;
  28. }
  29. void type_env::set_mangled_name(const std::string& name, const std::string& mangled) {
  30. auto it = names.find(name);
  31. if(it != names.end()) it->second.mangled_name = mangled;
  32. }
  33. const std::string& type_env::get_mangled_name(const std::string& name) const {
  34. auto it = names.find(name);
  35. if(it != names.end())
  36. return (it->second.mangled_name != "") ? it->second.mangled_name : name;
  37. if(parent) return parent->get_mangled_name(name);
  38. return name;
  39. }
  40. type_ptr type_env::lookup_type(const std::string& name) const {
  41. auto it = type_names.find(name);
  42. if(it != type_names.end()) return it->second;
  43. if(parent) return parent->lookup_type(name);
  44. return nullptr;
  45. }
  46. void type_env::bind(const std::string& name, type_ptr t, visibility v) {
  47. type_scheme_ptr new_scheme(new type_scheme(std::move(t)));
  48. names[name] = variable_data(std::move(new_scheme), v, "");
  49. }
  50. void type_env::bind(const std::string& name, type_scheme_ptr t, visibility v) {
  51. names[name] = variable_data(std::move(t), v, "");
  52. }
  53. void type_env::bind_type(const std::string& type_name, type_ptr t) {
  54. if(lookup_type(type_name) != nullptr) throw 0;
  55. type_names[type_name] = t;
  56. }
  57. void type_env::generalize(const std::string& name, const group& grp, type_mgr& mgr) {
  58. auto names_it = names.find(name);
  59. if(names_it == names.end()) throw 0;
  60. if(names_it->second.type->forall.size() > 0) throw 0;
  61. std::set<std::string> free_in_type;
  62. std::set<std::string> free_in_env;
  63. mgr.find_free(names_it->second.type->monotype, free_in_type);
  64. find_free_except(mgr, grp, free_in_env);
  65. for(auto& free : free_in_type) {
  66. if(free_in_env.find(free) != free_in_env.end()) continue;
  67. names_it->second.type->forall.push_back(free);
  68. }
  69. }
  70. type_env_ptr type_scope(type_env_ptr parent) {
  71. return type_env_ptr(new type_env(std::move(parent)));
  72. }