A Hugo incarnation of the blog.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

definition.cpp 4.8KB

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