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
andFarmScript::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.