// File: /workspace/github_cpp_makefile_star2_O2/xzebra[P]function-plotter/mathParser/mathParser.cpp
// Function: Parser::toPostfix(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
Operation* Parser::toPostfix(std::string infix) {
    Stack<std::string> operatorStack = Stack<std::string>();
    Operation *output = new Operation();
    output->v_pos = std::vector<int>(0);

    std::string funcName_temp;

    // While there are tokens to be read
    for(int i = 0; i < infix.length(); i++) {
        char c = infix[i]; // Read a token
        if(c == ' ') continue;
        if(isNum(c)) { // token is number
            // check if number is negative and not substracting
            bool negative = false;
            if(i == 1 && infix[i-1] == '-' || i > 1 && infix[i-1] == '-' && !isNum(infix[i-2])) {
                output->postfix += std::string(1, '-');
            }

            for(; i < infix.length(); i++) {
                // parse its digits
                if(!isNum(infix[i]) && infix[i] != '.') {
                    i--;
                    break;
                }            
                output->postfix += std::string(1, infix[i]); // push num to the output queue
            }
            output->postfix += ' ';
        } else if(c == ')') {
            bool found = false;
            while(!operatorStack.empty()) {
                // while the operator at the top of the stack is not a left
                // bracket -> pop the operator from stack onto the output
                if(operatorStack.getHead()[0] == '(') {
                    // pop the left bracket from the stack
                    operatorStack.pop();
                    found = true;
                    break;
                }
                output->postfix += operatorStack.pop();
                output->postfix += ' ';
            }
            if(!found) std::cout << "error: mismatched parenthesis" << std::endl;     
        } else if(isOperator(c) || isFunc(i, infix, funcName_temp)) {
            bool func = funcName_temp.length() > 1;
            if(!func && c == '-') {
                // check if substracting or is the negative sign of a number
                if(!i) continue;
                if(isOperator(infix[i-1])) continue;                    
                if((i-2) >= 0) {
                    if(isLetter(infix[i-1]) && isLetter(infix[i-2])) continue;
                    // else -> is variable
                }
            }
            while(!operatorStack.empty()) {
                std::string head = operatorStack.getHead();
                if(c == '(' || head[0] == '(') break;
                if(func) break;
                if(precedence(head[0]) < precedence(c)) break;
                if(precedence(head[0]) == precedence(c) && assocRight(head[0])) break;
                // push operator to the output queue
                output->postfix += operatorStack.pop();
                output->postfix += ' ';
            }
            if(func) {
                operatorStack.push(funcName_temp);
                funcName_temp = "";
            } else operatorStack.push(std::string(1, c));

        } else { // variable
            output->postfix += c;
            output->postfix += ' ';
            output->v_pos.push_back(output->postfix.length()-2);
            output->v_values.push_back(0);
        }
    }

    // no more tokens to read:
    while(!operatorStack.empty()) {
        output->postfix += operatorStack.pop();
        output->postfix += ' ';
    }

    return output;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x118, %rsp            # imm = 0x118
movq %rsi, %r14
xorps %xmm0, %xmm0
movaps %xmm0, -0x60(%rbp)
andq $0x0, -0x50(%rbp)
pushq $0x50
popq %rdi
callq 0x2190
leaq 0x10(%rax), %rcx
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rax)
movq %rcx, (%rax)
andq $0x0, 0x8(%rax)
movups %xmm0, 0x20(%rax)
movups %xmm0, 0x30(%rax)
movups %xmm0, 0x40(%rax)
movq %rax, %r15
xorl %ebx, %ebx
leaq -0xb0(%rbp), %rdi
leaq -0x88(%rbp), %rdx
xorl %esi, %esi
callq 0x3adc
leaq 0x20(%r15), %rdi
leaq -0xb0(%rbp), %r12
movq %rdi, -0xc0(%rbp)
movq %r12, %rsi
callq 0x3dd0
movq %r12, %rdi
callq 0x3cc6
leaq -0xa0(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
movq %r15, -0x38(%rbp)
addq $0x38, %r15
movq %r15, -0xb8(%rbp)
leaq -0x78(%rbp), %r15
leaq -0x88(%rbp), %r13
movl %ebx, -0x2c(%rbp)
movslq %ebx, %r12
cmpq %r12, 0x8(%r14)
jbe 0x37ae
movq (%r14), %rax
movzbl (%rax,%r12), %edx
cmpl $0x20, %edx
je 0x37a4
leal -0x30(%rdx), %ecx
cmpb $0x9, %cl
ja 0x343b
cmpl $0x1, %ebx
jne 0x3598
cmpb $0x2d, (%rax)
movq -0x38(%rbp), %rbx
jne 0x35e1
movq %r15, -0x88(%rbp)
movq %r13, %rdi
pushq $0x1
popq %rsi
pushq $0x2d
popq %rdx
callq 0x21a0
movq %rbx, %rdi
movq %r13, %rsi
callq 0x22d0
movq %r13, %rdi
callq 0x20c0
jmp 0x35e1
movq %rdx, -0x40(%rbp)
leal -0x28(%rdx), %eax
cmpl $0x36, %eax
movq -0x38(%rbp), %rbx
ja 0x3705
movabsq $0x400000000000ad, %rcx # imm = 0x400000000000AD
btq %rax, %rcx
jae 0x369f
movq -0xa8(%rbp), %rax
movq %rax, -0x90(%rbp)
cmpq $0x2, %rax
setae %al
cmpl $0x2d, -0x40(%rbp)
setne %cl
orb %al, %cl
jne 0x34cf
movslq -0x2c(%rbp), %rax
testq %rax, %rax
je 0x37a4
movq (%r14), %rcx
movzbl -0x1(%rcx,%rax), %edx
leal -0x28(%rdx), %esi
cmpl $0x36, %esi
ja 0x34b4
movabsq $0x400000000000ad, %rdi # imm = 0x400000000000AD
btq %rsi, %rdi
jb 0x37a4
cmpl $0x2, %eax
jl 0x34cf
addb $-0x61, %dl
cmpb $0x19, %dl
ja 0x34cf
movb -0x2(%rcx,%rax), %al
addb $-0x61, %al
cmpb $0x1a, %al
jb 0x37a4
cmpl $0x0, -0x50(%rbp)
je 0x3617
movq -0x60(%rbp), %rsi
movq %r13, %rdi
callq 0x2200
movb $0x1, %bl
cmpl $0x28, -0x40(%rbp)
je 0x353b
movq %r13, %r12
movq %r14, %r13
movq %r15, %r14
cmpq $0x2, -0x90(%rbp)
setb %al
movq -0x88(%rbp), %rcx
movb (%rcx), %r15b
cmpb $0x28, %r15b
setne %cl
testb %cl, %al
je 0x3532
movsbl %r15b, %edi
callq 0x32d1
movl %eax, -0x64(%rbp)
movsbl -0x40(%rbp), %edi
callq 0x32d1
movl -0x64(%rbp), %ecx
cmpl %eax, %ecx
jae 0x354c
movq %r14, %r15
movq %r13, %r14
movq %r12, %r13
movq %r13, %rdi
callq 0x20c0
testb %bl, %bl
je 0x34cf
jmp 0x3617
cmpb $0x5e, %r15b
movq %r14, %r15
movq %r13, %r14
movq %r12, %r13
leaq -0x120(%rbp), %r12
jne 0x3566
cmpl %eax, %ecx
je 0x353b
movq %r12, %rdi
leaq -0x60(%rbp), %rsi
callq 0x3b2e
movq -0x38(%rbp), %rbx
movq %rbx, %rdi
movq %r12, %rsi
callq 0x22d0
movq %r12, %rdi
callq 0x20c0
movq %rbx, %rdi
pushq $0x20
popq %rsi
callq 0x2140
xorl %ebx, %ebx
jmp 0x353b
movq -0x38(%rbp), %rbx
jle 0x35e1
cmpb $0x2d, -0x1(%rax,%r12)
jne 0x35e1
movb -0x2(%rax,%r12), %al
addb $-0x30, %al
cmpb $0xa, %al
jb 0x35e1
jmp 0x340e
movq %r15, -0x88(%rbp)
movsbl %al, %edx
movq %r13, %rdi
pushq $0x1
popq %rsi
callq 0x21a0
movq %rbx, %rdi
movq %r13, %rsi
callq 0x22d0
movq %r13, %rdi
callq 0x20c0
incq %r12
cmpq %r12, 0x8(%r14)
jbe 0x3603
movq (%r14), %rax
movb (%rax,%r12), %al
leal -0x30(%rax), %ecx
cmpb $0xa, %cl
setb %cl
cmpb $0x2e, %al
sete %dl
orb %cl, %dl
jne 0x35b6
decl %r12d
movl %r12d, -0x2c(%rbp)
movq %rbx, %rdi
pushq $0x20
popq %rsi
callq 0x2140
jmp 0x37a4
cmpq $0x2, -0x90(%rbp)
leaq -0x100(%rbp), %rdi
jae 0x3660
leaq -0xd0(%rbp), %rax
movq %rax, -0xe0(%rbp)
movsbl -0x40(%rbp), %edx
leaq -0xe0(%rbp), %rbx
movq %rbx, %rdi
pushq $0x1
popq %rsi
callq 0x21a0
leaq -0x60(%rbp), %rdi
movq %rbx, %rsi
callq 0x3b58
movq %rbx, %rdi
jmp 0x379f
leaq -0xb0(%rbp), %rsi
callq 0x2200
leaq -0x60(%rbp), %rdi
leaq -0x100(%rbp), %rbx
movq %rbx, %rsi
callq 0x3b58
movq %rbx, %rdi
callq 0x20c0
leaq -0xb0(%rbp), %rdi
leaq 0x1a09(%rip), %rsi      # 0x509e
callq 0x22c0
jmp 0x37a4
cmpq $0x1, %rax
jne 0x3705
cmpl $0x0, -0x50(%rbp)
je 0x376b
movq -0x60(%rbp), %rsi
movq %r13, %rdi
callq 0x2200
movq -0x88(%rbp), %rax
movb (%rax), %bl
movq %r13, %rdi
callq 0x20c0
cmpb $0x28, %bl
je 0x3788
movq %r13, %rdi
leaq -0x60(%rbp), %rsi
callq 0x3b2e
movq -0x38(%rbp), %rbx
movq %rbx, %rdi
movq %r13, %rsi
callq 0x22d0
movq %r13, %rdi
callq 0x20c0
movq %rbx, %rdi
pushq $0x20
popq %rsi
callq 0x2140
jmp 0x36a5
leaq -0x2c(%rbp), %rdi
movq %r14, %rsi
leaq -0xb0(%rbp), %rdx
callq 0x3268
testb %al, %al
jne 0x3463
movsbl -0x40(%rbp), %esi
movq %rbx, %rdi
callq 0x2140
movq %rbx, %rdi
pushq $0x20
popq %rsi
callq 0x2140
movl 0x8(%rbx), %eax
addl $-0x2, %eax
movl %eax, -0x88(%rbp)
movq -0xc0(%rbp), %rdi
movq %r13, %rsi
callq 0x3e3c
andq $0x0, -0x88(%rbp)
movq -0xb8(%rbp), %rdi
movq %r13, %rsi
callq 0x3f6a
jmp 0x37a4
movq 0x485e(%rip), %rdi      # 0x7fd0
leaq 0x195b(%rip), %rsi      # 0x50d4
callq 0x2180
movq %rax, %rdi
callq 0x20d0
jmp 0x37a4
leaq -0x140(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x3b2e
leaq -0x140(%rbp), %rdi
callq 0x20c0
movl -0x2c(%rbp), %ebx
incl %ebx
jmp 0x33cf
leaq -0x88(%rbp), %r14
leaq -0x60(%rbp), %r15
pushq $0x20
popq %r12
movq -0x38(%rbp), %rbx
cmpl $0x0, -0x50(%rbp)
je 0x37f2
movq %r14, %rdi
movq %r15, %rsi
callq 0x3b2e
movq %rbx, %rdi
movq %r14, %rsi
callq 0x22d0
movq %r14, %rdi
callq 0x20c0
movq %rbx, %rdi
movl %r12d, %esi
callq 0x2140
jmp 0x37c1
leaq -0xb0(%rbp), %rdi
callq 0x20c0
leaq -0x60(%rbp), %rdi
callq 0x3c64
movq %rbx, %rax
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x3883
jmp 0x3883
jmp 0x3822
movq %rax, %rbx
jmp 0x3892
jmp 0x3883
jmp 0x3883
movq %rax, %rbx
leaq -0x100(%rbp), %rdi
jmp 0x387c
movq %rax, %rbx
leaq -0xe0(%rbp), %rdi
jmp 0x387c
jmp 0x3883
jmp 0x3883
jmp 0x3872
jmp 0x3883
jmp 0x3872
movq %rax, %rbx
leaq -0x120(%rbp), %rdi
callq 0x20c0
jmp 0x3875
jmp 0x3872
jmp 0x3883
jmp 0x3883
jmp 0x3883
jmp 0x3872
jmp 0x3883
jmp 0x3883
jmp 0x3872
jmp 0x3883
jmp 0x3883
movq %rax, %rbx
leaq -0x88(%rbp), %rdi
callq 0x20c0
jmp 0x3886
movq %rax, %rbx
leaq -0xb0(%rbp), %rdi
callq 0x20c0
leaq -0x60(%rbp), %rdi
callq 0x3c64
movq %rbx, %rdi
callq 0x2290
nop