Class LoopGuardHelper
Provides reusable guard handling for:
- WHILE and DO-WHILE loops
- FOR-RANGE loops
- FOR-IN loops
- TRY statements
All constructs use the same guard pattern:
- Enter guard scope
- Guard setup (evaluates expression, assigns to variable)
- Guard entry check (IS_NULL + _isSet produces Boolean)
- IF (entry check passes) { inner_body }
- Exit guard scope
Supports all 4 guard operators:
<-(Declaration): Creates new variable, WITH guard check:=(Assignment): Assigns to existing variable, NO guard check:=?(Assignment If Unset): Assigns if unset, WITH guard check?=(Guarded Assignment): Assigns and checks result, WITH guard check
-
Field Summary
Fields inherited from class AbstractGenerator
debugInfoCreator, instructionBuilder, stackContext, typeNameOrException -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionevaluateGuardVariable(EK9Parser.PreFlowStatementContext preFlowStmt, String guardScopeId) Evaluate guard variable for control flow constructs.wrapBodyWithGuardEntryCheck(GuardVariableDetails guardDetails, List<IRInstr> bodyInstructions, String guardScopeId, DebugInfo debugInfo) Wrap body instructions in an IF_ELSE_IF that checks the guard entry condition.wrapChainWithGuardEntryCheck(GuardVariableDetails guardDetails, ControlFlowChainDetails chainDetails, String guardScopeId, DebugInfo debugInfo) Wrap a ControlFlowChainDetails (loop or try) in an IF_ELSE_IF that checks the guard entry condition.wrapExpressionFormWithGuardEntryCheck(GuardVariableDetails guardDetails, List<IRInstr> returnVariableSetup, List<IRInstr> bodyInstructionsWithoutRtn, String guardScopeId, DebugInfo debugInfo) Wrap body instructions in an IF_ELSE_IF for EXPRESSION FORM with return variable.
-
Constructor Details
-
LoopGuardHelper
-
-
Method Details
-
evaluateGuardVariable
public GuardVariableDetails evaluateGuardVariable(EK9Parser.PreFlowStatementContext preFlowStmt, String guardScopeId) Evaluate guard variable for control flow constructs. Supports all guard forms (same as IF statements):<-(Declaration):while value <- getValue() then condition:=(Assignment):while value := getValue() then condition- NO guard check:=?(Assignment If Unset):while value :=? getValue() then condition?=(Guarded Assignment):while value ?= getValue() then condition
Guard is evaluated ONCE before the construct body executes (not on each iteration for loops). Guard variable is scoped to the entire construct and available in body.
For loops and TRY, this also generates the guard ENTRY CHECK - the IS_NULL + _isSet() evaluation that happens ONCE at entry. If the check fails, the entire body is skipped.
NOTE: For
:=(blind assignment), NO entry check is generated since the operator doesn't require guard validation - it's just an assignment before the body.- Parameters:
preFlowStmt- preFlowStatement context with guard (may be null)guardScopeId- Scope ID where guard variable lives- Returns:
- GuardVariableDetails with guard info including entry check, or GuardVariableDetails.none() if no guard
-
wrapBodyWithGuardEntryCheck
public List<IRInstr> wrapBodyWithGuardEntryCheck(GuardVariableDetails guardDetails, List<IRInstr> bodyInstructions, String guardScopeId, DebugInfo debugInfo) Wrap body instructions in an IF_ELSE_IF that checks the guard entry condition.Structure:
- SCOPE_ENTER (guard scope)
- Guard setup (assignment)
- Guard entry check (IS_NULL + _isSet)
- IF (entry check passes) { body }
- SCOPE_EXIT (guard scope)
- Parameters:
guardDetails- Guard variable details with entry check infobodyInstructions- The body instructions to wrap (loop or try block)guardScopeId- The scope ID for the guarddebugInfo- Debug information- Returns:
- Instructions with guard wrapper
-
wrapChainWithGuardEntryCheck
public List<IRInstr> wrapChainWithGuardEntryCheck(GuardVariableDetails guardDetails, ControlFlowChainDetails chainDetails, String guardScopeId, DebugInfo debugInfo) Wrap a ControlFlowChainDetails (loop or try) in an IF_ELSE_IF that checks the guard entry condition.This is a convenience method for wrapping CONTROL_FLOW_CHAIN instructions.
- Parameters:
guardDetails- Guard variable details with entry check infochainDetails- The control flow chain to wrapguardScopeId- The scope ID for the guarddebugInfo- Debug information- Returns:
- Instructions with guard wrapper
-
wrapExpressionFormWithGuardEntryCheck
public List<IRInstr> wrapExpressionFormWithGuardEntryCheck(GuardVariableDetails guardDetails, List<IRInstr> returnVariableSetup, List<IRInstr> bodyInstructionsWithoutRtn, String guardScopeId, DebugInfo debugInfo) Wrap body instructions in an IF_ELSE_IF for EXPRESSION FORM with return variable.CRITICAL: For expression forms, the return variable must be initialized OUTSIDE the IF wrapper so the variable exists on all code paths (including when guard fails). This prevents JVM VerifyError "Bad local variable type" when accessing the return variable after the IF.
Structure:
- SCOPE_ENTER (guard scope)
- Guard setup (assignment)
- Guard entry check (IS_NULL + _isSet)
- Return variable setup (OUTSIDE IF - always executed)
- IF (entry check passes) { body only }
- SCOPE_EXIT (guard scope)
- Parameters:
guardDetails- Guard variable details with entry check inforeturnVariableSetup- Return variable initialization instructions (expression form)bodyInstructionsWithoutRtn- Body instructions WITHOUT return variable setupguardScopeId- The scope ID for the guarddebugInfo- Debug information- Returns:
- Instructions with guard wrapper and properly placed return variable
-