// File: /workspace/github_c_makefile_star2_O0/vtereshkov[P]umka-lang/src/umka_stmt.c
// Function: parseExprSwitchStmt
static void parseExprSwitchStmt(Compiler *comp)
{
    lexEat(&comp->lex, TOK_SWITCH);

    // Additional scope embracing shortVarDecl and statement body
    blocksEnter(&comp->blocks);

    // [shortVarDecl ";"]
    if (doShortVarDeclLookahead(comp))
    {
        parseShortVarDecl(comp);
        lexEat(&comp->lex, TOK_SEMICOLON);
    }

    // expr
    const Type *type = NULL;
    parseExpr(comp, &type, NULL);
    if (!typeOrdinal(type))
        comp->error.handler(comp->error.context, "Ordinal type expected");

    genSwitchCondEpilog(&comp->gen);

    // "{" {exprCase} "}"
    lexEat(&comp->lex, TOK_LBRACE);

    int numCases = 0;
    ConstArray existingConstants;
    constArrayAlloc(&existingConstants, &comp->storage, type);

    while (comp->lex.tok.kind == TOK_CASE)
    {
        parseExprCase(comp, type, &existingConstants);
        numCases++;
    }

    // [default]
    if (comp->lex.tok.kind == TOK_DEFAULT)
        parseDefault(comp);

    constArrayFree(&existingConstants);

    lexEat(&comp->lex, TOK_RBRACE);

    genSwitchEpilog(&comp->gen, numCases);

    // Additional scope embracing shortVarDecl and statement body
    doGarbageCollection(comp);
    identWarnIfUnusedAll(&comp->idents, blocksCurrent(&comp->blocks));
    blocksLeave(&comp->blocks);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x12, %esi
callq 0x1b150
movq -0x8(%rbp), %rdi
addq $0x4220, %rdi           # imm = 0x4220
callq 0x5e60
movq -0x8(%rbp), %rdi
callq 0x1f910
testb $0x1, %al
jne 0x1fe90
jmp 0x1feae
movq -0x8(%rbp), %rdi
callq 0xa8f0
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x40, %esi
callq 0x1b150
movq $0x0, -0x10(%rbp)
movq -0x8(%rbp), %rdi
leaq -0x10(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0xe8c0
movq -0x10(%rbp), %rdi
callq 0x20340
testb $0x1, %al
jne 0x1fef5
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
leaq 0x1b9c74(%rip), %rsi    # 0x1d9b65
movb $0x0, %al
callq *%rcx
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x18700
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x3c, %esi
callq 0x1b150
movl $0x0, -0x14(%rbp)
movq -0x8(%rbp), %rsi
addq $0xf0, %rsi
movq -0x10(%rbp), %rdx
leaq -0x38(%rbp), %rdi
callq 0x96b0
movq -0x8(%rbp), %rax
cmpl $0x2, 0x4bd0(%rax)
jne 0x1ff62
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
leaq -0x38(%rbp), %rdx
callq 0x20360
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x1ff39
movq -0x8(%rbp), %rax
cmpl $0x5, 0x4bd0(%rax)
jne 0x1ff78
movq -0x8(%rbp), %rdi
callq 0x202a0
leaq -0x38(%rbp), %rdi
callq 0x98a0
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x3d, %esi
callq 0x1b150
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl -0x14(%rbp), %esi
callq 0x18840
movq -0x8(%rbp), %rdi
callq 0x1d3a0
movq -0x8(%rbp), %rax
addq $0x4e38, %rax           # imm = 0x4E38
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4220, %rdi           # imm = 0x4220
callq 0x6020
movq -0x40(%rbp), %rdi
movl %eax, %esi
callq 0x1a7e0
movq -0x8(%rbp), %rdi
addq $0x4220, %rdi           # imm = 0x4220
callq 0x5fa0
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)