Class SwitchExpressionAsmGenerator


final class SwitchExpressionAsmGenerator extends AbstractControlFlowAsmGenerator
Specialized generator for EK9 switch expression form. Handles CONTROL_FLOW_CHAIN with chain_type: "SWITCH_EXPRESSION".

EK9 Switch Expression Pattern:

result <- switch value
  <- rtn as String: "Unknown"
  case 1
    rtn: "One"
  case 2
    rtn: "Two"
  default
    rtn: "Other"

Key Differences from Switch Statement:

  • Has return variable declared with returningParam (<- rtn as Type: defaultValue)
  • Each case body stores result into return variable
  • Default case also stores into return variable
  • Return variable transferred to result variable after switch completes

IR Structure:

CONTROL_FLOW_CHAIN [chain_type: "SWITCH_EXPRESSION"]
  return_variable: rtn
  return_variable_type: org.ek9.lang::String
  return_variable_setup:
    [REFERENCE rtn, LOAD_LITERAL "Unknown", RETAIN, SCOPE_REGISTER, STORE rtn, RETAIN rtn]
  evaluation_variable: _temp3 (switch value)
  condition_chain:
    [case 1: LITERAL check]
      condition_evaluation: [load value, compare with 1]
      body_evaluation: [SCOPE_ENTER, LOAD_LITERAL "One", RELEASE rtn, STORE rtn, RETAIN rtn, SCOPE_EXIT]
      body_result: rtn
    [case 2: LITERAL check]
      ...
  default_body_evaluation:
    [SCOPE_ENTER, LOAD_LITERAL "Other", RELEASE rtn, STORE rtn, RETAIN rtn, SCOPE_EXIT]
  default_result: rtn
  result: rtn (overall result variable)

Bytecode Pattern (Sequential Evaluation):

; Return variable setup (initialize with default value)
[return_variable_setup instructions]

; Evaluation variable setup (switch expression)
[evaluation variable already loaded by AssignmentExprInstrGenerator]

; Case 1
[condition evaluation]
iload primitive_condition
ifeq case_2                    ; Branch if false
[case 1 body - stores into rtn]
goto end                       ; Exit switch

case_2:
[condition evaluation]
iload primitive_condition
ifeq default_label             ; Branch if false
[case 2 body - stores into rtn]
goto end

default_label:
[default body - stores into rtn]
                               ; Fall through to end

end:
; rtn now holds the result value
; Ownership transfer happens in AssignmentExprInstrGenerator:
;   STORE _temp1, rtn
;   RELEASE rtn
;   RETAIN _temp1
;   SCOPE_REGISTER _temp1

Stack Frame Invariant: All paths arrive at 'end' label with empty stack. Result is in the return variable (rtn), ready for ownership transfer.

Design Note: Like switch statement, uses sequential evaluation (if/else-if pattern) rather than JVM tableswitch/lookupswitch for rich operator semantics and type flexibility.

  • Constructor Details

  • Method Details

    • generate

      public void generate(ControlFlowChainInstr instr)
      Generate bytecode for switch expression.

      Control Flow:

      1. Return variable setup already processed (happens before CONTROL_FLOW_CHAIN)
      2. For each case: evaluate condition, branch if false, execute body, jump to end
      3. Process default case (updates return variable)
      4. Place end label where all paths converge

      Stack Frame Invariant: Pre-condition: stack is empty Post-condition: stack is empty (result in return variable)

      NOTE: Return variable setup (rtn initialization with default value) happens in IR generation before this CONTROL_FLOW_CHAIN instruction. Those instructions are already processed by the time we reach this generator. See AssignmentExprInstrGenerator where processSwitchExpression() calls the switch statement generator.

      Parameters:
      instr - CONTROL_FLOW_CHAIN instruction with SWITCH_EXPRESSION type