#pragma once #include #include #include #include #include namespace scripting { namespace ast { enum class operator_t : uint8_t { logical_not = 0b00000, binary_not = 0b00001, divide = 0b00010, modulo = 0b00100, multiply = 0b00101, subtract = 0b00110, add = 0b01000, bitshift_left = 0b01001, bitshift_right = 0b01010, rotate_left = 0b01100, rotate_right = 0b01101, less_than = 0b01110, greater_than = 0b10000, less_or_equal_than = 0b10001, greater_or_equal_than = 0b10010, equals = 0b10100, different = 0b10101, binary_and = 0b10110, binary_or = 0b11000, binary_xor = 0b11001, logical_and = 0b11010, logical_or = 0b11100, }; enum class symbol_t { l_paren, r_paren, logical_not, binary_not, divide, modulo, multiply, subtract, add, bitshift_left, bitshift_right, rotate_left, rotate_right, less_than, greater_than, less_or_equal_than, greater_or_equal_than, equals, different, binary_and, binary_or, binary_xor, logical_and, logical_or, new_line }; struct identifier { std::shared_ptr location; std::string value; }; inline auto operator<=>(const identifier& lhs, const identifier& rhs) { // TODO: check if the stdlib evolves to support ALL THE HELLA <=> THAT SHOULD BE THERE return -1 * (lhs.value < rhs.value) + (lhs.value > rhs.value); } inline auto operator==(const identifier& lhs, const identifier& rhs) { return lhs.value == rhs.value; } struct expression; struct unary_algebraic_expression { std::shared_ptr location; operator_t op; std::unique_ptr content; }; struct binary_algebraic_expression { std::shared_ptr location; std::unique_ptr lhs; operator_t op; std::unique_ptr rhs; }; struct command_expression { std::shared_ptr location; identifier name; std::vector> arguments; }; struct variable_expression { std::shared_ptr location; identifier name; }; struct paren_expression { std::shared_ptr location; std::variant< std::unique_ptr, std::unique_ptr > content; }; struct literal_int_expression { std::shared_ptr location; int32_t value; }; struct literal_string_expression { std::shared_ptr location; std::string value; }; struct expression { std::shared_ptr location; std::variant< std::unique_ptr, std::unique_ptr, std::unique_ptr, std::unique_ptr, std::unique_ptr, std::unique_ptr > contents; }; struct statement; struct block { std::shared_ptr location; std::vector contents; }; struct conditional { std::shared_ptr location; std::unique_ptr condition; std::unique_ptr on_condition; std::unique_ptr otherwise; }; struct while_loop { std::shared_ptr location; std::unique_ptr condition; std::unique_ptr on_condition; }; struct statement { std::shared_ptr location; std::variant< std::unique_ptr, std::unique_ptr, std::unique_ptr > contents; }; struct token { std::shared_ptr location; std::variant value; }; std::vector lex(const std::string& code, std::vector& errors); scripting::ast::block parse(std::span code, std::vector& errors); } }