#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 "ErrorReporter.h" #include #include #include #include class Interpreter : public ExprVisitor, public StmtVisitor { public: Value visitBinaryExpr(const std::shared_ptr& expression) override; Value visitCallExpr(const std::shared_ptr& expression) override; Value visitFunctionExpr(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 visitVarExpr(const std::shared_ptr& expression) override; Value visitIncrementExpr(const std::shared_ptr& expression) override; Value visitAssignExpr(const std::shared_ptr& expression) override; void visitBlockStmt(const std::shared_ptr& statement, ExecutionContext* context = nullptr) override; void visitExpressionStmt(const std::shared_ptr& statement, ExecutionContext* context = nullptr) override; void visitVarStmt(const std::shared_ptr& statement, ExecutionContext* context = nullptr) override; void visitFunctionStmt(const std::shared_ptr& statement, ExecutionContext* context = nullptr) override; void visitReturnStmt(const std::shared_ptr& statement, ExecutionContext* context = nullptr) override; void visitIfStmt(const std::shared_ptr& statement, ExecutionContext* context = nullptr) override; void interpret(std::vector > statements); explicit Interpreter(bool IsInteractive) : IsInteractive(IsInteractive), errorReporter(nullptr){ environment = std::make_shared(); } virtual ~Interpreter() = default; private: std::shared_ptr environment; bool IsInteractive; std::vector > builtinFunctions; std::vector > functions; ErrorReporter* errorReporter; Value evaluate(const std::shared_ptr& expr); bool isEqual(Value a, Value b); bool isWholeNumer(double num); void execute(const std::shared_ptr& statement, ExecutionContext* context = nullptr); void executeBlock(std::vector > statements, std::shared_ptr env, ExecutionContext* context = nullptr); void addStdLibFunctions(); public: bool isTruthy(Value object); std::string stringify(Value object); void addBuiltinFunction(std::shared_ptr func); // Error reporting void setErrorReporter(ErrorReporter* reporter) { errorReporter = reporter; if (environment) { environment->setErrorReporter(reporter); } // Add standard library functions after error reporter is set addStdLibFunctions(); } };