Class ElvisCoalescingOperatorAsmGenerator
java.lang.Object
org.ek9lang.compiler.backend.jvm.AbstractAsmGenerator
org.ek9lang.compiler.backend.jvm.AbstractControlFlowAsmGenerator
org.ek9lang.compiler.backend.jvm.ElvisCoalescingOperatorAsmGenerator
Specialized generator for EK9 Elvis coalescing operator (:?).
Handles CONTROL_FLOW_CHAIN with chain_type: "ELVIS_COALESCING_OPERATOR".
EK9 Elvis Coalescing Operator Pattern: lhs :? rhs
- If LHS is null → returns RHS
- If LHS is not null BUT unset → returns RHS
- If LHS is not null AND set → returns LHS
Key Difference from Null Coalescing (??):
- ?? checks ONLY null (IS_NULL instruction) - 1 case
- :? checks BOTH null AND set (IS_NULL + IS_SET instructions) - 2 cases
IR Structure:
CONTROL_FLOW_CHAIN [chain_type: "ELVIS_COALESCING_OPERATOR"]
condition_chain:
[case 1: case_type: "NULL_CHECK"]
condition_evaluation: [LOAD lhs, IS_NULL lhs]
primitive_condition: temp_is_null
body_evaluation: [LOAD rhs] // Returns RHS if null
body_result: rhs
[case 2: case_type: "EXPRESSION"]
condition_evaluation: [CALL lhs._isSet(), CALL result._false()]
condition_result: isSetResult (EK9 Boolean)
primitive_condition: invertedPrimitive (NOT set)
body_evaluation: [LOAD rhs] // Returns RHS if unset
body_result: rhs
default_body_evaluation: [] // LHS already evaluated
default_result: lhs
Safety: NULL_CHECK always precedes _isSet() call to prevent accessing unallocated memory.
Stack Frame Invariant: All paths arrive at 'end' label with empty stack. Result is stored in local variable (overall_result).
-
Nested Class Summary
Nested classes/interfaces inherited from class AbstractAsmGenerator
AbstractAsmGenerator.LocalVariableInfo, AbstractAsmGenerator.MethodContext, AbstractAsmGenerator.ScopeInfo, AbstractAsmGenerator.TempVariableSource -
Field Summary
Fields inherited from class AbstractControlFlowAsmGenerator
contextFields inherited from class AbstractAsmGenerator
classWriter, constructTargetTuple, outputVisitor -
Constructor Summary
ConstructorsConstructorDescriptionElvisCoalescingOperatorAsmGenerator(ConstructTargetTuple constructTargetTuple, OutputVisitor outputVisitor, org.objectweb.asm.ClassWriter classWriter, BytecodeGenerationContext context) -
Method Summary
Modifier and TypeMethodDescriptionvoidgenerate(ControlFlowChainInstr instr) Generate bytecode for Elvis coalescing operator (:?).Methods inherited from class AbstractControlFlowAsmGenerator
branchIfFalse, branchIfTrue, copyResultVariable, createControlFlowLabel, jumpTo, placeLabel, processBodyEvaluation, processConditionCase, processConditionCaseWithoutLabelPlacement, processConditionEvaluation, processInstructionsMethods inherited from class AbstractAsmGenerator
convertToJvmDescriptor, convertToJvmName, extractFieldName, generateBooleanLiteral, generateCharacterLiteral, generateDebugInfo, generateFloatLiteral, generateIntegerLiteral, generateLoadVariable, generateLocalVariableTable, generateMethodDescriptor, generateObjectLiteral, generateStackOperation, generateStoreVariable, generateStringLiteral, getCurrentMethodVisitor, getFieldDescriptor, getMethodContext, getOrCreateLabel, getOwnerClassName, getVariableIndex, isFieldAccess, isVariableAllocated, setCurrentMethodVisitor, setSharedMethodContext, trackTempVariableFromLiteral, trackTempVariableFromLoad
-
Constructor Details
-
ElvisCoalescingOperatorAsmGenerator
ElvisCoalescingOperatorAsmGenerator(ConstructTargetTuple constructTargetTuple, OutputVisitor outputVisitor, org.objectweb.asm.ClassWriter classWriter, BytecodeGenerationContext context)
-
-
Method Details
-
generate
Generate bytecode for Elvis coalescing operator (:?).Bytecode Pattern:
// Case 1: Check if LHS is null ALOAD lhs_index IFNONNULL not_null_label // NULL case: load RHS ALOAD rhs_index ASTORE result_index GOTO end_label not_null_label: // Case 2: Check if LHS is set (safe because not null) ALOAD lhs_index INVOKEVIRTUAL _isSet() INVOKEVIRTUAL _false() // Inverted: if NOT set ILOAD invertedPrimitive_index IFEQ is_set_label // UNSET case: load RHS ALOAD rhs_index ASTORE result_index GOTO end_label is_set_label: // SET case: load LHS ALOAD lhs_index ASTORE result_index end_label: // result now holds correct value
Stack Frame Invariant: Pre-condition: stack is empty Post-condition: stack is empty (result in local variable)
- Parameters:
instr- CONTROL_FLOW_CHAIN instruction with ELVIS_COALESCING_OPERATOR type
-