#ifndef EXPR_HH #define EXPR_HH #include "../tokenizer.hh" #include #include #include struct Expr; struct Binary; struct Grouping; struct Literal; struct Unary; enum class ExprType { BINARY, GROUPING, LITERAL, UNARY, }; using ExprVariant = std::variant< std::shared_ptr, std::shared_ptr, std::shared_ptr, std::shared_ptr >; struct Expr { // Copy constructor Expr(const Expr &other); // Move constructor Expr(const Expr &&other); // Binary expressoin Expr(Expr left, Token op, Expr right); // Literal expression Expr(Object value); // Unary expressoin Expr(Token op, Expr right); // Group expression // Has to take an extra parameter to avoid conflicting with copy constructor Expr(Expr expr, void *ptr); ExprType type; ExprVariant value; }; struct Binary { Binary(Expr left, Token op, Expr right) : left{left}, op{op}, right{right} {} Expr left; Token op; Expr right; }; struct Grouping { Grouping(Expr expr) : expr{expr} {} Expr expr; }; struct Literal { Literal(Object value) : value{value} {} Object value; }; struct Unary { Unary(Token op, Expr right) : op{op}, right{right} {} Token op; Expr right; }; class AstPrinter { public: std::string print(const Expr &expr); private: std::string parenthesize(const std::string &name, std::vector exprs); }; #endif