template struct BinaryExpr : Expr, ExprVisitor { const Expr left; const Token oper; const Expr right; BinaryExpr(Expr left, Token oper, Expr right) : left(left), oper(oper), right(right) { } T accept(ExprVisitor visitor){ return visitor.visitBinaryExpr(this); } }; template struct GroupingExpr : Expr, ExprVisitor { const Expr expression; GroupingExpr(Expr expression) : expression(expression) { } T accept(ExprVisitor visitor){ return visitor.visitGroupingExpr(this); } }; template struct LiteralExpr : Expr, ExprVisitor { const std::string value; LiteralExpr(std::string value) : value(value) { } T accept(ExprVisitor visitor){ return visitor.visitLiteralExpr(this); } }; template struct UnaryExpr : Expr, ExprVisitor { const Token oper; const Expr right; UnaryExpr(Token oper, Expr right) : oper(oper), right(right) { } T accept(ExprVisitor visitor){ return visitor.visitUnaryExpr(this); } };