#ifndef EXPR_HH #define EXPR_HH #include "../tokenizer.hh" #include #include #include struct Expr; using ExprPtr = std::shared_ptr; struct _Binary { ExprPtr left; Token op; ExprPtr right; }; struct _Grouping { ExprPtr expression; }; struct _Literal { Object value; }; struct _Unary { Token op; ExprPtr right; }; enum class ExprType { BINARY, GROUPING, LITERAL, UNARY, }; using ExprVariant = std::variant<_Binary, _Grouping, _Literal, _Unary>; struct Expr { ExprType type; ExprVariant value; ExprPtr to_expr_ptr() { return std::make_shared(*this); } }; inline Expr Binary(ExprPtr left, Token op, ExprPtr right) { return Expr{ExprType::BINARY, _Binary{left, op, right}}; } inline Expr Grouping(ExprPtr expr) { return Expr{ExprType::GROUPING, _Grouping{expr}}; } inline Expr Literal(Object value) { return Expr{ExprType::LITERAL, _Literal{value}}; } inline Expr Unary(Token op, ExprPtr right) { return Expr{ExprType::UNARY, _Unary{op, right}}; } class AstPrinter { public: std::string print(const Expr &expr); private: std::string parenthesize(const std::string &name, std::vector exprs); }; #endif