// // 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 IncrementExpr; struct TernaryExpr; struct ArrayLiteralExpr; struct ArrayIndexExpr; struct ArrayAssignExpr; 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 visitIncrementExpr(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; virtual Value visitTernaryExpr(const std::shared_ptr& expr) = 0; virtual Value visitArrayLiteralExpr(const std::shared_ptr& expr) = 0; virtual Value visitArrayIndexExpr(const std::shared_ptr& expr) = 0; virtual Value visitArrayAssignExpr(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; bool isTailCall = false; // Flag for tail call optimization 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())); } }; struct IncrementExpr : Expr { std::shared_ptr operand; Token oper; bool isPrefix; // true for ++x, false for x++ IncrementExpr(std::shared_ptr operand, Token oper, bool isPrefix) : operand(operand), oper(oper), isPrefix(isPrefix) {} Value accept(ExprVisitor* visitor) override { return visitor->visitIncrementExpr(std::static_pointer_cast(shared_from_this())); } }; struct TernaryExpr : Expr { std::shared_ptr condition; std::shared_ptr thenExpr; std::shared_ptr elseExpr; TernaryExpr(std::shared_ptr condition, std::shared_ptr thenExpr, std::shared_ptr elseExpr) : condition(condition), thenExpr(thenExpr), elseExpr(elseExpr) {} Value accept(ExprVisitor* visitor) override { return visitor->visitTernaryExpr(std::static_pointer_cast(shared_from_this())); } }; struct ArrayLiteralExpr : Expr { std::vector> elements; explicit ArrayLiteralExpr(const std::vector>& elements) : elements(elements) {} Value accept(ExprVisitor* visitor) override { return visitor->visitArrayLiteralExpr(std::static_pointer_cast(shared_from_this())); } }; struct ArrayIndexExpr : Expr { std::shared_ptr array; std::shared_ptr index; Token bracket; // The closing bracket token for error reporting ArrayIndexExpr(std::shared_ptr array, std::shared_ptr index, Token bracket) : array(array), index(index), bracket(bracket) {} Value accept(ExprVisitor* visitor) override { return visitor->visitArrayIndexExpr(std::static_pointer_cast(shared_from_this())); } }; struct ArrayAssignExpr : Expr { std::shared_ptr array; std::shared_ptr index; std::shared_ptr value; Token bracket; // The closing bracket token for error reporting ArrayAssignExpr(std::shared_ptr array, std::shared_ptr index, std::shared_ptr value, Token bracket) : array(array), index(index), value(value), bracket(bracket) {} Value accept(ExprVisitor* visitor) override { return visitor->visitArrayAssignExpr(std::static_pointer_cast(shared_from_this())); } };