Roll up the Interpreter

Let's check the interpreter's main function.

interpreter.interpret(statements);

This function is responsible for executing the parsed statements.

#1 interpret(statements)

void Interpreter::interpret(std::vector<Stmt *> statements)
{
    // Iterate over each statement in the vector
    for (auto &statement : statements)
    {
        // Check if the statement is not null
        if (statement)
        {
            // Execute the current statement
            execute(statement);
        }

        // Check if a runtime error has occurred
        if (FarmScript::hadRuntimeError)
        {
            // Reset the flag for runtime error
            FarmScript::hadRuntimeError = false;
            // Break out of the loop to stop interpretation
            break;
        }
        // Check if a parsing error has occurred
        else if (FarmScript::hadError)
        {
            // Break out of the loop to stop interpretation
            break;
        }
    }
}
  • The method takes a vector of statements pointers (statements) as input.
  • It iterates over each statement pointer (statement) in the vector using a range-based for loop.
  • For each statement, first checks if the statement pointer is not null. This is a safety check to ensure that there are valid statements to interpret.
  • Inside the loop, it calls the execute method to execute the current statement.
  • After executing each statement, it checks two flags: FarmScript::hadRuntimeError and FarmScript::hadError. These flags are likely used to indicate whether a runtime error or a parsing error has occurred, respectively.
  • If a runtime error has occurred (FarmScript::hadRuntimeError is true), it resets the flag and breaks out of the loop to stop further interpretation.
  • If a parsing error has occurred (FarmScript::hadError is true), it breaks out of the loop to stop further interpretation.

#1.1 Execute

The execute method in Interpreter class is responsible for executing individual statements.

void Interpreter::execute(Stmt *stmt)
{
    // Check if the statement pointer is not null
    if (stmt)
    {
        // Determine the type of the statement and execute accordingly
        switch (stmt->type)
        {
            case StmtType_Print:
                // Execute a print statement
                visitPrint((Print *)stmt);
                break;
            case StmtType_Expression:
                // Execute an expression statement
                visitExpression((Expression *)stmt);
                break;
            case StmtType_Var:
                // Execute a variable declaration statement
                visitVar((Var *)stmt);
                break;
            case StmtType_Block:
                // Execute a block of statements
                visitBlock((Block *)stmt);
                break;
            case StmtType_If:
                // Execute an if statement
                visitIf((If *)stmt);
                break;
            case StmtType_While:
                // Execute a while loop statement
                visitWhile((While *)stmt);
                break;
            case StmtType_Break:
                // Execute a break statement
                visitBreak((Break *)stmt);
                break;
            case StmtType_Function:
                // Execute a function declaration statement
                visitFunction((Function *)stmt);
                break;
            case StmtType_Class:
                // Execute a class declaration statement
                visitClass((Class *)stmt);
                break;
            case StmtType_Return:
                // Execute a return statement
                visitReturn((Return *)stmt);
                break;
            default:
                // Handle error for invalid statement type
                FarmScript::error(0, "Invalid statement type.");
        }
    }
}
  • The method takes a pointer to a statement (stmt) as input.
  • It first checks if the statement pointer is not null to ensure that there is a valid statement to execute.
  • Based on the type of the statement (stmt->type), it dispatches execution to the appropriate method using a switch statement.
  • Each case in the switch statement corresponds to a different type of statement, such as print, expression, variable declaration, etc.
  • For each case, it casts the statement pointer to the appropriate type and calls the corresponding visit method to execute the statement.
  • If the statement type is invalid, it raises an error using the FarmScript::error method.