97 lines
2.0 KiB
C++
97 lines
2.0 KiB
C++
#ifndef EXPR_HH
|
|
#define EXPR_HH
|
|
|
|
#include "../tokenizer.hh"
|
|
#include <memory>
|
|
#include <variant>
|
|
|
|
struct Expr;
|
|
struct _Binary;
|
|
struct _Grouping;
|
|
struct _Literal;
|
|
struct _Unary;
|
|
struct _Variable;
|
|
struct _Assign;
|
|
|
|
enum class ExprType {
|
|
BINARY,
|
|
GROUPING,
|
|
LITERAL,
|
|
UNARY,
|
|
VARIABLE,
|
|
ASSIGN,
|
|
};
|
|
|
|
using ExprVariant = std::variant<
|
|
std::shared_ptr<_Binary>,
|
|
std::shared_ptr<_Grouping>,
|
|
std::shared_ptr<_Literal>,
|
|
std::shared_ptr<_Unary>,
|
|
std::shared_ptr<_Variable>,
|
|
std::shared_ptr<_Assign>
|
|
>;
|
|
|
|
#define Binary(LEFT, OP, RIGHT) (Expr{ExprType::BINARY, std::make_shared<_Binary>(LEFT, OP, RIGHT)})
|
|
#define Grouping(EXPR) (Expr{ExprType::GROUPING, std::make_shared<_Grouping>(EXPR)})
|
|
#define Literal(VALUE) (Expr{ExprType::LITERAL, std::make_shared<_Literal>(VALUE)})
|
|
#define Unary(OP, RIGHT) (Expr{ExprType::UNARY, std::make_shared<_Unary>(OP, RIGHT)})
|
|
#define Variable(NAME) (Expr{ExprType::VARIABLE, std::make_shared<_Variable>(NAME)})
|
|
#define Assign(NAME, VALUE) (Expr{ExprType::ASSIGN, std::make_shared<_Assign>(NAME, VALUE)})
|
|
|
|
struct Expr {
|
|
Expr(ExprType type, ExprVariant value);
|
|
|
|
// Copy constructor
|
|
Expr(const Expr &other);
|
|
|
|
// Move constructor
|
|
Expr(Expr &&other) noexcept;
|
|
|
|
// Copy assignment
|
|
Expr &operator=(const Expr &other);
|
|
|
|
// Move assignment
|
|
Expr &operator=(Expr &&other) noexcept;
|
|
|
|
~Expr() = default;
|
|
|
|
ExprType type;
|
|
ExprVariant value;
|
|
};
|
|
|
|
struct _Binary {
|
|
_Binary(const Expr &left, Token op, const Expr &right) : left{left}, op{op}, right{right} {}
|
|
Expr left;
|
|
Token op;
|
|
Expr right;
|
|
};
|
|
|
|
struct _Grouping {
|
|
_Grouping(const Expr &expr) : expr{expr} {}
|
|
Expr expr;
|
|
};
|
|
|
|
struct _Literal {
|
|
_Literal(Object value) : value{value} {}
|
|
Object value;
|
|
};
|
|
|
|
struct _Unary {
|
|
_Unary(Token op, const Expr &right) : op{op}, right{right} {}
|
|
Token op;
|
|
Expr right;
|
|
};
|
|
|
|
struct _Variable {
|
|
_Variable(Token name) : name{name} {}
|
|
Token name;
|
|
};
|
|
|
|
struct _Assign {
|
|
_Assign(Token name, const Expr &value) : name{name}, value{value} {}
|
|
Token name;
|
|
Expr value;
|
|
};
|
|
|
|
#endif
|