// File: /workspace/github_c_makefile_star2_O0/vtereshkov[P]umka-lang/src/umka_stmt.c
// Function: parseTypeSwitchStmt
static void parseTypeSwitchStmt(Compiler *comp)
{
    lexEat(&comp->lex, TOK_SWITCH);

    // Additional scope embracing ident and statement body
    blocksEnter(&comp->blocks);

    // ident
    lexCheck(&comp->lex, TOK_IDENT);
    IdentName concreteVarName;
    strcpy(concreteVarName, comp->lex.tok.name);
    lexNext(&comp->lex);

    // ":=" "type" "("
    lexEat(&comp->lex, TOK_COLONEQ);
    lexEat(&comp->lex, TOK_TYPE);
    lexEat(&comp->lex, TOK_LPAR);

    // expr
    const Type *type = NULL;
    parseExpr(comp, &type, NULL);
    if (type->kind != TYPE_INTERFACE)
        comp->error.handler(comp->error.context, "Interface type expected");

    // ")"
    lexEat(&comp->lex, TOK_RPAR);

    // "{" {typeCase} "}"
    lexEat(&comp->lex, TOK_LBRACE);

    int numCases = 0;
    ConstArray existingConcreteTypes;
    constArrayAlloc(&existingConcreteTypes, &comp->storage, comp->ptrVoidType);

    while (comp->lex.tok.kind == TOK_CASE)
    {
        parseTypeCase(comp, concreteVarName, &existingConcreteTypes);
        numCases++;
    }

    // [default]
    if (comp->lex.tok.kind == TOK_DEFAULT)
        parseDefault(comp);

    constArrayFree(&existingConcreteTypes);

    lexEat(&comp->lex, TOK_RBRACE);

    genSwitchEpilog(&comp->gen, numCases);

    genPop(&comp->gen);     // Remove expr

    // Additional scope embracing ident and statement body
    doGarbageCollection(comp);
    identWarnIfUnusedAll(&comp->idents, blocksCurrent(&comp->blocks));
    blocksLeave(&comp->blocks);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x150, %rsp            # imm = 0x150
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
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x45, %esi
callq 0x1b080
leaq -0x110(%rbp), %rdi
movq -0x8(%rbp), %rsi
addq $0x4ba8, %rsi           # imm = 0x4BA8
addq $0x28, %rsi
addq $0x8, %rsi
callq 0x30a0
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
callq 0x1ad90
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x37, %esi
callq 0x1b150
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x13, %esi
callq 0x1b150
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x38, %esi
callq 0x1b150
movq $0x0, -0x118(%rbp)
movq -0x8(%rbp), %rdi
leaq -0x118(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0xe8c0
movq -0x118(%rbp), %rax
cmpl $0x17, (%rax)
je 0x1fd13
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
leaq 0x1b863a(%rip), %rsi    # 0x1d8349
movb $0x0, %al
callq *%rcx
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x39, %esi
callq 0x1b150
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x3c, %esi
callq 0x1b150
movl $0x0, -0x11c(%rbp)
movq -0x8(%rbp), %rsi
addq $0xf0, %rsi
movq -0x8(%rbp), %rax
movq 0x5298(%rax), %rdx
leaq -0x140(%rbp), %rdi
callq 0x96b0
movq -0x8(%rbp), %rax
cmpl $0x2, 0x4bd0(%rax)
jne 0x1fd9e
movq -0x8(%rbp), %rdi
leaq -0x110(%rbp), %rsi
leaq -0x140(%rbp), %rdx
callq 0x20000
movl -0x11c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x11c(%rbp)
jmp 0x1fd69
movq -0x8(%rbp), %rax
cmpl $0x5, 0x4bd0(%rax)
jne 0x1fdb4
movq -0x8(%rbp), %rdi
callq 0x202a0
leaq -0x140(%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 -0x11c(%rbp), %esi
callq 0x18840
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x16d30
movq -0x8(%rbp), %rdi
callq 0x1d3a0
movq -0x8(%rbp), %rax
addq $0x4e38, %rax           # imm = 0x4E38
movq %rax, -0x148(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4220, %rdi           # imm = 0x4220
callq 0x6020
movq -0x148(%rbp), %rdi
movl %eax, %esi
callq 0x1a7e0
movq -0x8(%rbp), %rdi
addq $0x4220, %rdi           # imm = 0x4220
callq 0x5fa0
addq $0x150, %rsp            # imm = 0x150
popq %rbp
retq
nopl (%rax)