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.

179 lines
6.2 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 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_linux,
  12. x86_linux
  13. };
  14. #if defined(__x86_64__) && __linux__
  15. constexpr architecture_t architecture = architecture_t::x86_64_linux;
  16. constexpr size_t architecture_ptr_size = 8;
  17. #elif defined(__i386) || defined(__i386__) || defined(i386) && __linux__
  18. constexpr architecture_t architecture = architecture_t::x86_linux;
  19. constexpr size_t architecture_ptr_size = 4;
  20. #endif
  21. namespace molasses {
  22. struct type {
  23. [[nodiscard]] virtual std::string name() const = 0;
  24. [[nodiscard]] virtual size_t byte_size() const = 0;
  25. };
  26. inline auto operator<=>(const type& lhs, const type& rhs) {
  27. return lhs.name() <=> rhs.name();
  28. }
  29. struct primitive_type : public type {
  30. std::string _name;
  31. size_t _byte_size;
  32. primitive_type(std::string name, size_t byte_size)
  33. : _name(std::forward<std::string>(name))
  34. , _byte_size(byte_size)
  35. {}
  36. [[nodiscard]] std::string name() const final {
  37. return _name;
  38. }
  39. [[nodiscard]] size_t byte_size() const final {
  40. return _byte_size;
  41. };
  42. };
  43. struct parser_context;
  44. struct operation {
  45. [[nodiscard]] virtual std::string name() const = 0;
  46. [[nodiscard]] virtual std::vector<std::string> argument_types() const = 0;
  47. [[nodiscard]] virtual std::vector<std::string> return_types() const = 0;
  48. [[nodiscard]] virtual std::vector<std::string> generate(const parser_context&, const lexed_output& lexer_data) const = 0;
  49. [[nodiscard]] virtual std::vector<std::string> emit(const parser_context&) const = 0;
  50. };
  51. struct primitive_operation : public operation {
  52. std::string _name;
  53. std::vector<std::string> _args;
  54. std::vector<std::string> _rets;
  55. std::vector<std::string> _instructions;
  56. primitive_operation(std::string name, std::vector<std::string> args, std::vector<std::string> rets, std::vector<std::string> body)
  57. : _name(std::forward<std::string>(name))
  58. , _args(std::forward<std::vector<std::string>>(args))
  59. , _rets(std::forward<std::vector<std::string>>(rets))
  60. , _instructions(std::forward<std::vector<std::string>>(body))
  61. {}
  62. [[nodiscard]] std::string name() const final {
  63. return _name;
  64. }
  65. [[nodiscard]] std::vector<std::string> argument_types() const final {
  66. return _args;
  67. }
  68. [[nodiscard]] std::vector<std::string> return_types() const final {
  69. return _rets;
  70. }
  71. [[nodiscard]] std::vector<std::string> generate(const parser_context&, const lexed_output& lexer_data) const final {
  72. return {};
  73. }
  74. [[nodiscard]] std::vector<std::string> emit(const parser_context&) const final {
  75. return _instructions;
  76. }
  77. };
  78. struct procedure_operation : public operation {
  79. std::string _name;
  80. std::vector<std::string> _args;
  81. std::vector<std::string> _rets;
  82. std::vector<symbol> _body;
  83. procedure_operation(std::string name, std::vector<std::string> args, std::vector<std::string> rets, std::vector<symbol> body)
  84. : _name(std::forward<std::string>(name))
  85. , _args(std::forward<std::vector<std::string>>(args))
  86. , _rets(std::forward<std::vector<std::string>>(rets))
  87. , _body(std::forward<std::vector<symbol>>(body))
  88. {}
  89. [[nodiscard]] std::string name() const final {
  90. return _name;
  91. }
  92. [[nodiscard]] std::vector<std::string> argument_types() const final {
  93. return _args;
  94. }
  95. [[nodiscard]] std::vector<std::string> return_types() const final {
  96. return _rets;
  97. }
  98. [[nodiscard]] std::vector<std::string> generate(const parser_context&, const lexed_output& lexer_data) const final;
  99. [[nodiscard]] std::vector<std::string> emit(const parser_context&) const final;
  100. };
  101. inline auto operator<=>(const operation& lhs, const operation& rhs) {
  102. return lhs.name() <=> rhs.name();
  103. }
  104. struct type_input_error : std::runtime_error {
  105. type_input_error() : std::runtime_error("Bad type provided") {}
  106. // TODO: Better error message
  107. };
  108. struct value_missing_error : std::runtime_error {
  109. value_missing_error() : std::runtime_error("Expected value, none provided") {}
  110. // TODO: Better error message
  111. };
  112. struct procedure_stack_error : std::runtime_error {
  113. procedure_stack_error() : std::runtime_error("Expected the stack to look like the return stack upon completion") {}
  114. // TODO: Better error message
  115. };
  116. struct unexpected_token_error : std::runtime_error {
  117. unexpected_token_error() : std::runtime_error("An unexpected token has been encountered") {}
  118. // TODO: Better error message
  119. };
  120. struct expecting_token_error : std::runtime_error {
  121. expecting_token_error() : std::runtime_error("An expected token has not been encountered before the end of the input") {}
  122. // TODO: Better error message
  123. };
  124. struct unknown_token_error : std::runtime_error {
  125. unknown_token_error() : std::runtime_error("An unknown token has not been encountered") {}
  126. // TODO: Better error message
  127. };
  128. struct type_expected_with_modifier_error : std::runtime_error {
  129. type_expected_with_modifier_error() : std::runtime_error("A type is expected before a modifier") {}
  130. // TODO: Better error message
  131. };
  132. std::vector<std::string> operator>>(std::vector<std::string> current_stack, const operation& next_op);
  133. std::optional<int32_t> try_parse_int32(const std::string& str);
  134. struct parser_context {
  135. std::vector<std::shared_ptr<type>> types;
  136. std::vector<std::shared_ptr<operation>> operations;
  137. std::vector<std::shared_ptr<procedure_operation>> procedures;
  138. [[nodiscard]] std::shared_ptr<type> lookup_type(const std::string&) const;
  139. [[nodiscard]] std::shared_ptr<operation> lookup_operation(const std::string&) const;
  140. };
  141. struct generate_context {
  142. lexed_output lexer;
  143. parser_context parser;
  144. std::vector<std::shared_ptr<procedure_operation>> procedures;
  145. };
  146. generate_context parse(parser_context, const lexed_output&);
  147. std::vector<std::string> generate(generate_context);
  148. parser_context register_integers(parser_context);
  149. parser_context register_i32_operations(parser_context);
  150. 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);
  151. }