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.hpp 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #pragma once
  2. #include <memory>
  3. #include <map>
  4. #include <string>
  5. #include <vector>
  6. #include <set>
  7. #include <optional>
  8. #include "location.hh"
  9. class type_mgr;
  10. struct type {
  11. virtual ~type() = default;
  12. virtual void print(const type_mgr& mgr, std::ostream& to) const = 0;
  13. };
  14. using type_ptr = std::shared_ptr<type>;
  15. struct type_scheme {
  16. std::vector<std::string> forall;
  17. type_ptr monotype;
  18. type_scheme(type_ptr type) : forall(), monotype(std::move(type)) {}
  19. void print(const type_mgr& mgr, std::ostream& to) const;
  20. type_ptr instantiate(type_mgr& mgr) const;
  21. };
  22. using type_scheme_ptr = std::shared_ptr<type_scheme>;
  23. struct type_var : public type {
  24. std::string name;
  25. type_var(std::string n)
  26. : name(std::move(n)) {}
  27. void print(const type_mgr& mgr, std::ostream& to) const;
  28. };
  29. struct type_base : public type {
  30. std::string name;
  31. int32_t arity;
  32. type_base(std::string n, int32_t a = 0)
  33. : name(std::move(n)), arity(a) {}
  34. void print(const type_mgr& mgr, std::ostream& to) const;
  35. };
  36. struct type_data : public type_base {
  37. struct constructor {
  38. int tag;
  39. };
  40. std::map<std::string, constructor> constructors;
  41. type_data(std::string n, int32_t a = 0)
  42. : type_base(std::move(n), a) {}
  43. };
  44. struct type_arr : public type {
  45. type_ptr left;
  46. type_ptr right;
  47. type_arr(type_ptr l, type_ptr r)
  48. : left(std::move(l)), right(std::move(r)) {}
  49. void print(const type_mgr& mgr, std::ostream& to) const;
  50. };
  51. struct type_app : public type {
  52. type_ptr constructor;
  53. std::vector<type_ptr> arguments;
  54. type_app(type_ptr c)
  55. : constructor(std::move(c)) {}
  56. void print(const type_mgr& mgr, std::ostream& to) const;
  57. };
  58. class type_mgr {
  59. private:
  60. int last_id = 0;
  61. std::map<std::string, type_ptr> types;
  62. public:
  63. std::string new_type_name();
  64. type_ptr new_type();
  65. type_ptr new_arrow_type();
  66. void unify(type_ptr l, type_ptr r, const std::optional<yy::location>& loc = std::nullopt);
  67. type_ptr substitute(
  68. const std::map<std::string, type_ptr>& subst,
  69. const type_ptr& t) const;
  70. type_ptr lookup(const std::string& var) const;
  71. type_ptr resolve(type_ptr t, type_var*& var) const;
  72. void bind(const std::string& s, type_ptr t);
  73. void find_free(const type_ptr& t, std::set<std::string>& into) const;
  74. void find_free(const type_scheme_ptr& t, std::set<std::string>& into) const;
  75. };