visitForStmt method
Implementation
@override
Uint8List visitForStmt(ForExpr stmt) {
final bytesBuilder = BytesBuilder();
bytesBuilder.add(_lineInfo(stmt.line, stmt.column));
if (_currentFunctionOptimization == null) {
bytesBuilder.addByte(OpCode.codeBlock);
bytesBuilder.add(_identifier(InternalIdentifier.forExpressionInit));
}
late Uint8List condition;
Uint8List? increment;
ASTNode? capturedDecl;
final newSymbolMap = <String, String>{};
final newVariableMap = <String, HTResolvedVariable>{};
_markedSymbolsList.add(newSymbolMap);
_markedVariablesList.add(newVariableMap);
if (stmt.init != null) {
final userDecl = stmt.init as VarDecl;
final markedId = '${_lexicon.internalPrefix}${userDecl.id.id}';
final markedVariable = _optimization.loopBindings[stmt]!.first;
newSymbolMap[userDecl.id.id] = markedId;
newVariableMap[markedId] = markedVariable;
// Uint8List? initializer;
// if (userDecl.initializer != null) {
// initializer = compileAST(!, endOfExec: true);
// }
final initDecl = VarDecl(
IdentifierExpr(markedId),
initializer: userDecl.initializer,
isMutable: userDecl.isMutable,
line: userDecl.line,
column: userDecl.column,
);
_syntheticDeclarations[initDecl.id] = markedVariable;
bytesBuilder.add(visitVarDecl(initDecl));
// 这里是为了实现将变量声明移动到for循环语句块内部的效果
final capturedInit = _syntheticIdentifier(markedId, markedVariable);
capturedDecl = VarDecl(userDecl.id, initializer: capturedInit);
}
if (stmt.condition != null) {
condition = compileAST(stmt.condition!);
} else {
final boolExpr = ASTLiteralBoolean(true);
condition = visitBooleanExpr(boolExpr);
}
if (stmt.increment != null) {
increment = compileAST(stmt.increment!);
}
if (capturedDecl != null) {
stmt.loop.statements.insert(0, capturedDecl);
}
final loop = visitBlockStmt(stmt.loop);
final continueLength = condition.length + loop.length + 1;
final breakLength = continueLength + (increment?.length ?? 0) + 3;
bytesBuilder.addByte(OpCode.loopPoint);
bytesBuilder.add(_uint16(continueLength));
bytesBuilder.add(_uint16(breakLength));
bytesBuilder.add(condition);
bytesBuilder.addByte(OpCode.whileStmt);
bytesBuilder.add(loop);
if (increment != null) {
bytesBuilder.add(increment);
}
bytesBuilder.addByte(OpCode.skip);
bytesBuilder.add(_int16(-breakLength));
_markedSymbolsList.removeLast();
_markedVariablesList.removeLast();
if (_currentFunctionOptimization == null) {
bytesBuilder.addByte(OpCode.endOfCodeBlock);
}
return bytesBuilder.toBytes();
}