run function
void
run(
- String source, {
- required bool isRepl,
})
Implementation
void run(String source, {required bool isRepl}) {
Object? result;
try {
final lexer = Lexer(source);
List<Token> tokens = lexer.scanTokens();
final parser = Parser(tokens);
List<Stmt> statements = parser.parse(); // parse() now returns List<Stmt>
// Stop if there was a syntax error during parsing (indicated by hadError flag)
// The error message should have been printed by the parser's error handler.
// Note: Parser exceptions are caught below, this check might be redundant.
// if (hadError) return; // Let exceptions handle control flow
// // Optional: Print AST for debugging
// if (isRepl && !hadError) { // Only print AST if no parse errors
// print("--- AST ---");
// statements.forEach((stmt) => print(AstPrinter().printStmt(stmt)));
// print("-----------");
// }
// If parsing was successful, interpret the AST
result = interpreter.interpret(statements);
if (result != null) result = interpreter.repr(result);
} on LexerError catch (e) {
print(e);
hadError = true; // Mark static error
} on ParseError {
// Error should have been printed by parser's synchronize/error mechanism.
hadError = true; // Mark static error
} on RuntimeError {
// Runtime errors are caught by interpreter.interpret() and printed there.
hadRuntimeError = true; // Mark runtime error
} on ReturnValue catch (_) {
// This should only happen if 'return' is used at the top level (outside any function)
hadRuntimeError = true; // Treat as runtime error in REPL/script context
} catch (e, stacktrace) {
// Catch any other unexpected Dart errors during execution
print("An unexpected internal error occurred: $e");
if (isRepl) {
// Show stacktrace in REPL for debugging the interpreter itself
print(stacktrace);
}
hadError = true; // Treat unexpected errors as critical failures
}
if (result != null) {
print(result.toString());
}
}