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.

definition.cpp 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include "definition.hpp"
  2. #include <cassert>
  3. #include "error.hpp"
  4. #include "ast.hpp"
  5. #include "instruction.hpp"
  6. #include "llvm_context.hpp"
  7. #include "type.hpp"
  8. #include "type_env.hpp"
  9. #include "graph.hpp"
  10. #include <llvm/IR/DerivedTypes.h>
  11. #include <llvm/IR/Function.h>
  12. #include <llvm/IR/Type.h>
  13. void definition_defn::find_free() {
  14. body->find_free(free_variables);
  15. for(auto& param : params) {
  16. free_variables.erase(param);
  17. }
  18. }
  19. void definition_defn::insert_types(type_mgr& mgr, type_env_ptr& env, visibility v) {
  20. this->env = env;
  21. var_env = type_scope(env);
  22. return_type = mgr.new_type();
  23. full_type = return_type;
  24. for(auto it = params.rbegin(); it != params.rend(); it++) {
  25. type_ptr param_type = mgr.new_type();
  26. full_type = type_ptr(new type_arr(param_type, full_type));
  27. var_env->bind(*it, param_type);
  28. }
  29. env->bind(name, full_type, v);
  30. }
  31. void definition_defn::typecheck(type_mgr& mgr) {
  32. type_ptr body_type = body->typecheck(mgr, var_env);
  33. mgr.unify(return_type, body_type);
  34. }
  35. global_function& definition_defn::into_global(global_scope& scope) {
  36. std::vector<std::string> all_params;
  37. for(auto& free : free_variables) {
  38. if(env->is_global(free)) continue;
  39. all_params.push_back(free);
  40. }
  41. all_params.insert(all_params.end(), params.begin(), params.end());
  42. body->translate(scope);
  43. return scope.add_function(name, std::move(all_params), std::move(body));
  44. }
  45. void definition_data::insert_types(type_env_ptr& env) {
  46. this->env = env;
  47. env->bind_type(name, type_ptr(new type_data(name, vars.size())));
  48. }
  49. void definition_data::insert_constructors() const {
  50. type_ptr this_type_ptr = env->lookup_type(name);
  51. type_data* this_type = static_cast<type_data*>(this_type_ptr.get());
  52. int next_tag = 0;
  53. std::set<std::string> var_set;
  54. type_app* return_app = new type_app(std::move(this_type_ptr));
  55. type_ptr return_type(return_app);
  56. for(auto& var : vars) {
  57. if(var_set.find(var) != var_set.end())
  58. throw compiler_error(
  59. "type variable " + var +
  60. " used twice in data type definition.", loc);
  61. var_set.insert(var);
  62. return_app->arguments.push_back(type_ptr(new type_var(var)));
  63. }
  64. for(auto& constructor : constructors) {
  65. constructor->tag = next_tag;
  66. this_type->constructors[constructor->name] = { next_tag++ };
  67. type_ptr full_type = return_type;
  68. for(auto it = constructor->types.rbegin(); it != constructor->types.rend(); it++) {
  69. type_ptr type = (*it)->to_type(var_set, env);
  70. full_type = type_ptr(new type_arr(type, full_type));
  71. }
  72. type_scheme_ptr full_scheme(new type_scheme(std::move(full_type)));
  73. full_scheme->forall.insert(full_scheme->forall.begin(), vars.begin(), vars.end());
  74. env->bind(constructor->name, full_scheme, visibility::global);
  75. }
  76. }
  77. void definition_data::into_globals(global_scope& scope) {
  78. for(auto& constructor : constructors) {
  79. global_constructor& c = scope.add_constructor(
  80. constructor->name, constructor->tag, constructor->types.size());
  81. env->set_mangled_name(constructor->name, c.name);
  82. }
  83. }
  84. void definition_group::find_free(std::set<std::string>& into) {
  85. for(auto& def_pair : defs_defn) {
  86. def_pair.second->find_free();
  87. for(auto& free_var : def_pair.second->free_variables) {
  88. if(defs_defn.find(free_var) == defs_defn.end()) {
  89. into.insert(free_var);
  90. } else {
  91. def_pair.second->nearby_variables.insert(free_var);
  92. }
  93. }
  94. }
  95. }
  96. void definition_group::typecheck(type_mgr& mgr, type_env_ptr& env) {
  97. this->env = type_scope(env);
  98. for(auto& def_data : defs_data) {
  99. def_data.second->insert_types(this->env);
  100. }
  101. for(auto& def_data : defs_data) {
  102. def_data.second->insert_constructors();
  103. }
  104. function_graph dependency_graph;
  105. for(auto& def_defn : defs_defn) {
  106. def_defn.second->find_free();
  107. dependency_graph.add_function(def_defn.second->name);
  108. for(auto& dependency : def_defn.second->nearby_variables) {
  109. assert(defs_defn.find(dependency) != defs_defn.end());
  110. dependency_graph.add_edge(def_defn.second->name, dependency);
  111. }
  112. }
  113. std::vector<group_ptr> groups = dependency_graph.compute_order();
  114. for(auto it = groups.rbegin(); it != groups.rend(); it++) {
  115. auto& group = *it;
  116. for(auto& def_defnn_name : group->members) {
  117. auto& def_defn = defs_defn.find(def_defnn_name)->second;
  118. def_defn->insert_types(mgr, this->env, vis);
  119. }
  120. for(auto& def_defnn_name : group->members) {
  121. auto& def_defn = defs_defn.find(def_defnn_name)->second;
  122. def_defn->typecheck(mgr);
  123. }
  124. for(auto& def_defnn_name : group->members) {
  125. this->env->generalize(def_defnn_name, *group, mgr);
  126. }
  127. }
  128. }