visitForRangeStmt method

  1. @override
Uint8List visitForRangeStmt(
  1. ForRangeStmt stmt
)
override

Implementation

@override
Uint8List visitForRangeStmt(ForRangeStmt stmt) {
  final bytesBuilder = BytesBuilder();
  bytesBuilder.add(_lineInfo(stmt.line, stmt.column));
  bytesBuilder.addByte(HTOpCode.codeBlock);
  bytesBuilder.add(_parseIdentifier(Semantic.forStmtInit));

  final collection = stmt.iterateValue
      ? MemberExpr(stmt.collection,
          IdentifierExpr(_lexicon.idCollectionValues, isLocal: false))
      : stmt.collection;

  // declare the iterator
  final iterInit = MemberExpr(collection,
      IdentifierExpr(_lexicon.idIterableIterator, isLocal: false));
  final iterInitBytes = compileAST(iterInit, endOfExec: true);
  final iterId = '__iter${iterIndex++}';
  final iterDecl = _assembleVarDeclStmt(
      iterId, stmt.iterator.line, stmt.iterator.column,
      initializer: iterInitBytes);
  bytesBuilder.add(iterDecl);

  // update iter move result
  // calls iterator.moveNext()
  final moveIter = CallExpr(MemberExpr(IdentifierExpr(iterId),
      IdentifierExpr(_lexicon.idIterableIteratorMoveNext, isLocal: false)));
  final moveIterBytes = visitCallExpr(moveIter);
  final condition = moveIterBytes;

  // get current item value
  stmt.iterator.initializer = MemberExpr(IdentifierExpr(iterId),
      IdentifierExpr(_lexicon.idIterableIteratorCurrent, isLocal: false));
  stmt.loop.statements.insert(0, stmt.iterator);
  final loop = visitBlockStmt(stmt.loop);

  bytesBuilder.addByte(HTOpCode.loopPoint);
  final continueLength = condition.length + 1 + loop.length;
  final loopLength = condition.length + 1 + loop.length + 3;
  bytesBuilder.add(_uint16(continueLength));
  bytesBuilder.add(_uint16(loopLength));
  bytesBuilder.add(condition);
  bytesBuilder.addByte(HTOpCode.whileStmt);
  bytesBuilder.add(loop);
  bytesBuilder.addByte(HTOpCode.skip);
  bytesBuilder.add(_int16(-loopLength));
  bytesBuilder.addByte(HTOpCode.endOfCodeBlock);
  return bytesBuilder.toBytes();
}