#pragma once #include #include #include #include #include #include #include "Value.h" #include "RuntimeDiagnostics.h" struct Expr; struct Stmt; struct Environment; struct BuiltinFunction; struct Function; struct Thunk; class ErrorReporter; struct ExecutionContext; struct CallExpr; // Forward declaration class Evaluator; // RAII helper for thunk execution flag struct ScopedThunkFlag { bool& flag; bool prev; ScopedThunkFlag(bool& f) : flag(f), prev(f) { flag = true; } ~ScopedThunkFlag() { flag = prev; } }; // RAII helper for environment management struct ScopedEnv { std::shared_ptr& target; std::shared_ptr prev; ScopedEnv(std::shared_ptr& e) : target(e), prev(e) {} ~ScopedEnv() { target = prev; } }; // Thunk class for trampoline-based tail call optimization struct Thunk { public: using ThunkFunction = std::function; explicit Thunk(ThunkFunction func) : func(std::move(func)) {} Value execute() const { return func(); } bool isThunk() const { return true; } private: ThunkFunction func; }; class Executor; class Interpreter { private: std::shared_ptr environment; bool isInteractive; std::vector> builtinFunctions; std::vector> functions; std::vector> thunks; // Store thunks to prevent memory leaks // Global extension registries std::unordered_map>> classExtensions; std::unordered_map>> builtinExtensions; // keys: "string","array","dict","any" std::unordered_map classParents; // child -> parent std::unordered_map> classTemplates; // className -> template dict ErrorReporter* errorReporter; bool inThunkExecution = false; // Automatic cleanup tracking int thunkCreationCount = 0; static const int CLEANUP_THRESHOLD = 10000; RuntimeDiagnostics diagnostics; // Utility functions for runtime operations std::unique_ptr evaluator; std::unique_ptr executor; public: explicit Interpreter(bool isInteractive); virtual ~Interpreter(); // Public interface for main void interpret(std::vector> statements); void setErrorReporter(ErrorReporter* reporter); // Methods needed by Evaluator Value evaluate(const std::shared_ptr& expr); Value evaluateCallExprInline(const std::shared_ptr& expression); // Inline TCO for performance void execute(const std::shared_ptr& statement, ExecutionContext* context = nullptr); void executeBlock(std::vector> statements, std::shared_ptr env, ExecutionContext* context = nullptr); bool isTruthy(Value object); bool isEqual(Value a, Value b); std::string stringify(Value object); bool isInteractiveMode() const; std::shared_ptr getEnvironment(); void setEnvironment(std::shared_ptr env); void addFunction(std::shared_ptr function); void reportError(int line, int column, const std::string& errorType, const std::string& message, const std::string& lexeme = ""); void addBuiltinFunction(std::shared_ptr func); void cleanupUnusedFunctions(); void cleanupUnusedThunks(); void forceCleanup(); // Extension APIs void registerExtension(const std::string& targetName, const std::string& methodName, std::shared_ptr fn); std::shared_ptr lookupExtension(const std::string& targetName, const std::string& methodName); void registerClass(const std::string& className, const std::string& parentName); std::string getParentClass(const std::string& className) const; void setClassTemplate(const std::string& className, const std::unordered_map& tmpl); bool getClassTemplate(const std::string& className, std::unordered_map& out) const; std::unordered_map buildMergedTemplate(const std::string& className) const; void addStdLibFunctions(); private: Value runTrampoline(Value initialResult); };