// File: fondoger[P]C0-Compiler/src/grammar.cpp
// Function: pCaseItem(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, DataType const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
static void pCaseItem(const std::string &switched_val, 
        const DataType &switched_dtype,
        const std::string &end_label)
{
    // TODO: default clause must be behind of case clause, 
    // which is prescribed by C0 grammar rules.
    // TODO: values in cases can't be equal
    // TODO: might sort case item's and apply binary search
    // to improve switch-case's performance.
    std::string cased_val;
    DataType cased_dtype;
    std::string case_label = genLabel();

    test3(Symset({CASESY, DEFAULTSY}));
    if (g_sym == CASESY) {
        readSymbol();
        // cased-value must be int or char literal, can't be 
        // const identifier
        test3(Symset({CHARVALUE, MINUS, PLUS, INTVALUE}));
        if (g_sym == CHARVALUE) {
            std::stringstream ss;
            ss << "\'" << g_char << "\'";
            cased_val = ss.str();
            cased_dtype = DT_CHAR;
            readSymbol();
        } else { // g_sym == INTVALUE
            pSignedInteger();
            cased_val = std::to_string(g_num);
            cased_dtype = DT_INT;
        }
        if (switched_dtype != cased_dtype) {
            error(ERR_SWITCH_TYPE_NOT_MATCH);
            std::stringstream ss;
            ss << "$witched=" << switched_val << "(" << dtype2str[switched_dtype]
               << ") $cased=" << cased_val << "(" << dtype2str[cased_dtype]
               << ")" << std::endl;
            error(ss.str());
            return;
        }
        test3(Symset({COLON}));
        readSymbol();
        case_label = genLabel();
        // generate if...goto... without cache
        // TODO: optimize switch, we don't have to load
        // switched_val every time when compare 
        genMidCode(COMPARE, switched_val, tokens[EQL], cased_val);
        genMidCode(BNZ, case_label, NONE, NONE);
        // generate labels and statements body in cache stack
        startCachingMidCode();
        genMidCode(LABEL, case_label, NONE, NONE); 
        pStatement();
        genMidCode(GOTO, end_label, NONE, NONE);
        // stop cache
        pauseCachingMidCode();

    } else {
        // default:
        readSymbol();
        test3(Symset({COLON}));
        readSymbol();
        // this label is not necessary, but it improves
        // readability of generated mid code and final 
        // mips code.
        case_label = genLabel();
        genMidCode(LABEL, case_label, NONE, NONE);
        // no cache for default clause
        pStatement();
        genMidCode(GOTO, end_label, NONE, NONE);
    }

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x680, %rsp            # imm = 0x680
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x3450
leaq -0x60(%rbp), %rdi
callq 0x272a0
jmp 0x2165b
jmp 0x2165d
movl $0xa, -0x90(%rbp)
movl $0xb, -0x8c(%rbp)
leaq -0x90(%rbp), %rax
movq %rax, -0x88(%rbp)
movq $0x2, -0x80(%rbp)
movq -0x88(%rbp), %rsi
movq -0x80(%rbp), %rdx
leaq -0x78(%rbp), %rdi
callq 0x227f0
jmp 0x2169d
movl $0x22, -0xb0(%rbp)
movl $0x26, -0xac(%rbp)
leaq -0xb0(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq $0x2, -0xa0(%rbp)
movq -0xa8(%rbp), %rsi
movq -0xa0(%rbp), %rdx
leaq -0x98(%rbp), %rdi
callq 0x227f0
jmp 0x216e6
movq -0x78(%rbp), %rdi
movq -0x98(%rbp), %rsi
callq 0x18170
jmp 0x216f8
movl $0xa, -0xd0(%rbp)
movl $0xb, -0xcc(%rbp)
leaq -0xd0(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq $0x2, -0xc0(%rbp)
movq -0xc8(%rbp), %rsi
movq -0xc0(%rbp), %rdx
leaq -0xb8(%rbp), %rdi
callq 0x227f0
jmp 0x21741
leaq 0x29f68(%rip), %rax     # 0x4b6b0
movl (%rax), %esi
leaq -0xb8(%rbp), %rdi
callq 0x18b40
xorb $-0x1, %al
testb $0x1, %al
jne 0x2175e
jmp 0x21796
callq 0x2e050
jmp 0x21765
movl $0x1, -0xd4(%rbp)
jmp 0x2202b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x2204f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x22046
jmp 0x21798
jmp 0x2179a
leaq 0x29f0f(%rip), %rax     # 0x4b6b0
cmpl $0xa, (%rax)
jne 0x21e6e
callq 0x2e050
jmp 0x217b1
jmp 0x217b3
movl $0x10, -0x100(%rbp)
movl $0x14, -0xfc(%rbp)
movl $0x13, -0xf8(%rbp)
movl $0x11, -0xf4(%rbp)
leaq -0x100(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq $0x4, -0xe8(%rbp)
movq -0xf0(%rbp), %rsi
movq -0xe8(%rbp), %rdx
leaq -0xe0(%rbp), %rdi
callq 0x227f0
jmp 0x21810
movl $0x22, -0x120(%rbp)
movl $0x26, -0x11c(%rbp)
leaq -0x120(%rbp), %rax
movq %rax, -0x118(%rbp)
movq $0x2, -0x110(%rbp)
movq -0x118(%rbp), %rsi
movq -0x110(%rbp), %rdx
leaq -0x108(%rbp), %rdi
callq 0x227f0
jmp 0x21859
movq -0xe0(%rbp), %rdi
movq -0x108(%rbp), %rsi
callq 0x18170
jmp 0x2186e
movl $0x10, -0x148(%rbp)
movl $0x14, -0x144(%rbp)
movl $0x13, -0x140(%rbp)
movl $0x11, -0x13c(%rbp)
leaq -0x148(%rbp), %rax
movq %rax, -0x138(%rbp)
movq $0x4, -0x130(%rbp)
movq -0x138(%rbp), %rsi
movq -0x130(%rbp), %rdx
leaq -0x128(%rbp), %rdi
callq 0x227f0
jmp 0x218cb
leaq 0x29dde(%rip), %rax     # 0x4b6b0
movl (%rax), %esi
leaq -0x128(%rbp), %rdi
callq 0x18b40
xorb $-0x1, %al
testb $0x1, %al
jne 0x218e8
jmp 0x218fe
callq 0x2e050
jmp 0x218ef
movl $0x1, -0xd4(%rbp)
jmp 0x2202b
jmp 0x21900
jmp 0x21902
leaq 0x29da7(%rip), %rax     # 0x4b6b0
cmpl $0x10, (%rax)
jne 0x219e1
leaq -0x2d0(%rbp), %rdi
callq 0x3270
jmp 0x21920
leaq -0x2c0(%rbp), %rdi
leaq 0x1453c(%rip), %rsi     # 0x35e6a
callq 0x3300
movq %rax, -0x600(%rbp)
jmp 0x2193c
movq -0x600(%rbp), %rdi
leaq 0x29d8e(%rip), %rax     # 0x4b6d8
movsbl (%rax), %esi
callq 0x33b0
movq %rax, -0x608(%rbp)
jmp 0x2195b
movq -0x608(%rbp), %rdi
leaq 0x14501(%rip), %rsi     # 0x35e6a
callq 0x3300
jmp 0x21970
leaq -0x2f0(%rbp), %rdi
leaq -0x2d0(%rbp), %rsi
callq 0x32f0
jmp 0x21985
leaq -0x38(%rbp), %rdi
leaq -0x2f0(%rbp), %rsi
movq %rsi, -0x610(%rbp)
callq 0x33d0
movq -0x610(%rbp), %rdi
callq 0x35e8
movl $0x2, -0x3c(%rbp)
callq 0x2e050
jmp 0x219b6
leaq -0x2d0(%rbp), %rdi
callq 0x35f0
jmp 0x21a22
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0x35f0
jmp 0x22046
callq 0x20ed0
jmp 0x219e8
leaq 0x29ced(%rip), %rax     # 0x4b6dc
movl (%rax), %esi
leaq -0x310(%rbp), %rdi
callq 0x22950
jmp 0x219ff
leaq -0x38(%rbp), %rdi
leaq -0x310(%rbp), %rsi
callq 0x33d0
leaq -0x310(%rbp), %rdi
callq 0x35e8
movl $0x1, -0x3c(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %eax
cmpl -0x3c(%rbp), %eax
je 0x21c6e
leaq -0x331(%rbp), %rdi
movq %rdi, -0x618(%rbp)
callq 0x3570
movq -0x618(%rbp), %rdx
leaq 0x13dc5(%rip), %rsi     # 0x35817
leaq -0x330(%rbp), %rdi
callq 0x3440
jmp 0x21a60
leaq -0x330(%rbp), %rdi
callq 0x18620
jmp 0x21a6e
leaq -0x330(%rbp), %rdi
callq 0x35e8
leaq -0x331(%rbp), %rdi
callq 0x3370
leaq -0x4c0(%rbp), %rdi
callq 0x3270
jmp 0x21a94
leaq -0x4b0(%rbp), %rdi
leaq 0x13da5(%rip), %rsi     # 0x35847
callq 0x3300
movq %rax, -0x620(%rbp)
jmp 0x21ab0
movq -0x620(%rbp), %rdi
movq -0x8(%rbp), %rsi
callq 0x32c0
movq %rax, -0x628(%rbp)
jmp 0x21ac9
movq -0x628(%rbp), %rdi
leaq 0x13d7a(%rip), %rsi     # 0x35851
callq 0x3300
movq %rax, -0x630(%rbp)
jmp 0x21ae5
movq -0x630(%rbp), %rdi
movq -0x10(%rbp), %rax
movl (%rax), %eax
shlq $0x5, %rax
leaq 0x250e3(%rip), %rsi     # 0x46be0
addq %rax, %rsi
callq 0x32c0
movq %rax, -0x638(%rbp)
jmp 0x21b0e
movq -0x638(%rbp), %rdi
leaq 0x13d37(%rip), %rsi     # 0x35853
callq 0x3300
movq %rax, -0x640(%rbp)
jmp 0x21b2a
movq -0x640(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x32c0
movq %rax, -0x648(%rbp)
jmp 0x21b43
movq -0x648(%rbp), %rdi
leaq 0x13d00(%rip), %rsi     # 0x35851
callq 0x3300
movq %rax, -0x650(%rbp)
jmp 0x21b5f
movq -0x650(%rbp), %rdi
movl -0x3c(%rbp), %eax
shlq $0x5, %rax
leaq 0x2506c(%rip), %rsi     # 0x46be0
addq %rax, %rsi
callq 0x32c0
movq %rax, -0x658(%rbp)
jmp 0x21b85
movq -0x658(%rbp), %rdi
leaq 0x14885(%rip), %rsi     # 0x36418
callq 0x3300
movq %rax, -0x660(%rbp)
jmp 0x21ba1
movq -0x660(%rbp), %rdi
movq 0x233f9(%rip), %rsi     # 0x44fa8
callq 0x3360
jmp 0x21bb6
leaq -0x4e0(%rbp), %rdi
leaq -0x4c0(%rbp), %rsi
callq 0x32f0
jmp 0x21bcb
leaq -0x4e0(%rbp), %rdi
callq 0x18620
jmp 0x21bd9
leaq -0x4e0(%rbp), %rdi
callq 0x35e8
movl $0x1, -0xd4(%rbp)
leaq -0x4c0(%rbp), %rdi
callq 0x35f0
jmp 0x2202b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x21c26
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x330(%rbp), %rdi
callq 0x35e8
leaq -0x331(%rbp), %rdi
callq 0x3370
jmp 0x22046
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x21c5d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x4e0(%rbp), %rdi
callq 0x35e8
leaq -0x4c0(%rbp), %rdi
callq 0x35f0
jmp 0x22046
jmp 0x21c70
movl $0x25, -0x4fc(%rbp)
leaq -0x4fc(%rbp), %rax
movq %rax, -0x4f8(%rbp)
movq $0x1, -0x4f0(%rbp)
movq -0x4f8(%rbp), %rsi
movq -0x4f0(%rbp), %rdx
leaq -0x4e8(%rbp), %rdi
callq 0x227f0
jmp 0x21caf
movl $0x22, -0x520(%rbp)
movl $0x26, -0x51c(%rbp)
leaq -0x520(%rbp), %rax
movq %rax, -0x518(%rbp)
movq $0x2, -0x510(%rbp)
movq -0x518(%rbp), %rsi
movq -0x510(%rbp), %rdx
leaq -0x508(%rbp), %rdi
callq 0x227f0
jmp 0x21cf8
movq -0x4e8(%rbp), %rdi
movq -0x508(%rbp), %rsi
callq 0x18170
jmp 0x21d0d
movl $0x25, -0x53c(%rbp)
leaq -0x53c(%rbp), %rax
movq %rax, -0x538(%rbp)
movq $0x1, -0x530(%rbp)
movq -0x538(%rbp), %rsi
movq -0x530(%rbp), %rdx
leaq -0x528(%rbp), %rdi
callq 0x227f0
jmp 0x21d4c
leaq 0x2995d(%rip), %rax     # 0x4b6b0
movl (%rax), %esi
leaq -0x528(%rbp), %rdi
callq 0x18b40
xorb $-0x1, %al
testb $0x1, %al
jne 0x21d69
jmp 0x21d7f
callq 0x2e050
jmp 0x21d70
movl $0x1, -0xd4(%rbp)
jmp 0x2202b
jmp 0x21d81
jmp 0x21d83
callq 0x2e050
jmp 0x21d8a
leaq -0x560(%rbp), %rdi
callq 0x272a0
jmp 0x21d98
leaq -0x60(%rbp), %rdi
leaq -0x560(%rbp), %rsi
movq %rsi, -0x668(%rbp)
callq 0x33d0
movq -0x668(%rbp), %rdi
callq 0x35e8
movl $0x11, -0x564(%rbp)
movq -0x8(%rbp), %rsi
leaq 0x246d0(%rip), %rdx     # 0x464a0
leaq -0x564(%rbp), %rdi
leaq -0x38(%rbp), %rcx
callq 0x26340
jmp 0x21de2
movl $0x16, -0x568(%rbp)
leaq 0x2520d(%rip), %rcx     # 0x47000
leaq -0x568(%rbp), %rdi
leaq -0x60(%rbp), %rsi
movq %rcx, %rdx
callq 0x26340
jmp 0x21e08
callq 0x27090
jmp 0x21e0f
movl $0x13, -0x56c(%rbp)
leaq 0x251e0(%rip), %rcx     # 0x47000
leaq -0x56c(%rbp), %rdi
leaq -0x60(%rbp), %rsi
movq %rcx, %rdx
callq 0x26340
jmp 0x21e35
callq 0x1c2d0
jmp 0x21e3c
movl $0x14, -0x570(%rbp)
movq -0x18(%rbp), %rsi
leaq 0x251af(%rip), %rcx     # 0x47000
leaq -0x570(%rbp), %rdi
movq %rcx, %rdx
callq 0x26340
jmp 0x21e62
callq 0x270b0
jmp 0x21e69
jmp 0x22021
callq 0x2e050
jmp 0x21e75
jmp 0x21e77
movl $0x25, -0x58c(%rbp)
leaq -0x58c(%rbp), %rax
movq %rax, -0x588(%rbp)
movq $0x1, -0x580(%rbp)
movq -0x588(%rbp), %rsi
movq -0x580(%rbp), %rdx
leaq -0x578(%rbp), %rdi
callq 0x227f0
jmp 0x21eb6
movl $0x22, -0x5b0(%rbp)
movl $0x26, -0x5ac(%rbp)
leaq -0x5b0(%rbp), %rax
movq %rax, -0x5a8(%rbp)
movq $0x2, -0x5a0(%rbp)
movq -0x5a8(%rbp), %rsi
movq -0x5a0(%rbp), %rdx
leaq -0x598(%rbp), %rdi
callq 0x227f0
jmp 0x21eff
movq -0x578(%rbp), %rdi
movq -0x598(%rbp), %rsi
callq 0x18170
jmp 0x21f14
movl $0x25, -0x5cc(%rbp)
leaq -0x5cc(%rbp), %rax
movq %rax, -0x5c8(%rbp)
movq $0x1, -0x5c0(%rbp)
movq -0x5c8(%rbp), %rsi
movq -0x5c0(%rbp), %rdx
leaq -0x5b8(%rbp), %rdi
callq 0x227f0
jmp 0x21f53
leaq 0x29756(%rip), %rax     # 0x4b6b0
movl (%rax), %esi
leaq -0x5b8(%rbp), %rdi
callq 0x18b40
xorb $-0x1, %al
testb $0x1, %al
jne 0x21f70
jmp 0x21f86
callq 0x2e050
jmp 0x21f77
movl $0x1, -0xd4(%rbp)
jmp 0x2202b
jmp 0x21f88
jmp 0x21f8a
callq 0x2e050
jmp 0x21f91
leaq -0x5f0(%rbp), %rdi
callq 0x272a0
jmp 0x21f9f
leaq -0x60(%rbp), %rdi
movq %rdi, -0x670(%rbp)
leaq -0x5f0(%rbp), %rsi
movq %rsi, -0x678(%rbp)
callq 0x33d0
movq -0x678(%rbp), %rdi
callq 0x35e8
movq -0x670(%rbp), %rsi
movl $0x13, -0x5f4(%rbp)
leaq 0x2501f(%rip), %rcx     # 0x47000
leaq -0x5f4(%rbp), %rdi
movq %rcx, %rdx
callq 0x26340
jmp 0x21ff2
callq 0x1c2d0
jmp 0x21ff9
movl $0x14, -0x5f8(%rbp)
movq -0x18(%rbp), %rsi
leaq 0x24ff2(%rip), %rcx     # 0x47000
leaq -0x5f8(%rbp), %rdi
movq %rcx, %rdx
callq 0x26340
jmp 0x2201f
jmp 0x22021
movl $0x0, -0xd4(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x35e8
leaq -0x38(%rbp), %rdi
callq 0x35e8
addq $0x680, %rsp            # imm = 0x680
popq %rbp
retq
leaq -0x60(%rbp), %rdi
callq 0x35e8
leaq -0x38(%rbp), %rdi
callq 0x35e8
movq -0x68(%rbp), %rdi
callq 0x3560
nopw %cs:(%rax,%rax)