// File: /workspace/github_cpp_makefile_star2_O2/KJTang[P]SimpleCompiler/Parser.cpp
// Function: Parser::parseExpression()
ASTNode *Parser::parseExpression() {
    #ifdef DEBUG
    std::cout<<curToken.second<<"\tparseExpression"<<std::endl;
    #endif
    std::stack<ASTNode*> numStack;
    std::stack<int> opStack;
    while (true) {
        switch (curToken.first) {
            case Token::NUMBER: {
                numStack.push(this->parseNumber());
                break;
            }
            case Token::IDENTIFIER: {
                numStack.push(this->parseIdentifier());
                break;
            }
            case static_cast<Token>('('): {
                numStack.push(this->parseParenExpr());
                break;
            }
            case static_cast<Token>(','): 
            case static_cast<Token>(';'): {
                // expression end
                getNextToken(); // eat ',' or ';'
            }
            case static_cast<Token>(')'): {
                // expression end
                while (!opStack.empty()) {
                    char op = opStack.top();
                    opStack.pop();
                    ASTNode *l, *r;
                    r = numStack.top();
                    numStack.pop();
                    l = numStack.top();
                    numStack.pop();
                    BinaryExprAST *binExpr = new BinaryExprAST(op, l, r);
                    numStack.push(binExpr);
                }
                if (!numStack.empty()) {
                    return numStack.top();
                } else {
                    // std::cout<<"empty expression!"<<std::endl;
                    return nullptr;
                }
            }
            default: {
                // std::cout<<"op"<<std::endl;
                if (!opStack.empty() && 
                    getOperatorPrecedence(opStack.top()) >= getOperatorPrecedence(static_cast<int>(curToken.first))) {
                    char op = opStack.top();
                    opStack.pop();
                    ASTNode *l, *r;
                    r = numStack.top();
                    numStack.pop();
                    l = numStack.top();
                    numStack.pop();
                    BinaryExprAST *binExpr = new BinaryExprAST(op, l, r);
                    numStack.push(binExpr);
                }
                opStack.push(static_cast<int>(curToken.first));
                getNextToken();
                break;
            }
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq %rdi, %rbx
leaq -0x90(%rbp), %rdi
callq 0x80a4
leaq -0xe0(%rbp), %rdi
callq 0x80c4
leaq -0x90(%rbp), %r14
leaq -0x30(%rbp), %r15
leaq -0xe0(%rbp), %r12
leaq 0xa5a0(%rip), %rax      # 0x11bb0
addq $0x10, %rax
movq %rax, -0x40(%rbp)
movl 0x58(%rbx), %eax
testl %eax, %eax
je 0x7797
cmpl $0x1, %eax
je 0x77b3
cmpl $0x28, %eax
je 0x777b
cmpl $0x29, %eax
je 0x77d7
cmpl $0x2c, %eax
je 0x77cf
cmpl $0x3b, %eax
je 0x77cf
movq -0xb0(%rbp), %rax
cmpq -0xd0(%rbp), %rax
je 0x775d
cmpq -0xa8(%rbp), %rax
jne 0x7680
movq -0x98(%rbp), %rax
movq -0x8(%rax), %rax
movl $0x200, %ecx            # imm = 0x200
addq %rcx, %rax
movl -0x4(%rax), %esi
movq %rbx, %rdi
callq 0x80e4
movl %eax, %r13d
movl 0x58(%rbx), %esi
movq %rbx, %rdi
callq 0x80e4
cmpl %eax, %r13d
jl 0x775d
movq -0xb0(%rbp), %rax
cmpq -0xa8(%rbp), %rax
jne 0x76c5
movq -0x98(%rbp), %rax
movq -0x8(%rax), %rax
movl $0x200, %ecx            # imm = 0x200
addq %rcx, %rax
movl -0x4(%rax), %eax
movl %eax, -0x34(%rbp)
movq %r12, %rdi
callq 0x8b86
movq -0x60(%rbp), %rax
cmpq -0x58(%rbp), %rax
jne 0x76ed
movq -0x48(%rbp), %rax
movq -0x8(%rax), %rax
movl $0x200, %ecx            # imm = 0x200
addq %rcx, %rax
movq -0x8(%rax), %r12
movq %r14, %rdi
callq 0x8be6
movq -0x60(%rbp), %rax
cmpq -0x58(%rbp), %rax
movq %r14, %r13
jne 0x7716
movq -0x48(%rbp), %rax
movq -0x8(%rax), %rax
movl $0x200, %ecx            # imm = 0x200
addq %rcx, %rax
movq -0x8(%rax), %r14
movq %r13, %rdi
callq 0x8be6
pushq $0x20
popq %rdi
callq 0x31e0
movsbl -0x34(%rbp), %ecx
andl $0x0, 0x8(%rax)
movq -0x40(%rbp), %rdx
movq %rdx, (%rax)
movl %ecx, 0xc(%rax)
movq %r14, 0x10(%rax)
movq %r12, 0x18(%rax)
movq %rax, -0x30(%rbp)
movq %r13, %rdi
movq %r15, %rsi
callq 0x893a
movq %r13, %r14
leaq -0xe0(%rbp), %r12
movl 0x58(%rbx), %eax
movl %eax, -0x30(%rbp)
movq %r12, %rdi
movq %r15, %rsi
callq 0x8c46
movq %rbx, %rdi
callq 0x7fbe
jmp 0x7618
movq %rbx, %rdi
callq 0x7966
movq %rax, -0x30(%rbp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x893a
jmp 0x7618
movq %rbx, %rdi
callq 0x79b2
movq %rax, -0x30(%rbp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x893a
jmp 0x7618
movq %rbx, %rdi
callq 0x7922
movq %rax, -0x30(%rbp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x893a
jmp 0x7618
movq %rbx, %rdi
callq 0x7fbe
movl $0x200, %r13d           # imm = 0x200
leaq -0x90(%rbp), %r14
movq -0xb0(%rbp), %rax
cmpq -0xd0(%rbp), %rax
je 0x7896
cmpq -0xa8(%rbp), %rax
jne 0x780f
movq -0x98(%rbp), %rax
movq -0x8(%rax), %rax
addq %r13, %rax
movl -0x4(%rax), %ebx
leaq -0xe0(%rbp), %rdi
callq 0x8b86
movq -0x60(%rbp), %rax
cmpq -0x58(%rbp), %rax
jne 0x7833
movq -0x48(%rbp), %rax
movq -0x8(%rax), %rax
addq %r13, %rax
movq -0x8(%rax), %r15
movq %r14, %rdi
callq 0x8be6
movq -0x60(%rbp), %rax
cmpq -0x58(%rbp), %rax
jne 0x7854
movq -0x48(%rbp), %rax
movq -0x8(%rax), %rax
addq %r13, %rax
movq -0x8(%rax), %r12
movq %r14, %rdi
callq 0x8be6
pushq $0x20
popq %rdi
callq 0x31e0
movsbl %bl, %ecx
andl $0x0, 0x8(%rax)
movq -0x40(%rbp), %rdx
movq %rdx, (%rax)
movl %ecx, 0xc(%rax)
movq %r12, 0x10(%rax)
movq %r15, 0x18(%rax)
movq %rax, -0x30(%rbp)
movq %r14, %rdi
leaq -0x30(%rbp), %rsi
callq 0x893a
jmp 0x77e4
movq -0x60(%rbp), %rax
cmpq -0x80(%rbp), %rax
je 0x78b9
cmpq -0x58(%rbp), %rax
jne 0x78b3
movq -0x48(%rbp), %rcx
movl $0x200, %eax            # imm = 0x200
addq -0x8(%rcx), %rax
movq -0x8(%rax), %rbx
jmp 0x78bb
xorl %ebx, %ebx
leaq -0xe0(%rbp), %rdi
callq 0x4bee
leaq -0x90(%rbp), %rdi
callq 0x841e
movq %rbx, %rax
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x78ff
movq %rax, %rbx
jmp 0x790e
jmp 0x78ff
jmp 0x78ff
jmp 0x78ff
jmp 0x78ff
jmp 0x78ff
jmp 0x78ff
jmp 0x78ff
jmp 0x78ff
movq %rax, %rbx
leaq -0xe0(%rbp), %rdi
callq 0x4bee
leaq -0x90(%rbp), %rdi
callq 0x841e
movq %rbx, %rdi
callq 0x3350