Class RangeIterationHelper
Extracts the body-independent parts of range iteration from ForRangeGenerator:
initialization (start/end/by evaluation, assertions, direction detection),
dispatch case generation (ascending/descending/equal), loop condition evaluation,
increment operations, and body setup (loop variable assignment).
Both ForRangeGenerator and StreamStatementGenerator delegate to this helper,
each providing their own body instructions. This eliminates ~500 lines of duplication
between for-range loops and stream for-range sources.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static final recordParameters for case constructor (AscendingCase or DescendingCase).(package private) static final recordHelper record to pass initialization data between methods. -
Field Summary
Fields inherited from class AbstractGenerator
constantCopyOnAccessLoader, debugInfoCreator, instructionBuilder, MAX_MESSAGE_LENGTH, stackContext, synthesisedCallMetaData, typeNameOrException -
Constructor Summary
ConstructorsConstructorDescriptionRangeIterationHelper(IRGenerationContext stackContext, GeneratorSet generators) -
Method Summary
Modifier and TypeMethodDescriptiongenerateBodySetup(String loopVariableName, String currentTemp, ISymbol rangeType, DebugInfo debugInfo) Generate body setup: loopVariable becomes a FRESH per-iteration value copied from the counter.(package private) ForRangePolymorphicInstr.DispatchCasesgenerateDispatchCases(RangeIterationHelper.InitializationData initData, String loopVariableName, DebugInfo debugInfo) Generate dispatch cases with explicit IR for all three directions.(package private) RangeIterationHelper.InitializationDatagenerateInitialization(EK9Parser.ForRangeContext forRangeCtx, DebugInfo debugInfo) Generate initialization instructions for the loop.(package private) ForRangePolymorphicInstr.LoopMetadatagenerateLoopMetadata(RangeIterationHelper.InitializationData initData, String loopVariableName) Generate loop metadata containing variable names and types.
-
Constructor Details
-
RangeIterationHelper
RangeIterationHelper(IRGenerationContext stackContext, GeneratorSet generators)
-
-
Method Details
-
generateInitialization
RangeIterationHelper.InitializationData generateInitialization(EK9Parser.ForRangeContext forRangeCtx, DebugInfo debugInfo) Generate initialization instructions for the loop. This includes: evaluating start/end/by, asserting they're set, direction detection. -
generateDispatchCases
ForRangePolymorphicInstr.DispatchCases generateDispatchCases(RangeIterationHelper.InitializationData initData, String loopVariableName, DebugInfo debugInfo) Generate dispatch cases with explicit IR for all three directions. -
generateLoopMetadata
ForRangePolymorphicInstr.LoopMetadata generateLoopMetadata(RangeIterationHelper.InitializationData initData, String loopVariableName) Generate loop metadata containing variable names and types. -
generateBodySetup
List<IRInstr> generateBodySetup(String loopVariableName, String currentTemp, ISymbol rangeType, DebugInfo debugInfo) Generate body setup: loopVariable becomes a FRESH per-iteration value copied from the counter.Per-iteration value semantics (FOR-RANGE only). The internal counter (
currentTemp) is a single object advanced in place by_inc()/_dec(). If the user-visible loop variable merely aliased that counter (the oldSTORE loopVariable, currentTemp), any capture / alias / escape of the loop variable would track the moving counter and read the FINAL value — the classic "closure captures the loop variable" footgun. Instead we give the loop variable a fresh object each iteration: a copy of the counter made by the range type's copy constructor,T(counter). Once decoupled, captures hold the value the developer expects with no escape analysis required for correctness (a dead copy is later elided by a Phase 12 pass).Contrast FOR-IN (
ForInGenerator): its loop variable is a reference to a REAL collection element fromiterator.next(), so it must NOT be copied — see that generator. The asymmetry is principled: FOR-RANGE variable = a loop-owned synthesised value (copy it); FOR-IN variable = a reference to a real element (leave it).Pattern: RELEASE (drop previous iteration's object, NULL-safe on first iteration) +
<init>(currentTemp)(the copy constructor: a new object holding the counter's value). Variable already registered to loop scope at declaration. Seedocs/ir-and-codegen/EK9_LOOP_VARIABLE_PER_ITERATION_SEMANTICS.md.
-