// // Created by Bobby Lucero on 5/21/23. // #pragma once #include #include #include "Lexer.h" #include "helperFunctions/ShortHands.h" #include "TypeWrapper.h" #include "Value.h" // Forward declarations struct FunctionExpr; struct ExprVisitor; struct AssignExpr; struct BinaryExpr; struct GroupingExpr; struct LiteralExpr; struct UnaryExpr; struct VarExpr; struct CallExpr; // AST nodes use shared_ptr for proper memory management struct ExprVisitor { virtual Value visitAssignExpr(const std::shared_ptr& expr) = 0; virtual Value visitBinaryExpr(const std::shared_ptr& expr) = 0; virtual Value visitCallExpr(const std::shared_ptr& expr) = 0; virtual Value visitFunctionExpr(const std::shared_ptr& expr) = 0; virtual Value visitGroupingExpr(const std::shared_ptr& expr) = 0; virtual Value visitLiteralExpr(const std::shared_ptr& expr) = 0; virtual Value visitUnaryExpr(const std::shared_ptr& expr) = 0; virtual Value visitVarExpr(const std::shared_ptr& expr) = 0; }; struct Expr : public std::enable_shared_from_this { virtual Value accept(ExprVisitor* visitor) = 0; virtual ~Expr() = default; }; struct AssignExpr : Expr { const Token name; const Token op; std::shared_ptr value; AssignExpr(Token name, Token op, std::shared_ptr value) : name(name), op(op), value(value) {} Value accept(ExprVisitor* visitor) override { return visitor->visitAssignExpr(std::static_pointer_cast(shared_from_this())); } }; struct BinaryExpr : Expr { std::shared_ptr left; const Token oper; std::shared_ptr right; BinaryExpr(std::shared_ptr left, Token oper, std::shared_ptr right) : left(left), oper(oper), right(right) {} Value accept(ExprVisitor* visitor) override{ return visitor->visitBinaryExpr(std::static_pointer_cast(shared_from_this())); } }; struct GroupingExpr : Expr { std::shared_ptr expression; explicit GroupingExpr(std::shared_ptr expression) : expression(expression) {} Value accept(ExprVisitor* visitor) override{ return visitor->visitGroupingExpr(std::static_pointer_cast(shared_from_this())); } }; struct LiteralExpr : Expr { std::string value; bool isNumber; bool isNull; bool isBoolean; LiteralExpr(const std::string& value, bool isNumber, bool isNull, bool isBoolean) : value(value), isNumber(isNumber), isNull(isNull), isBoolean(isBoolean) {} Value accept(ExprVisitor* visitor) override{ return visitor->visitLiteralExpr(std::static_pointer_cast(shared_from_this())); } }; struct UnaryExpr : Expr { Token oper; std::shared_ptr right; UnaryExpr(Token oper, std::shared_ptr right) : oper(oper), right(right) {} Value accept(ExprVisitor* visitor) override{ return visitor->visitUnaryExpr(std::static_pointer_cast(shared_from_this())); } }; struct VarExpr : Expr { Token name; explicit VarExpr(Token name) : name(name){}; Value accept(ExprVisitor* visitor) override { return visitor->visitVarExpr(std::static_pointer_cast(shared_from_this())); } }; struct FunctionExpr : Expr { std::vector params; std::vector> body; FunctionExpr(const std::vector& params, const std::vector>& body) : params(params), body(body) {} Value accept(ExprVisitor* visitor) override { return visitor->visitFunctionExpr(std::static_pointer_cast(shared_from_this())); } }; struct CallExpr : Expr { std::shared_ptr callee; Token paren; std::vector> arguments; CallExpr(std::shared_ptr callee, Token paren, std::vector> arguments) : callee(callee), paren(paren), arguments(arguments) {} Value accept(ExprVisitor* visitor) override { return visitor->visitCallExpr(std::static_pointer_cast(shared_from_this())); } };