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.

160 lines
5.4 KiB

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