95 lines
1.9 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);
// Copy assignment
Expr &operator=(const Expr &other);
// Move assignment
Expr &operator=(Expr &&other);
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