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.

144 lines
4.5 KiB

1 year ago
  1. #pragma once
  2. #include <string>
  3. #include <set>
  4. #include <vector>
  5. #include <memory>
  6. #include <optional>
  7. #include <charconv>
  8. #include <concepts>
  9. #include "molasses/lexer.h"
  10. namespace molasses {
  11. struct type {
  12. [[nodiscard]] virtual std::string name() const = 0;
  13. [[nodiscard]] virtual size_t byte_size() const = 0;
  14. };
  15. inline auto operator<=>(const type& lhs, const type& rhs) {
  16. return lhs.name() <=> rhs.name();
  17. }
  18. struct primitive_type : public type {
  19. std::string _name;
  20. size_t _byte_size;
  21. primitive_type(std::string name, size_t byte_size)
  22. : _name(std::forward<std::string>(name))
  23. , _byte_size(byte_size)
  24. {}
  25. [[nodiscard]] std::string name() const final {
  26. return _name;
  27. }
  28. [[nodiscard]] size_t byte_size() const final {
  29. return _byte_size;
  30. };
  31. };
  32. struct parser_context;
  33. struct operation {
  34. [[nodiscard]] virtual std::string name() const = 0;
  35. [[nodiscard]] virtual std::vector<std::string> argument_types() const = 0;
  36. [[nodiscard]] virtual std::vector<std::string> return_types() const = 0;
  37. [[nodiscard]] virtual std::vector<std::string> generate(const parser_context&) const = 0;
  38. // Add generate() -> instruction[]
  39. };
  40. struct primitive_operation : public operation {
  41. std::string _name;
  42. std::vector<std::string> _args;
  43. std::vector<std::string> _rets;
  44. std::vector<std::string> _instructions;
  45. primitive_operation(std::string name, std::vector<std::string> args, std::vector<std::string> rets)
  46. : _name(std::forward<std::string>(name))
  47. , _args(std::forward<std::vector<std::string>>(args))
  48. , _rets(std::forward<std::vector<std::string>>(rets))
  49. {}
  50. [[nodiscard]] std::string name() const final {
  51. return _name;
  52. }
  53. [[nodiscard]] std::vector<std::string> argument_types() const final {
  54. return _args;
  55. }
  56. [[nodiscard]] std::vector<std::string> return_types() const final {
  57. return _rets;
  58. }
  59. [[nodiscard]] std::vector<std::string> generate(const parser_context&) const final {
  60. return _instructions;
  61. }
  62. };
  63. struct procedure_operation : public operation {
  64. std::string _name;
  65. std::vector<std::string> _args;
  66. std::vector<std::string> _rets;
  67. std::vector<symbol> _body;
  68. procedure_operation(std::string name, std::vector<std::string> args, std::vector<std::string> rets, std::vector<symbol> body)
  69. : _name(std::forward<std::string>(name))
  70. , _args(std::forward<std::vector<std::string>>(args))
  71. , _rets(std::forward<std::vector<std::string>>(rets))
  72. , _body(std::forward<std::vector<symbol>>(body))
  73. {}
  74. [[nodiscard]] std::string name() const final {
  75. return _name;
  76. }
  77. [[nodiscard]] std::vector<std::string> argument_types() const final {
  78. return _args;
  79. }
  80. [[nodiscard]] std::vector<std::string> return_types() const final {
  81. return _rets;
  82. }
  83. [[nodiscard]] std::vector<std::string> generate(const parser_context&) const final;
  84. };
  85. inline auto operator<=>(const operation& lhs, const operation& rhs) {
  86. return lhs.name() <=> rhs.name();
  87. }
  88. struct TypeInputError : std::runtime_error {
  89. TypeInputError() : std::runtime_error("Bad type provided") {}
  90. // TODO: Better error message
  91. };
  92. struct ValueMissingError : std::runtime_error {
  93. ValueMissingError() : std::runtime_error("Expected value, none provided") {}
  94. // TODO: Better error message
  95. };
  96. struct ProcedureStackError : std::runtime_error {
  97. ProcedureStackError() : std::runtime_error("Expected the stack to look like the return stack upon completion") {}
  98. // TODO: Better error message
  99. };
  100. struct UnexpectedTokenError : std::runtime_error {
  101. UnexpectedTokenError() : std::runtime_error("An unexpected token has been encountered") {}
  102. // TODO: Better error message
  103. };
  104. struct ExpectingTokenError : std::runtime_error {
  105. ExpectingTokenError() : std::runtime_error("An expected token has not been encountered before the end of the input") {}
  106. // TODO: Better error message
  107. };
  108. std::vector<std::string> operator>>(std::vector<std::string> current_stack, const operation& next_op);
  109. std::optional<int32_t> try_parse_int32(const std::string& str);
  110. struct parser_context {
  111. std::vector<std::shared_ptr<type>> types;
  112. std::vector<std::shared_ptr<operation>> operations;
  113. [[nodiscard]] std::shared_ptr<type> lookup_type(const std::string&) const;
  114. [[nodiscard]] std::shared_ptr<operation> lookup_operation(const std::string&) const;
  115. };
  116. parser_context parse(parser_context, const lexed_output&);
  117. parser_context register_integers(parser_context);
  118. bool type_check(const parser_context&, const lexed_output&, const std::vector<symbol>&, std::vector<std::string> execution_input, const std::vector<std::string>& execution_output);
  119. }