#pragma once #include "Expression.h" #include "Statement.h" #include "helperFunctions/ShortHands.h" #include "TypeWrapper.h" #include "Environment.h" #include "Value.h" #include "StdLib.h" #include #include #include #include class Return : public std::exception { public: Value value; Return(Value value) : value(value) {} const char* what() const noexcept override { return "Return"; } }; class Interpreter : public ExprVisitor, public StmtVisitor { public: Value visitBinaryExpr(const std::shared_ptr& expression) override; Value visitGroupingExpr(const std::shared_ptr& expression) override; Value visitLiteralExpr(const std::shared_ptr& expression) override; Value visitUnaryExpr(const std::shared_ptr& expression) override; Value visitVariableExpr(const std::shared_ptr& expression) override; Value visitAssignExpr(const std::shared_ptr& expression) override; Value visitCallExpr(const std::shared_ptr& expression) override; void visitBlockStmt(const std::shared_ptr& statement) override; void visitExpressionStmt(const std::shared_ptr& statement) override; void visitVarStmt(const std::shared_ptr& statement) override; void visitFunctionStmt(const std::shared_ptr& statement) override; void visitReturnStmt(const std::shared_ptr& statement) override; void visitIfStmt(const std::shared_ptr& statement) override; void interpret(std::vector> statements); explicit Interpreter(bool IsInteractive) : IsInteractive(IsInteractive){ environment = std::make_shared(); // Pre-allocate environment pool for (size_t i = 0; i < POOL_SIZE; ++i) { envPool.push(std::make_shared()); } // Add standard library functions addStdLibFunctions(); } virtual ~Interpreter() = default; private: std::shared_ptr environment; bool IsInteractive; std::vector> builtinFunctions; std::vector> functions; // Environment pool for fast function calls std::stack> envPool; static const size_t POOL_SIZE = 1000; // Pre-allocate 1000 environments // Return value mechanism (replaces exceptions) struct ReturnContext { Value returnValue; bool hasReturn; ReturnContext() : returnValue(NONE_VALUE), hasReturn(false) {} }; std::stack returnStack; Value evaluate(const std::shared_ptr& expr); bool isEqual(Value a, Value b); bool isWholeNumer(double num); void execute(const std::shared_ptr& statement); void executeBlock(std::vector> statements, std::shared_ptr env); void addStdLibFunctions(); public: bool isTruthy(Value object); std::string stringify(Value object); void addBuiltinFunction(std::shared_ptr func); };