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.

ast.hpp 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #pragma once
  2. #include <memory>
  3. #include <vector>
  4. #include <set>
  5. #include "type.hpp"
  6. #include "type_env.hpp"
  7. #include "binop.hpp"
  8. #include "instruction.hpp"
  9. #include "env.hpp"
  10. #include "definition.hpp"
  11. #include "location.hh"
  12. #include "global_scope.hpp"
  13. struct ast {
  14. type_env_ptr env;
  15. yy::location loc;
  16. ast(yy::location l) : env(nullptr), loc(std::move(l)) {}
  17. virtual ~ast() = default;
  18. virtual void print(int indent, std::ostream& to) const = 0;
  19. virtual void find_free(std::set<std::string>& into) = 0;
  20. virtual type_ptr typecheck(type_mgr& mgr, type_env_ptr& env) = 0;
  21. virtual void translate(global_scope& scope) = 0;
  22. virtual void compile(const env_ptr& env,
  23. std::vector<instruction_ptr>& into) const = 0;
  24. };
  25. using ast_ptr = std::unique_ptr<ast>;
  26. struct pattern {
  27. yy::location loc;
  28. pattern(yy::location l) : loc(std::move(l)) {}
  29. virtual ~pattern() = default;
  30. virtual void print(std::ostream& to) const = 0;
  31. virtual void find_variables(std::set<std::string>& into) const = 0;
  32. virtual void typecheck(type_ptr t, type_mgr& mgr, type_env_ptr& env) const = 0;
  33. };
  34. using pattern_ptr = std::unique_ptr<pattern>;
  35. struct branch {
  36. pattern_ptr pat;
  37. ast_ptr expr;
  38. branch(pattern_ptr p, ast_ptr a)
  39. : pat(std::move(p)), expr(std::move(a)) {}
  40. };
  41. using branch_ptr = std::unique_ptr<branch>;
  42. struct ast_int : public ast {
  43. int value;
  44. explicit ast_int(int v, yy::location l = yy::location())
  45. : ast(std::move(l)), value(v) {}
  46. void print(int indent, std::ostream& to) const;
  47. void find_free(std::set<std::string>& into);
  48. type_ptr typecheck(type_mgr& mgr, type_env_ptr& env);
  49. void translate(global_scope& scope);
  50. void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const;
  51. };
  52. struct ast_lid : public ast {
  53. std::string id;
  54. explicit ast_lid(std::string i, yy::location l = yy::location())
  55. : ast(std::move(l)), id(std::move(i)) {}
  56. void print(int indent, std::ostream& to) const;
  57. void find_free(std::set<std::string>& into);
  58. type_ptr typecheck(type_mgr& mgr, type_env_ptr& env);
  59. void translate(global_scope& scope);
  60. void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const;
  61. };
  62. struct ast_uid : public ast {
  63. std::string id;
  64. explicit ast_uid(std::string i, yy::location l = yy::location())
  65. : ast(std::move(l)), id(std::move(i)) {}
  66. void print(int indent, std::ostream& to) const;
  67. void find_free(std::set<std::string>& into);
  68. type_ptr typecheck(type_mgr& mgr, type_env_ptr& env);
  69. void translate(global_scope& scope);
  70. void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const;
  71. };
  72. struct ast_binop : public ast {
  73. binop op;
  74. ast_ptr left;
  75. ast_ptr right;
  76. ast_binop(binop o, ast_ptr l, ast_ptr r, yy::location lc = yy::location())
  77. : ast(std::move(lc)), op(o), left(std::move(l)), right(std::move(r)) {}
  78. void print(int indent, std::ostream& to) const;
  79. void find_free(std::set<std::string>& into);
  80. type_ptr typecheck(type_mgr& mgr, type_env_ptr& env);
  81. void translate(global_scope& scope);
  82. void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const;
  83. };
  84. struct ast_app : public ast {
  85. ast_ptr left;
  86. ast_ptr right;
  87. ast_app(ast_ptr l, ast_ptr r, yy::location lc = yy::location())
  88. : ast(std::move(lc)), left(std::move(l)), right(std::move(r)) {}
  89. void print(int indent, std::ostream& to) const;
  90. void find_free(std::set<std::string>& into);
  91. type_ptr typecheck(type_mgr& mgr, type_env_ptr& env);
  92. void translate(global_scope& scope);
  93. void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const;
  94. };
  95. struct ast_case : public ast {
  96. ast_ptr of;
  97. type_ptr input_type;
  98. std::vector<branch_ptr> branches;
  99. ast_case(ast_ptr o, std::vector<branch_ptr> b, yy::location l = yy::location())
  100. : ast(std::move(l)), of(std::move(o)), branches(std::move(b)) {}
  101. void print(int indent, std::ostream& to) const;
  102. void find_free(std::set<std::string>& into);
  103. type_ptr typecheck(type_mgr& mgr, type_env_ptr& env);
  104. void translate(global_scope& scope);
  105. void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const;
  106. };
  107. struct ast_let : public ast {
  108. using basic_definition = std::pair<std::string, ast_ptr>;
  109. definition_group definitions;
  110. ast_ptr in;
  111. std::vector<basic_definition> translated_definitions;
  112. ast_let(definition_group g, ast_ptr i, yy::location l = yy::location())
  113. : ast(std::move(l)), definitions(std::move(g)), in(std::move(i)) {}
  114. void print(int indent, std::ostream& to) const;
  115. void find_free(std::set<std::string>& into);
  116. type_ptr typecheck(type_mgr& mgr, type_env_ptr& env);
  117. void translate(global_scope& scope);
  118. void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const;
  119. };
  120. struct ast_lambda : public ast {
  121. std::vector<std::string> params;
  122. ast_ptr body;
  123. type_env_ptr var_env;
  124. std::set<std::string> free_variables;
  125. ast_ptr translated;
  126. ast_lambda(std::vector<std::string> ps, ast_ptr b, yy::location l = yy::location())
  127. : ast(std::move(l)), params(std::move(ps)), body(std::move(b)) {}
  128. void print(int indent, std::ostream& to) const;
  129. void find_free(std::set<std::string>& into);
  130. type_ptr typecheck(type_mgr& mgr, type_env_ptr& env);
  131. void translate(global_scope& scope);
  132. void compile(const env_ptr& env, std::vector<instruction_ptr>& into) const;
  133. };
  134. struct pattern_var : public pattern {
  135. std::string var;
  136. pattern_var(std::string v, yy::location l = yy::location())
  137. : pattern(std::move(l)), var(std::move(v)) {}
  138. void print(std::ostream &to) const;
  139. void find_variables(std::set<std::string>& into) const;
  140. void typecheck(type_ptr t, type_mgr& mgr, type_env_ptr& env) const;
  141. };
  142. struct pattern_constr : public pattern {
  143. std::string constr;
  144. std::vector<std::string> params;
  145. pattern_constr(std::string c, std::vector<std::string> p, yy::location l = yy::location())
  146. : pattern(std::move(l)), constr(std::move(c)), params(std::move(p)) {}
  147. void print(std::ostream &to) const;
  148. void find_variables(std::set<std::string>& into) const;
  149. virtual void typecheck(type_ptr t, type_mgr& mgr, type_env_ptr& env) const;
  150. };