SELECT CASE

Syntax

Syntax: SELECT CASE expr : CASE value [, value] [, min TO max] : ... : [CASE ELSE : ...] : END SELECT
Source: pb_cg_emit_select (pb_codegen.c:5550)

Description

Branches execution based on the value of a selector expression. Each CASE clause tests the selector against one or more values. Unlike a chain of IF/ELSEIF statements, the selector expression is evaluated only once. Supports single value matches, comma-separated multiple values, and range matching with min TO max. CASE ELSE provides a default path when no other case matches.

Parameters

ParameterDescription
exprThe selector expression, evaluated once at the start. Must be a numeric or string type.
CASE valueA single value to match against the selector. Multiple values can be comma-separated: CASE 1, 3, 5.
CASE min TO maxA range of values (inclusive). Matches when min <= expr <= max. Example: CASE 80 TO 89.
CASE ELSEOptional catch-all. Executes when no other CASE matches.
END SELECTTerminates the SELECT CASE block.

Example

FUNCTION PBMAIN() AS LONG
    LOCAL grade AS LONG
    grade = 85
    
    ' Grade classification
    SELECT CASE grade
        CASE 90 TO 100
            PRINT "Grade: A"
        CASE 80 TO 89
            PRINT "Grade: B"
        CASE 70 TO 79
            PRINT "Grade: C"
        CASE 60 TO 69
            PRINT "Grade: D"
        CASE 0 TO 59
            PRINT "Grade: F"
        CASE ELSE
            PRINT "Invalid grade!"
    END SELECT
    
    FUNCTION = 0
END FUNCTION

Generated Assembly

; Evaluate selector expression -> RAX
mov    [rbp - select_value_offset], rax  ; save selector

; For each CASE branch:
mov    rax, [rbp - select_value_offset]  ; reload selector
mov    r10, <case_value>                 ; first case value
cmp    rax, r10
jne    __pb_select_next1_N              ; skip if no match
; ... CASE body ...
jmp    __pb_select_end_N                ; done

__pb_select_next1_N:                    ; next case label
mov    rax, [rbp - select_value_offset]
mov    r10, <case_value2>
cmp    rax, r10
jne    __pb_select_next2_N
; ... body ...
jmp    __pb_select_end_N

; For range CASE (min TO max):
__pb_select_next2_N:
mov    rax, [rbp - select_value_offset]
cmp    rax, <range_min>
jl     __pb_select_next3_N              ; below range
cmp    rax, <range_max>
jg     __pb_select_next3_N              ; above range
; ... range body ...
jmp    __pb_select_end_N

; CASE ELSE:
__pb_select_next3_N:
; ... default body ...

__pb_select_end_N: