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 5.5KB

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