Class IRGenerationContext
This context provides stack-based scope management that eliminates parameter threading throughout the IR generation process. It manages the transient stack of scope contexts, provides debug information management, and handles instruction building coordination.
Like SymbolsAndScopes, this class provides the shared state management that allows focused helpers to work together cleanly without complex parameter passing.
-
Constructor Summary
ConstructorsConstructorDescriptionIRGenerationContext(IRContext irContext) Create a new IR generation context with existing IRContext.IRGenerationContext(IRContext irContext, CoverageProbePlacer sharedProbePlacer) Create a new IR generation context with optional shared CoverageProbePlacer. -
Method Summary
Modifier and TypeMethodDescriptionvoidaddInstruction(IRInstr instruction) Add instruction to current instruction list.voidaddInstructions(List<IRInstr> instructions) Add multiple instructions to current instruction list.voidClear current instruction list.createDebugInfo(org.antlr.v4.runtime.Token token) Create debug info from an ANTLR token.createDebugInfo(org.antlr.v4.runtime.tree.ParseTree ctx) Create debug info from a parse context.createDebugInfo(Ek9Token token) Create debug info from a token.createDebugInfo(IToken token) Create debug info from an EK9 IToken.createDebugInfoAlways(org.antlr.v4.runtime.Token token) Create debug info ALWAYS, regardless of debug mode flag.createDebugInfoAlways(org.antlr.v4.runtime.tree.ParseTree ctx) Create debug info ALWAYS from a parse context, regardless of debug mode flag.Get current debug info from the stack.Get current frame type.Get current scope ID from the stack.voidenterMethodScope(String scopeId, DebugInfo debugInfo, IRFrameType frameType) Enter a method/function scope with fresh IRContext for counter isolation.voidenterScope(String scopeId, DebugInfo debugInfo, IRFrameType frameType) Enter a new IR scope context.voidExit the current IR scope.Get current instruction list and clear it.Navigate back up stack to find aggregate frame.findFrameOfType(IRFrameType frameType) Navigate back up stack to find frame of specific type.Navigate back up stack to find method or function frame.generateBlockLabel(String prefix) Generate a unique block label.generateLabelName(String prefix) Generate a unique label name.generateScopeId(String prefix) Generate a unique scope identifier.Generate a unique temporary variable name.Get the compiler flags from IRContext.Get the coverage probe placer for inserting coverage instrumentation.Get current instruction list without clearing.Get current IRContext from stack frame (traverses up to find method-level IRContext).Get the underlying IR context.Get the IR generation stack (for advanced operations).Get the parsed module from IRContext.intGet current stack depth (for debugging).booleanCheck if current scope has left-hand side.booleanCheck if coverage instrumentation is enabled.booleanisInFrameType(IRFrameType frameType) Check if we're currently in a specific frame type.booleanneedsResultVariable(String returnType) Check if we need a result variable for the current context.resolveScopeTypeName(IScope scope) resolveTypeName(ISymbol)for an owning SCOPE that is usually - but not always - a symbol (a method's parent scope, giving the type the method is emitted on).resolveTypeName(ISymbol typeSymbol) THE "what concrete type name does this (possibly conceptual) type have inside the current Scenario-3 monomorphisation?" step - use this, and never re-derive a variant.voidSet the active Scenario 3 substitution for parameterized type IR generation.
-
Constructor Details
-
IRGenerationContext
Create a new IR generation context with existing IRContext. Creates a new CoverageProbePlacer for this module. Use the overload with CoverageProbePlacer for shared module-level coverage tracking. -
IRGenerationContext
Create a new IR generation context with optional shared CoverageProbePlacer. This allows multiple constructs in a module to share probe ID numbering.- Parameters:
irContext- The IR context for this generation scopesharedProbePlacer- Optional shared probe placer; if null, a new one is created
-
-
Method Details
-
enterScope
Enter a new IR scope context. -
enterMethodScope
Enter a method/function scope with fresh IRContext for counter isolation. Creates new IRContext via copy constructor to ensure fresh temp var and label counters. -
exitScope
public void exitScope()Exit the current IR scope. -
currentScopeId
Get current scope ID from the stack. -
currentDebugInfo
-
hasLeftHandSide
public boolean hasLeftHandSide()Check if current scope has left-hand side. -
currentFrameType
Get current frame type. -
createDebugInfo
Create debug info from a parse context. -
createDebugInfo
-
createDebugInfo
Create debug info from an ANTLR token. -
createDebugInfo
-
createDebugInfoAlways
Create debug info ALWAYS, regardless of debug mode flag. Used for require/assert statements where source location is essential for error reporting in production, not just debugging. -
createDebugInfoAlways
Create debug info ALWAYS from a parse context, regardless of debug mode flag. Used for require/assert statements where source location is essential for error reporting in production, not just debugging. -
getCurrentIRContext
Get current IRContext from stack frame (traverses up to find method-level IRContext). Always creates a fresh IRContext for proper counter isolation if none exists. -
generateTempName
Generate a unique temporary variable name. -
generateScopeId
-
generateBlockLabel
-
generateLabelName
-
addInstruction
Add instruction to current instruction list. -
addInstructions
-
extractInstructions
-
getCurrentInstructions
-
clearInstructions
public void clearInstructions()Clear current instruction list. -
needsResultVariable
Check if we need a result variable for the current context. -
findFrameOfType
Navigate back up stack to find frame of specific type. -
findMethodOrFunctionFrame
Navigate back up stack to find method or function frame. -
findAggregateFrame
Navigate back up stack to find aggregate frame. -
isInFrameType
Check if we're currently in a specific frame type. -
getParsedModule
Get the parsed module from IRContext. -
getCompilerFlags
Get the compiler flags from IRContext. -
getIRContext
Get the underlying IR context. -
getIRGenerationStack
Get the IR generation stack (for advanced operations). -
getStackDepth
public int getStackDepth()Get current stack depth (for debugging). -
getCoverageProbePlacer
Get the coverage probe placer for inserting coverage instrumentation.The placer is always available, but only inserts probes when coverage is enabled in compiler flags. This allows generator code to unconditionally call probe methods without checking coverage state.
-
isCoverageEnabled
public boolean isCoverageEnabled()Check if coverage instrumentation is enabled. -
setTypeParameterMapping
Set the active Scenario 3 substitution for parameterized type IR generation.The mapping pairs the generic type's conceptual 'type parameters' with the concrete 'type arguments' it was parameterized with, positionally and by symbol - the SAME
PositionalConceptualLookupMapping.Mappingphase 6TypeSubstitutionuses, so both phases substitute identically.- Parameters:
typeMapping- The conceptual to concrete mapping, or null to clear
-
resolveTypeName
THE "what concrete type name does this (possibly conceptual) type have inside the current Scenario-3 monomorphisation?" step - use this, and never re-derive a variant.Scenario 3 generates a parameterized type's method BODIES by walking the GENERIC type's AST (there is only one AST, shared by every parameterization), so every symbol recorded against that AST carries TEMPLATE types - a bare
T, or a dependent parameterisation such asList of Tand theIterator of Tthat itsiterator()returns. Each must be re-pointed at its concrete counterpart before it is emitted. Signatures and fields need none of this: those come from the parameterized symbol itself, already substituted by phase 6.This MUST take the type SYMBOL, never its name. A parameterised type's fully qualified name is a one-way SHA-256 digest (
_List_<hash over Box::T>), so a template name cannot be decomposed - a name-to-name lookup silently returns the TEMPLATE name and leaks a class that is never generated into the emitted IR (NoClassDefFoundError, or NoSuchMethodError where it leaks into a call's return type).ConceptualTypeReplacementdoes the substitution structurally, from symbols.- Parameters:
typeSymbol- The (possibly conceptual) type symbol- Returns:
- The concrete type FQN to emit
-
resolveScopeTypeName
resolveTypeName(ISymbol)for an owning SCOPE that is usually - but not always - a symbol (a method's parent scope, giving the type the method is emitted on). Kept here rather than repeated at each call site so the symbol form, and hence the structural substitution, is never skipped.- Parameters:
scope- The scope naming the owning type- Returns:
- The concrete type FQN to emit
-