// File: fondoger[P]C0-Compiler/src/grammar.cpp
// Function: pFactor(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, DataType&)
static void pFactor(std::string &res, DataType &res_dtype)
{
    std::string id, temp_var;
    std::stringstream ss;
    TabEntry entry;
    DataType temp_dtype;
    // For conveniency, we assume all identifiers here are non-void-function-call
    test3(Symset({IDENTSY, CHARVALUE, LPARENT, PLUS, MINUS, INTVALUE}));
    switch (g_sym) {
        case IDENTSY:   id = g_id;
                        readSymbol(); 
                        if (!tabFind(id, entry)) {
                            // undefined identifier
                            error(ERR_UNDEFINED_IDENTIFIER);
                            return;
                        }
                        // entry.itype might be:
                        // IT_FUNCTION, IT_ARRAY, IT_VARIABLE, IT_CONST

                        // 1. handle functions
                        if (entry.itype == IT_FUNCTION) {
                            pNonVoidFunctionCall(res, res_dtype, id, entry);
                            return;
                        } else if (g_sym == LPARENT) { 
                            // use function call on a not-a-function identifier
                            error(ERR_NOT_A_FUNCTION);
                            return;
                        }
                        // 2. handle arrays
                        if (entry.itype == IT_ARRAY) {
                            pArrayRead(res, res_dtype, id, entry);
                            return;
                        }
                        assert(entry.itype == IT_CONST || entry.itype == IT_VARIABLE);
                        assert(entry.dtype == DT_CHAR || entry.dtype == DT_INT);
                        // 3. handle consts variable
                        if (entry.itype == IT_CONST) {
                            // return consts' character directly
                            if (entry.dtype == DT_CHAR) {
                                res_dtype = DT_CHAR;
                                ss << '\'' << (char)entry.value << '\'';
                            } else {
                                res_dtype = DT_INT;
                                ss << entry.value;
                            }
                            res = ss.str();
                        } 
                        // 4. handle normal variable (int or char)
                        else {
                            // return identifier directly
                            res = id;
                            res_dtype = entry.dtype;
                        }
                        break;
        case CHARVALUE: readSymbol();
                        ss << '\'' << g_char << '\'';
                        res = ss.str();
                        res_dtype = DT_CHAR;
                        break;
        case LPARENT:   readSymbol();
                        pExpression(res, temp_dtype);
                        res_dtype = DT_INT;           // ('p') should be convert to int
                        test3(Symset({RPARENT}));
                        readSymbol();
                        break;
        default:        pSignedInteger();  // a signed integer is stored at g_num
                        ss << g_num;
                        res = ss.str();
                        res_dtype = DT_INT;
                        break;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3e0, %rsp            # imm = 0x3E0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x3450
leaq -0x50(%rbp), %rdi
callq 0x3450
leaq -0x1d8(%rbp), %rdi
callq 0x3270
jmp 0x1fe23
jmp 0x1fe25
movups 0x15564(%rip), %xmm0    # 0x35390
movaps %xmm0, -0x230(%rbp)
movabsq $0x1100000014, %rax     # imm = 0x1100000014
movq %rax, -0x220(%rbp)
leaq -0x230(%rbp), %rax
movq %rax, -0x218(%rbp)
movq $0x6, -0x210(%rbp)
movq -0x218(%rbp), %rsi
movq -0x210(%rbp), %rdx
leaq -0x208(%rbp), %rdi
callq 0x227f0
jmp 0x1fe79
movl $0x22, -0x250(%rbp)
movl $0x26, -0x24c(%rbp)
leaq -0x250(%rbp), %rax
movq %rax, -0x248(%rbp)
movq $0x2, -0x240(%rbp)
movq -0x248(%rbp), %rsi
movq -0x240(%rbp), %rdx
leaq -0x238(%rbp), %rdi
callq 0x227f0
jmp 0x1fec2
movq -0x208(%rbp), %rdi
movq -0x238(%rbp), %rsi
callq 0x18170
jmp 0x1fed7
movups 0x154ca(%rip), %xmm0    # 0x353a8
movaps %xmm0, -0x280(%rbp)
movabsq $0x1100000014, %rax     # imm = 0x1100000014
movq %rax, -0x270(%rbp)
leaq -0x280(%rbp), %rax
movq %rax, -0x268(%rbp)
movq $0x6, -0x260(%rbp)
movq -0x268(%rbp), %rsi
movq -0x260(%rbp), %rdx
leaq -0x258(%rbp), %rdi
callq 0x227f0
jmp 0x1ff2b
leaq 0x2b77e(%rip), %rax     # 0x4b6b0
movl (%rax), %esi
leaq -0x258(%rbp), %rdi
callq 0x18b40
xorb $-0x1, %al
testb $0x1, %al
jne 0x1ff48
jmp 0x1ff8c
callq 0x2e050
jmp 0x1ff4f
movl $0x1, -0x284(%rbp)
jmp 0x2057b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1e0(%rbp)
movl %eax, -0x1e4(%rbp)
jmp 0x205ae
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1e0(%rbp)
movl %eax, -0x1e4(%rbp)
jmp 0x205a2
jmp 0x1ff8e
jmp 0x1ff90
leaq 0x2b719(%rip), %rax     # 0x4b6b0
movl (%rax), %eax
movl %eax, -0x39c(%rbp)
testl %eax, %eax
je 0x1ffca
jmp 0x1ffa5
movl -0x39c(%rbp), %eax
subl $0x10, %eax
je 0x20349
jmp 0x1ffb6
movl -0x39c(%rbp), %eax
subl $0x1d, %eax
je 0x203dc
jmp 0x20518
leaq 0x2b6e7(%rip), %rsi     # 0x4b6b8
leaq -0x30(%rbp), %rdi
callq 0x3040
jmp 0x1ffdc
callq 0x2e050
jmp 0x1ffe3
leaq -0x30(%rbp), %rdi
leaq -0x1f8(%rbp), %rsi
callq 0x2f100
movb %al, -0x39d(%rbp)
jmp 0x1fffb
movb -0x39d(%rbp), %al
testb $0x1, %al
jne 0x200b2
jmp 0x2000b
leaq -0x2a9(%rbp), %rdi
movq %rdi, -0x3a8(%rbp)
callq 0x3570
movq -0x3a8(%rbp), %rdx
leaq 0x15524(%rip), %rsi     # 0x35550
leaq -0x2a8(%rbp), %rdi
callq 0x3440
jmp 0x2003a
leaq -0x2a8(%rbp), %rdi
callq 0x18620
jmp 0x20048
leaq -0x2a8(%rbp), %rdi
callq 0x35e8
leaq -0x2a9(%rbp), %rdi
callq 0x3370
movl $0x1, -0x284(%rbp)
jmp 0x2057b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1e0(%rbp)
movl %eax, -0x1e4(%rbp)
jmp 0x200a1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1e0(%rbp)
movl %eax, -0x1e4(%rbp)
leaq -0x2a8(%rbp), %rdi
callq 0x35e8
leaq -0x2a9(%rbp), %rdi
callq 0x3370
jmp 0x205a2
cmpl $0x2, -0x1f4(%rbp)
jne 0x200e4
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
leaq -0x30(%rbp), %rdx
leaq -0x1f8(%rbp), %rcx
callq 0x205d0
jmp 0x200d5
movl $0x1, -0x284(%rbp)
jmp 0x2057b
leaq 0x2b5c5(%rip), %rax     # 0x4b6b0
cmpl $0x1d, (%rax)
jne 0x2019b
leaq -0x2d1(%rbp), %rdi
movq %rdi, -0x3b0(%rbp)
callq 0x3570
movq -0x3b0(%rbp), %rdx
leaq 0x1545d(%rip), %rsi     # 0x35572
leaq -0x2d0(%rbp), %rdi
callq 0x3440
jmp 0x20123
leaq -0x2d0(%rbp), %rdi
callq 0x18620
jmp 0x20131
leaq -0x2d0(%rbp), %rdi
callq 0x35e8
leaq -0x2d1(%rbp), %rdi
callq 0x3370
movl $0x1, -0x284(%rbp)
jmp 0x2057b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1e0(%rbp)
movl %eax, -0x1e4(%rbp)
jmp 0x2018a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1e0(%rbp)
movl %eax, -0x1e4(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0x35e8
leaq -0x2d1(%rbp), %rdi
callq 0x3370
jmp 0x205a2
jmp 0x2019d
cmpl $0x3, -0x1f4(%rbp)
jne 0x201cf
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
leaq -0x30(%rbp), %rdx
leaq -0x1f8(%rbp), %rcx
callq 0x20920
jmp 0x201c0
movl $0x1, -0x284(%rbp)
jmp 0x2057b
movb $0x1, %al
cmpl $0x0, -0x1f4(%rbp)
movb %al, -0x3b1(%rbp)
je 0x201f0
cmpl $0x1, -0x1f4(%rbp)
sete %al
movb %al, -0x3b1(%rbp)
movb -0x3b1(%rbp), %al
testb $0x1, %al
jne 0x201fc
jmp 0x201fe
jmp 0x2021d
leaq 0x1539c(%rip), %rdi     # 0x355a1
leaq 0x1521c(%rip), %rsi     # 0x35428
movl $0x3bd, %edx            # imm = 0x3BD
leaq 0x153bf(%rip), %rcx     # 0x355d7
callq 0x3230
movb $0x1, %al
cmpl $0x2, -0x1f0(%rbp)
movb %al, -0x3b2(%rbp)
je 0x2023e
cmpl $0x1, -0x1f0(%rbp)
sete %al
movb %al, -0x3b2(%rbp)
movb -0x3b2(%rbp), %al
testb $0x1, %al
jne 0x2024a
jmp 0x2024c
jmp 0x2026b
leaq 0x153ac(%rip), %rdi     # 0x355ff
leaq 0x151ce(%rip), %rsi     # 0x35428
movl $0x3be, %edx            # imm = 0x3BE
leaq 0x15371(%rip), %rcx     # 0x355d7
callq 0x3230
cmpl $0x0, -0x1f4(%rbp)
jne 0x20329
cmpl $0x2, -0x1f0(%rbp)
jne 0x202d6
movq -0x10(%rbp), %rax
movl $0x2, (%rax)
leaq -0x1c8(%rbp), %rdi
movl $0x27, %esi
callq 0x33b0
movq %rax, -0x3c0(%rbp)
jmp 0x202a5
movq -0x3c0(%rbp), %rdi
movsbl -0x1ec(%rbp), %esi
callq 0x33b0
movq %rax, -0x3c8(%rbp)
jmp 0x202c1
movq -0x3c8(%rbp), %rdi
movl $0x27, %esi
callq 0x33b0
jmp 0x202d4
jmp 0x202f6
movq -0x10(%rbp), %rax
movl $0x1, (%rax)
leaq -0x1c8(%rbp), %rdi
movl -0x1ec(%rbp), %esi
callq 0x3550
jmp 0x202f4
jmp 0x202f6
leaq -0x2f8(%rbp), %rdi
leaq -0x1d8(%rbp), %rsi
callq 0x32f0
jmp 0x2030b
movq -0x8(%rbp), %rdi
leaq -0x2f8(%rbp), %rsi
callq 0x33d0
leaq -0x2f8(%rbp), %rdi
callq 0x35e8
jmp 0x20344
movq -0x8(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x3040
jmp 0x20338
movl -0x1f0(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
jmp 0x20571
callq 0x2e050
jmp 0x20350
leaq -0x1c8(%rbp), %rdi
movl $0x27, %esi
callq 0x33b0
movq %rax, -0x3d0(%rbp)
jmp 0x2036a
movq -0x3d0(%rbp), %rdi
leaq 0x2b360(%rip), %rax     # 0x4b6d8
movsbl (%rax), %esi
callq 0x33b0
movq %rax, -0x3d8(%rbp)
jmp 0x20389
movq -0x3d8(%rbp), %rdi
movl $0x27, %esi
callq 0x33b0
jmp 0x2039c
leaq -0x318(%rbp), %rdi
leaq -0x1d8(%rbp), %rsi
callq 0x32f0
jmp 0x203b1
movq -0x8(%rbp), %rdi
leaq -0x318(%rbp), %rsi
callq 0x33d0
leaq -0x318(%rbp), %rdi
callq 0x35e8
movq -0x10(%rbp), %rax
movl $0x2, (%rax)
jmp 0x20571
callq 0x2e050
jmp 0x203e3
movq -0x8(%rbp), %rdi
leaq -0x1fc(%rbp), %rsi
callq 0x1f630
jmp 0x203f5
movq -0x10(%rbp), %rax
movl $0x1, (%rax)
movl $0x1e, -0x334(%rbp)
leaq -0x334(%rbp), %rax
movq %rax, -0x330(%rbp)
movq $0x1, -0x328(%rbp)
movq -0x330(%rbp), %rsi
movq -0x328(%rbp), %rdx
leaq -0x320(%rbp), %rdi
callq 0x227f0
jmp 0x2043e
movl $0x22, -0x358(%rbp)
movl $0x26, -0x354(%rbp)
leaq -0x358(%rbp), %rax
movq %rax, -0x350(%rbp)
movq $0x2, -0x348(%rbp)
movq -0x350(%rbp), %rsi
movq -0x348(%rbp), %rdx
leaq -0x340(%rbp), %rdi
callq 0x227f0
jmp 0x20487
movq -0x320(%rbp), %rdi
movq -0x340(%rbp), %rsi
callq 0x18170
jmp 0x2049c
movl $0x1e, -0x374(%rbp)
leaq -0x374(%rbp), %rax
movq %rax, -0x370(%rbp)
movq $0x1, -0x368(%rbp)
movq -0x370(%rbp), %rsi
movq -0x368(%rbp), %rdx
leaq -0x360(%rbp), %rdi
callq 0x227f0
jmp 0x204db
leaq 0x2b1ce(%rip), %rax     # 0x4b6b0
movl (%rax), %esi
leaq -0x360(%rbp), %rdi
callq 0x18b40
xorb $-0x1, %al
testb $0x1, %al
jne 0x204f8
jmp 0x2050b
callq 0x2e050
jmp 0x204ff
movl $0x1, -0x284(%rbp)
jmp 0x2057b
jmp 0x2050d
jmp 0x2050f
callq 0x2e050
jmp 0x20516
jmp 0x20571
callq 0x20ed0
jmp 0x2051f
leaq -0x1c8(%rbp), %rdi
leaq 0x2b1af(%rip), %rax     # 0x4b6dc
movl (%rax), %esi
callq 0x3550
jmp 0x20536
leaq -0x398(%rbp), %rdi
leaq -0x1d8(%rbp), %rsi
callq 0x32f0
jmp 0x2054b
movq -0x8(%rbp), %rdi
leaq -0x398(%rbp), %rsi
callq 0x33d0
leaq -0x398(%rbp), %rdi
callq 0x35e8
movq -0x10(%rbp), %rax
movl $0x1, (%rax)
movl $0x0, -0x284(%rbp)
leaq -0x1d8(%rbp), %rdi
callq 0x35f0
leaq -0x50(%rbp), %rdi
callq 0x35e8
leaq -0x30(%rbp), %rdi
callq 0x35e8
addq $0x3e0, %rsp            # imm = 0x3E0
popq %rbp
retq
leaq -0x1d8(%rbp), %rdi
callq 0x35f0
leaq -0x50(%rbp), %rdi
callq 0x35e8
leaq -0x30(%rbp), %rdi
callq 0x35e8
movq -0x1e0(%rbp), %rdi
callq 0x3560
nopl (%rax)