// File: CHEN-Zhihan[P]Compiler/Node.cpp
// Function: ExprNode::ex(std::vector<int, std::allocator<int>>&, int, int, int) const
void ExprNode::ex(vector<int>& sList, int functionID, int blbl, int clbl) const {
    unordered_set<int> uniOp{INTEGER, CHARACTER, STRING, BOOL, VAR, CALL};
    if (uniOp.count(oper) != 0) {
        op[0]->ex(sList, functionID, blbl, clbl);
        return;
    }
    switch (oper) {
        case '=': {
            op[1]->ex(sList, functionID, blbl, clbl);
            auto v = dynamic_pointer_cast<VarNode>(op[0]);
            v->pop(sList, functionID);
            if (!inStatement) {
                v->push(sList, functionID);
            }
            break;
        } case NOT: {
            printf("\tpush\t1\n");
            op[0]->ex(sList, functionID, blbl, clbl);
            printf("\tsub\n");
            break;

        } case UMINUS: {
            op[0]->ex(sList, functionID, blbl, clbl);
            printf("\tneg\n");
            break;
        } case POSINC: {
            if (!inStatement) {
                op[0]->ex(sList, functionID, blbl, clbl);
            }
            incdec(dynamic_pointer_cast<VarNode>(op[0]), blbl, clbl, sList, functionID, true);
            break;
        } case PREINC: {
            incdec(dynamic_pointer_cast<VarNode>(op[0]), blbl, clbl, sList, functionID, true);
            if (!inStatement) {
                op[0]->ex(sList, functionID, blbl, clbl);
            }
            break;
        } case POSDEC: {
            if (!inStatement) {
                op[0]->ex(sList, functionID, blbl, clbl);
            }
            incdec(dynamic_pointer_cast<VarNode>(op[0]), blbl, clbl, sList, functionID, false);
            break;
        } case PREDEC: {
            incdec(dynamic_pointer_cast<VarNode>(op[0]), blbl, clbl, sList, functionID, false);
            if (!inStatement) {
                op[0]->ex(sList, functionID, blbl, clbl);
            }
            break;
        } default: {
            op[0]->ex(sList, functionID, blbl, clbl);
            op[1]->ex(sList, functionID, blbl, clbl);
            if (operatorInstruction.count(oper) != 0) {
                cout << "\t" << operatorInstruction[oper] << "\n";
            }
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movl %r8d, -0x1c(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xf8(%rbp)
movabsq $-0x200000005, %rax     # imm = 0xFFFFFFFDFFFFFFFB
movq %rax, -0x70(%rbp)
movups 0x14003(%rip), %xmm0    # 0x36720
movaps %xmm0, -0x80(%rbp)
leaq -0x80(%rbp), %rax
movq %rax, -0x68(%rbp)
movq $0x6, -0x60(%rbp)
leaq -0x83(%rbp), %rdi
movq %rdi, -0xf0(%rbp)
callq 0x16f20
movq -0xf0(%rbp), %rcx
movq -0x68(%rbp), %rsi
movq -0x60(%rbp), %rdx
movq %rsp, %rax
movq %rcx, (%rax)
xorl %eax, %eax
movl %eax, %ecx
leaq -0x58(%rbp), %rdi
leaq -0x81(%rbp), %r8
leaq -0x82(%rbp), %r9
callq 0x294e0
jmp 0x22776
leaq -0x83(%rbp), %rdi
callq 0x16fc0
movq -0xf8(%rbp), %rsi
addq $0x8, %rsi
leaq -0x58(%rbp), %rdi
callq 0x29540
movq %rax, -0x100(%rbp)
jmp 0x2279f
movq -0x100(%rbp), %rax
cmpq $0x0, %rax
je 0x22830
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x29570
movq %rax, %rdi
callq 0x17630
movq %rax, %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movl -0x1c(%rbp), %r8d
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
jmp 0x227e7
movl $0x1, -0x98(%rbp)
jmp 0x22e8a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x83(%rbp), %rdi
callq 0x16fc0
jmp 0x22ea5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x22e9c
movq -0xf8(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0x104(%rbp)
subl $0x3d, %eax
je 0x228bc
jmp 0x22847
movl -0x104(%rbp), %eax
subl $0x112, %eax            # imm = 0x112
je 0x22a4d
jmp 0x2285a
movl -0x104(%rbp), %eax
subl $0x113, %eax            # imm = 0x113
je 0x22bd9
jmp 0x2286d
movl -0x104(%rbp), %eax
subl $0x114, %eax            # imm = 0x114
je 0x22b13
jmp 0x22880
movl -0x104(%rbp), %eax
subl $0x115, %eax            # imm = 0x115
je 0x22ca6
jmp 0x22893
movl -0x104(%rbp), %eax
subl $0x120, %eax            # imm = 0x120
je 0x22a01
jmp 0x228a6
movl -0x104(%rbp), %eax
subl $0x121, %eax            # imm = 0x121
je 0x229a5
jmp 0x22d73
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
movl $0x1, %esi
callq 0x29570
movq %rax, %rdi
callq 0x17630
movq %rax, %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movl -0x1c(%rbp), %r8d
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
jmp 0x228f4
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x29570
movq %rax, %rsi
leaq -0xa8(%rbp), %rdi
movq %rdi, -0x110(%rbp)
callq 0xbb80
movq -0x110(%rbp), %rdi
callq 0x292f0
movq %rax, %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
callq 0x225a0
jmp 0x2293b
movq -0xf8(%rbp), %rax
testb $0x1, 0xc(%rax)
jne 0x2298a
leaq -0xa8(%rbp), %rdi
callq 0x292f0
movq %rax, %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
callq 0x22ec0
jmp 0x22965
jmp 0x2298a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0xbc50
jmp 0x22e9c
movl $0x2, -0x98(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0xbc50
jmp 0x22e80
leaq 0x13e3b(%rip), %rdi     # 0x367e7
xorl %eax, %eax
callq 0x4040
jmp 0x229b5
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x29570
movq %rax, %rdi
callq 0x17630
movq %rax, %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movl -0x1c(%rbp), %r8d
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
jmp 0x229ec
leaq 0x13dfd(%rip), %rdi     # 0x367f0
xorl %eax, %eax
callq 0x4040
jmp 0x229fc
jmp 0x22e80
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x29570
movq %rax, %rdi
callq 0x17630
movq %rax, %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movl -0x1c(%rbp), %r8d
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
jmp 0x22a38
leaq 0x13db7(%rip), %rdi     # 0x367f6
xorl %eax, %eax
callq 0x4040
jmp 0x22a48
jmp 0x22e80
movq -0xf8(%rbp), %rax
testb $0x1, 0xc(%rax)
jne 0x22a93
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x29570
movq %rax, %rdi
callq 0x17630
movq %rax, %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movl -0x1c(%rbp), %r8d
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
jmp 0x22a91
jmp 0x22a93
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x29570
movq %rax, %rsi
leaq -0xb8(%rbp), %rdi
movq %rdi, -0x118(%rbp)
callq 0xbb80
movq -0x118(%rbp), %rdi
movl -0x18(%rbp), %esi
movl -0x1c(%rbp), %edx
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %r8d
movl $0x1, %r9d
callq 0x22500
jmp 0x22adf
leaq -0xb8(%rbp), %rdi
callq 0xbc50
jmp 0x22e80
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0xbc50
jmp 0x22e9c
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x29570
movq %rax, %rsi
leaq -0xc8(%rbp), %rdi
movq %rdi, -0x120(%rbp)
callq 0xbb80
movq -0x120(%rbp), %rdi
movl -0x18(%rbp), %esi
movl -0x1c(%rbp), %edx
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %r8d
movl $0x1, %r9d
callq 0x22500
jmp 0x22b5f
leaq -0xc8(%rbp), %rdi
callq 0xbc50
movq -0xf8(%rbp), %rax
testb $0x1, 0xc(%rax)
jne 0x22bd4
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x29570
movq %rax, %rdi
callq 0x17630
movq %rax, %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movl -0x1c(%rbp), %r8d
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
jmp 0x22baf
jmp 0x22bd4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0xbc50
jmp 0x22e9c
jmp 0x22e80
movq -0xf8(%rbp), %rax
testb $0x1, 0xc(%rax)
jne 0x22c1f
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x29570
movq %rax, %rdi
callq 0x17630
movq %rax, %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movl -0x1c(%rbp), %r8d
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
jmp 0x22c1d
jmp 0x22c1f
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, -0x124(%rbp)
movl %eax, %esi
callq 0x29570
movq %rax, %rsi
leaq -0xd8(%rbp), %rdi
movq %rdi, -0x130(%rbp)
callq 0xbb80
movq -0x130(%rbp), %rdi
movl -0x124(%rbp), %r9d
movl -0x18(%rbp), %esi
movl -0x1c(%rbp), %edx
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %r8d
callq 0x22500
jmp 0x22c72
leaq -0xd8(%rbp), %rdi
callq 0xbc50
jmp 0x22e80
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0xbc50
jmp 0x22e9c
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, -0x134(%rbp)
movl %eax, %esi
callq 0x29570
movq %rax, %rsi
leaq -0xe8(%rbp), %rdi
movq %rdi, -0x140(%rbp)
callq 0xbb80
movq -0x140(%rbp), %rdi
movl -0x134(%rbp), %r9d
movl -0x18(%rbp), %esi
movl -0x1c(%rbp), %edx
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %r8d
callq 0x22500
jmp 0x22cf9
leaq -0xe8(%rbp), %rdi
callq 0xbc50
movq -0xf8(%rbp), %rax
testb $0x1, 0xc(%rax)
jne 0x22d6e
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x29570
movq %rax, %rdi
callq 0x17630
movq %rax, %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movl -0x1c(%rbp), %r8d
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
jmp 0x22d49
jmp 0x22d6e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0xbc50
jmp 0x22e9c
jmp 0x22e80
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x29570
movq %rax, %rdi
callq 0x17630
movq %rax, %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movl -0x1c(%rbp), %r8d
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
jmp 0x22daa
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
movl $0x1, %esi
callq 0x29570
movq %rax, %rdi
callq 0x17630
movq %rax, %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movl -0x1c(%rbp), %r8d
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
jmp 0x22de2
movq -0xf8(%rbp), %rsi
addq $0x8, %rsi
leaq 0x2e5fc(%rip), %rdi     # 0x513f0
callq 0x295a0
movq %rax, -0x148(%rbp)
jmp 0x22e02
movq -0x148(%rbp), %rax
cmpq $0x0, %rax
je 0x22e7e
movq 0x2e1aa(%rip), %rdi     # 0x50fc0
leaq 0x139c8(%rip), %rsi     # 0x367e5
callq 0x4210
movq %rax, -0x150(%rbp)
jmp 0x22e2b
movq -0xf8(%rbp), %rsi
addq $0x8, %rsi
leaq 0x2e5b3(%rip), %rdi     # 0x513f0
callq 0x295d0
movq %rax, -0x158(%rbp)
jmp 0x22e4b
movq -0x158(%rbp), %rsi
movq -0x150(%rbp), %rdi
callq 0x41f0
movq %rax, -0x160(%rbp)
jmp 0x22e67
movq -0x160(%rbp), %rdi
leaq 0x133c8(%rip), %rsi     # 0x3623d
callq 0x4210
jmp 0x22e7c
jmp 0x22e7e
jmp 0x22e80
movl $0x0, -0x98(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x17460
addq $0x170, %rsp            # imm = 0x170
popq %rbp
retq
leaq -0x58(%rbp), %rdi
callq 0x17460
movq -0x90(%rbp), %rdi
callq 0x43d0
nopw %cs:(%rax,%rax)