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.
 

169 lines
4.0 KiB

#pragma once
#include <variant>
#include <memory>
#include <vector>
#include <span>
#include <UserScript.h>
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<const code_location> 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<const code_location> location;
operator_t op;
std::unique_ptr<expression> content;
};
struct binary_algebraic_expression {
std::shared_ptr<const code_location> location;
std::unique_ptr<expression> lhs;
operator_t op;
std::unique_ptr<expression> rhs;
};
struct command_expression {
std::shared_ptr<const code_location> location;
identifier name;
std::vector<std::unique_ptr<expression>> arguments;
};
struct variable_expression {
std::shared_ptr<const code_location> location;
identifier name;
};
struct paren_expression {
std::shared_ptr<const code_location> location;
std::variant<
std::unique_ptr<expression>,
std::unique_ptr<command_expression>
> content;
};
struct literal_int_expression {
std::shared_ptr<const code_location> location;
int32_t value;
};
struct literal_string_expression {
std::shared_ptr<const code_location> location;
std::string value;
};
struct expression {
std::shared_ptr<const code_location> location;
std::variant<
std::unique_ptr<unary_algebraic_expression>,
std::unique_ptr<binary_algebraic_expression>,
std::unique_ptr<paren_expression>,
std::unique_ptr<variable_expression>,
std::unique_ptr<literal_int_expression>,
std::unique_ptr<literal_string_expression>
> contents;
};
struct statement;
struct block {
std::shared_ptr<const code_location> location;
std::vector<statement> contents;
};
struct conditional {
std::shared_ptr<const code_location> location;
std::unique_ptr<expression> condition;
std::unique_ptr<block> on_condition;
std::unique_ptr<block> otherwise;
};
struct while_loop {
std::shared_ptr<const code_location> location;
std::unique_ptr<expression> condition;
std::unique_ptr<block> on_condition;
};
struct statement {
std::shared_ptr<const code_location> location;
std::variant<
std::unique_ptr<command_expression>,
std::unique_ptr<conditional>,
std::unique_ptr<while_loop>
> contents;
};
struct token {
std::shared_ptr<const scripting::code_location> location;
std::variant<scripting::ast::identifier, int32_t, std::string, symbol_t> value;
};
std::vector<token> lex(const std::string& code, std::vector<scripting::script_error>& errors);
scripting::ast::block parse(std::span<token> code, std::vector<scripting::script_error>& errors);
}
}