// File: CHEN-Zhihan[P]Compiler/Node.cpp
// Function: ExprNode::evaluate()
void ExprNode::evaluate() {
    array<int, 2> stack;
    if (oper == STRING) {
        cerr << "Invalid operation on string" << endl;
        exit(-1);
    }
    switch (oper) {
        case INTEGER: {
            value = dynamic_pointer_cast<IntNode>(op[0])->getValue();
            known = true;
            break;
        }
        case CHARACTER: {
            value = dynamic_pointer_cast<CharNode>(op[0])->getValue();
            known = true;            
            break;
        }
        case BOOL: {
            value = dynamic_pointer_cast<BoolNode>(op[0])->getValue();
            known = true;
            break;
        }
        case VAR: {
            known = false;
            return;
        }
        default: {
            auto left = dynamic_pointer_cast<ExprNode>(op[0]);
            auto right = dynamic_pointer_cast<ExprNode>(op[1]);
            left->evaluate();
            right->evaluate();
            if (not left->known or not right->known) {
                known = false;
                return;
            }
            known = true;
            stack[0] = left->value;
            stack[1] = right->value;
            switch (oper) {
                case '+': {
                    EVAL(+);
                }
                case '-': {
                    EVAL(-);
                }
                case '*': {
                    EVAL(*);
                }
                case '/': {
                    if (stack[1] == 0) {
                        cerr << "Division by 0" << endl;
                        exit(-1);
                    }
                    EVAL(/);
                }
                case '%': {
                    if (stack[1] == 0) {
                        cerr << "Division by 0" << endl;
                        exit(-1);
                    }
                    EVAL(%);
                } case UMINUS: {
                    value = -stack[0];
                    break;
                } case '>': {
                    EVAL(>);
                } case '<': {
                    EVAL(<);
                } case GE: {
                    EVAL(>=);
                } case LE: {
                    EVAL(<=);
                } case EQ: {
                    EVAL(==);
                } case NE: {
                    EVAL(!=);
                } case AND: {
                    EVAL(&&);
                } case OR: {
                    EVAL(||);
                }
            }
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x78(%rbp)
cmpl $0x104, 0x8(%rax)       # imm = 0x104
jne 0x23d8c
movq 0x2d289(%rip), %rdi     # 0x50ff0
leaq 0x12ad0(%rip), %rsi     # 0x3683e
callq 0x4210
movq %rax, %rdi
movq 0x2d223(%rip), %rsi     # 0x50fa0
callq 0x4240
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x42c0
movq -0x78(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0x7c(%rbp)
subl $-0x5, %eax
je 0x23eb3
jmp 0x23da1
movl -0x7c(%rbp), %eax
subl $0x102, %eax            # imm = 0x102
je 0x23dcc
jmp 0x23dad
movl -0x7c(%rbp), %eax
subl $0x103, %eax            # imm = 0x103
je 0x23e19
jmp 0x23db9
movl -0x7c(%rbp), %eax
subl $0x105, %eax            # imm = 0x105
je 0x23e66
jmp 0x23ec0
movq -0x78(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x29460
movq %rax, %rsi
leaq -0x20(%rbp), %rdi
callq 0x296a0
leaq -0x20(%rbp), %rdi
callq 0x29730
movq %rax, %rdi
callq 0x224e0
movl %eax, %ecx
movq -0x78(%rbp), %rax
movl %ecx, 0x10(%rax)
leaq -0x20(%rbp), %rdi
callq 0x29750
movq -0x78(%rbp), %rax
movb $0x1, 0x14(%rax)
jmp 0x24521
movq -0x78(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x29460
movq %rax, %rsi
leaq -0x30(%rbp), %rdi
callq 0x29770
leaq -0x30(%rbp), %rdi
callq 0x29800
movq %rax, %rdi
callq 0x22410
movl %eax, %ecx
movq -0x78(%rbp), %rax
movl %ecx, 0x10(%rax)
leaq -0x30(%rbp), %rdi
callq 0x29820
movq -0x78(%rbp), %rax
movb $0x1, 0x14(%rax)
jmp 0x24521
movq -0x78(%rbp), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x29460
movq %rax, %rsi
leaq -0x40(%rbp), %rdi
callq 0x29840
leaq -0x40(%rbp), %rdi
callq 0x298d0
movq %rax, %rdi
callq 0x22330
movl %eax, %ecx
movq -0x78(%rbp), %rax
movl %ecx, 0x10(%rax)
leaq -0x40(%rbp), %rdi
callq 0x298f0
movq -0x78(%rbp), %rax
movb $0x1, 0x14(%rax)
jmp 0x24521
movq -0x78(%rbp), %rax
movb $0x0, 0x14(%rax)
jmp 0x24521
movq -0x78(%rbp), %rdi
addq $0x18, %rdi
movq %rdi, -0x90(%rbp)
xorl %eax, %eax
movl %eax, %esi
callq 0x29460
movq %rax, %rsi
leaq -0x50(%rbp), %rdi
movq %rdi, -0x88(%rbp)
callq 0x29910
movq -0x90(%rbp), %rdi
movl $0x1, %esi
callq 0x29460
movq %rax, %rsi
leaq -0x60(%rbp), %rdi
callq 0x29910
movq -0x88(%rbp), %rdi
callq 0x299a0
movq %rax, %rdi
callq 0x23d40
jmp 0x23f1e
leaq -0x60(%rbp), %rdi
callq 0x299a0
movq %rax, %rdi
callq 0x23d40
jmp 0x23f31
leaq -0x50(%rbp), %rdi
callq 0x299a0
testb $0x1, 0x14(%rax)
je 0x23f4f
leaq -0x60(%rbp), %rdi
callq 0x299a0
testb $0x1, 0x14(%rax)
jne 0x23f86
movq -0x78(%rbp), %rax
movb $0x0, 0x14(%rax)
movl $0x1, -0x70(%rbp)
jmp 0x24502
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x60(%rbp), %rdi
callq 0xbc30
leaq -0x50(%rbp), %rdi
callq 0xbc30
jmp 0x2452a
movq -0x78(%rbp), %rax
movb $0x1, 0x14(%rax)
leaq -0x50(%rbp), %rdi
callq 0x299a0
movl 0x10(%rax), %eax
movl %eax, -0xa4(%rbp)
xorl %eax, %eax
movl %eax, %esi
leaq -0x10(%rbp), %rdi
movq %rdi, -0xa0(%rbp)
callq 0x299c0
movl -0xa4(%rbp), %ecx
movl %ecx, (%rax)
leaq -0x60(%rbp), %rdi
callq 0x299a0
movq -0xa0(%rbp), %rdi
movl 0x10(%rax), %eax
movl %eax, -0x98(%rbp)
movl $0x1, %esi
callq 0x299c0
movl -0x98(%rbp), %edx
movq %rax, %rcx
movq -0x78(%rbp), %rax
movl %edx, (%rcx)
movl 0x8(%rax), %eax
movl %eax, -0x94(%rbp)
subl $0x25, %eax
je 0x2422a
jmp 0x24002
movl -0x94(%rbp), %eax
subl $0x2a, %eax
je 0x24164
jmp 0x24013
movl -0x94(%rbp), %eax
subl $0x2b, %eax
je 0x240f0
jmp 0x24024
movl -0x94(%rbp), %eax
subl $0x2d, %eax
je 0x2412a
jmp 0x24035
movl -0x94(%rbp), %eax
subl $0x2f, %eax
je 0x2419f
jmp 0x24046
movl -0x94(%rbp), %eax
subl $0x3c, %eax
je 0x24316
jmp 0x24057
movl -0x94(%rbp), %eax
subl $0x3e, %eax
je 0x242d3
jmp 0x24068
movl -0x94(%rbp), %eax
subl $0x118, %eax            # imm = 0x118
je 0x24465
jmp 0x2407b
movl -0x94(%rbp), %eax
subl $0x119, %eax            # imm = 0x119
je 0x244b1
jmp 0x2408e
movl -0x94(%rbp), %eax
subl $0x11a, %eax            # imm = 0x11A
je 0x24359
jmp 0x240a1
movl -0x94(%rbp), %eax
subl $0x11b, %eax            # imm = 0x11B
je 0x2439c
jmp 0x240b4
movl -0x94(%rbp), %eax
subl $0x11c, %eax            # imm = 0x11C
je 0x243df
jmp 0x240c7
movl -0x94(%rbp), %eax
subl $0x11d, %eax            # imm = 0x11D
je 0x24422
jmp 0x240da
movl -0x94(%rbp), %eax
subl $0x120, %eax            # imm = 0x120
je 0x242b3
jmp 0x244fb
leaq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x299c0
movl (%rax), %eax
movl %eax, -0xa8(%rbp)
leaq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x299c0
movl -0xa8(%rbp), %ecx
movq %rax, %rdx
movq -0x78(%rbp), %rax
addl (%rdx), %ecx
movl %ecx, 0x10(%rax)
jmp 0x244fb
leaq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x299c0
movl (%rax), %eax
movl %eax, -0xac(%rbp)
leaq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x299c0
movl -0xac(%rbp), %ecx
movq %rax, %rdx
movq -0x78(%rbp), %rax
subl (%rdx), %ecx
movl %ecx, 0x10(%rax)
jmp 0x244fb
leaq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x299c0
movl (%rax), %eax
movl %eax, -0xb0(%rbp)
leaq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x299c0
movl -0xb0(%rbp), %ecx
movq %rax, %rdx
movq -0x78(%rbp), %rax
imull (%rdx), %ecx
movl %ecx, 0x10(%rax)
jmp 0x244fb
leaq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x299c0
cmpl $0x0, (%rax)
jne 0x241ed
movq 0x2ce37(%rip), %rdi     # 0x50ff0
leaq 0x1269a(%rip), %rsi     # 0x3685a
callq 0x4210
movq %rax, -0xb8(%rbp)
jmp 0x241ce
movq -0xb8(%rbp), %rdi
movq 0x2cdc4(%rip), %rsi     # 0x50fa0
callq 0x4240
jmp 0x241e3
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x42c0
leaq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x299c0
movl (%rax), %eax
movl %eax, -0xbc(%rbp)
leaq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x299c0
movq %rax, %rcx
movl -0xbc(%rbp), %eax
cltd
idivl (%rcx)
movl %eax, %ecx
movq -0x78(%rbp), %rax
movl %ecx, 0x10(%rax)
jmp 0x244fb
leaq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x299c0
cmpl $0x0, (%rax)
jne 0x24278
movq 0x2cdac(%rip), %rdi     # 0x50ff0
leaq 0x1260f(%rip), %rsi     # 0x3685a
callq 0x4210
movq %rax, -0xc8(%rbp)
jmp 0x24259
movq -0xc8(%rbp), %rdi
movq 0x2cd39(%rip), %rsi     # 0x50fa0
callq 0x4240
jmp 0x2426e
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x42c0
leaq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x299c0
movl (%rax), %eax
movl %eax, -0xcc(%rbp)
leaq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x299c0
movq %rax, %rcx
movl -0xcc(%rbp), %eax
cltd
idivl (%rcx)
movq -0x78(%rbp), %rax
movl %edx, 0x10(%rax)
jmp 0x244fb
leaq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x299c0
movq %rax, %rdx
movq -0x78(%rbp), %rax
xorl %ecx, %ecx
subl (%rdx), %ecx
movl %ecx, 0x10(%rax)
jmp 0x244fb
leaq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x299c0
movl (%rax), %eax
movl %eax, -0xd0(%rbp)
leaq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x299c0
movl -0xd0(%rbp), %ecx
movq %rax, %rdx
movq -0x78(%rbp), %rax
cmpl (%rdx), %ecx
setg %cl
andb $0x1, %cl
movzbl %cl, %ecx
movl %ecx, 0x10(%rax)
jmp 0x244fb
leaq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x299c0
movl (%rax), %eax
movl %eax, -0xd4(%rbp)
leaq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x299c0
movl -0xd4(%rbp), %ecx
movq %rax, %rdx
movq -0x78(%rbp), %rax
cmpl (%rdx), %ecx
setl %cl
andb $0x1, %cl
movzbl %cl, %ecx
movl %ecx, 0x10(%rax)
jmp 0x244fb
leaq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x299c0
movl (%rax), %eax
movl %eax, -0xd8(%rbp)
leaq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x299c0
movl -0xd8(%rbp), %ecx
movq %rax, %rdx
movq -0x78(%rbp), %rax
cmpl (%rdx), %ecx
setge %cl
andb $0x1, %cl
movzbl %cl, %ecx
movl %ecx, 0x10(%rax)
jmp 0x244fb
leaq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x299c0
movl (%rax), %eax
movl %eax, -0xdc(%rbp)
leaq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x299c0
movl -0xdc(%rbp), %ecx
movq %rax, %rdx
movq -0x78(%rbp), %rax
cmpl (%rdx), %ecx
setle %cl
andb $0x1, %cl
movzbl %cl, %ecx
movl %ecx, 0x10(%rax)
jmp 0x244fb
leaq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x299c0
movl (%rax), %eax
movl %eax, -0xe0(%rbp)
leaq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x299c0
movl -0xe0(%rbp), %ecx
movq %rax, %rdx
movq -0x78(%rbp), %rax
cmpl (%rdx), %ecx
sete %cl
andb $0x1, %cl
movzbl %cl, %ecx
movl %ecx, 0x10(%rax)
jmp 0x244fb
leaq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x299c0
movl (%rax), %eax
movl %eax, -0xe4(%rbp)
leaq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x299c0
movl -0xe4(%rbp), %ecx
movq %rax, %rdx
movq -0x78(%rbp), %rax
cmpl (%rdx), %ecx
setne %cl
andb $0x1, %cl
movzbl %cl, %ecx
movl %ecx, 0x10(%rax)
jmp 0x244fb
leaq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x299c0
movq %rax, %rcx
xorl %eax, %eax
cmpl $0x0, (%rcx)
movb %al, -0xe5(%rbp)
je 0x2449c
leaq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x299c0
cmpl $0x0, (%rax)
setne %al
movb %al, -0xe5(%rbp)
movq -0x78(%rbp), %rax
movb -0xe5(%rbp), %cl
andb $0x1, %cl
movzbl %cl, %ecx
movl %ecx, 0x10(%rax)
jmp 0x244fb
leaq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x299c0
movq %rax, %rcx
movb $0x1, %al
cmpl $0x0, (%rcx)
movb %al, -0xe6(%rbp)
jne 0x244e8
leaq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x299c0
cmpl $0x0, (%rax)
setne %al
movb %al, -0xe6(%rbp)
movq -0x78(%rbp), %rax
movb -0xe6(%rbp), %cl
andb $0x1, %cl
movzbl %cl, %ecx
movl %ecx, 0x10(%rax)
movl $0x0, -0x70(%rbp)
leaq -0x60(%rbp), %rdi
callq 0xbc30
leaq -0x50(%rbp), %rdi
callq 0xbc30
movl -0x70(%rbp), %eax
testl %eax, %eax
je 0x2451f
jmp 0x2451d
jmp 0x24521
jmp 0x24521
addq $0xf0, %rsp
popq %rbp
retq
movq -0x68(%rbp), %rdi
callq 0x43d0
nopw %cs:(%rax,%rax)