// File: 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
subq $0x310, %rsp            # imm = 0x310
movq %rsi, -0x210(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, -0x30(%rbp)
movq $0x0, -0x20(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x5090
movl $0x50, %edi
callq 0x21d0
movq %rax, -0x208(%rbp)
jmp 0x40c5
movq -0x208(%rbp), %rdi
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rdi)
movaps %xmm0, 0x30(%rdi)
movaps %xmm0, 0x20(%rdi)
movaps %xmm0, 0x10(%rdi)
movaps %xmm0, (%rdi)
callq 0x50b0
movq -0x208(%rbp), %rax
movq %rax, -0x38(%rbp)
leaq -0x61(%rbp), %rdi
movq %rdi, -0x218(%rbp)
callq 0x50f0
movq -0x218(%rbp), %rdx
xorl %eax, %eax
movl %eax, %esi
leaq -0x60(%rbp), %rdi
callq 0x5110
jmp 0x4118
movq -0x38(%rbp), %rdi
addq $0x20, %rdi
leaq -0x60(%rbp), %rsi
callq 0x5180
leaq -0x60(%rbp), %rdi
callq 0x51b0
leaq -0x61(%rbp), %rdi
callq 0x5210
leaq -0x88(%rbp), %rdi
callq 0x22a0
movl $0x0, -0x8c(%rbp)
movq -0x210(%rbp), %rdi
movslq -0x8c(%rbp), %rax
movq %rax, -0x220(%rbp)
callq 0x22c0
movq %rax, %rcx
movq -0x220(%rbp), %rax
cmpq %rcx, %rax
jae 0x4b47
movq -0x210(%rbp), %rdi
movslq -0x8c(%rbp), %rsi
callq 0x2380
movq %rax, -0x228(%rbp)
jmp 0x419a
movq -0x228(%rbp), %rax
movb (%rax), %al
movb %al, -0x8d(%rbp)
movsbl -0x8d(%rbp), %eax
cmpl $0x20, %eax
jne 0x41f6
jmp 0x4b33
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x4c0a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x61(%rbp), %rdi
callq 0x5210
jmp 0x4c0a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x4bfe
movsbl -0x8d(%rbp), %edi
callq 0x3e80
testb $0x1, %al
jne 0x420b
jmp 0x44dd
movb $0x0, -0x8e(%rbp)
cmpl $0x1, -0x8c(%rbp)
jne 0x424a
movq -0x210(%rbp), %rdi
movl -0x8c(%rbp), %eax
decl %eax
movslq %eax, %rsi
callq 0x2380
movq %rax, -0x230(%rbp)
jmp 0x423b
movq -0x230(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
je 0x42c2
cmpl $0x1, -0x8c(%rbp)
jle 0x4357
movq -0x210(%rbp), %rdi
movl -0x8c(%rbp), %eax
decl %eax
movslq %eax, %rsi
callq 0x2380
movq %rax, -0x238(%rbp)
jmp 0x4277
movq -0x238(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
jne 0x4357
movq -0x210(%rbp), %rdi
movl -0x8c(%rbp), %eax
addl $-0x2, %eax
movslq %eax, %rsi
callq 0x2380
movq %rax, -0x240(%rbp)
jmp 0x42ab
movq -0x240(%rbp), %rax
movsbl (%rax), %edi
callq 0x3e80
testb $0x1, %al
jne 0x4357
leaq -0xb1(%rbp), %rdi
movq %rdi, -0x248(%rbp)
callq 0x2330
movq -0x248(%rbp), %rcx
leaq -0xb0(%rbp), %rdi
movl $0x1, %esi
movl $0x2d, %edx
callq 0x2150
jmp 0x42f4
movq -0x38(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x2250
jmp 0x4306
leaq -0xb0(%rbp), %rdi
callq 0x2130
leaq -0xb1(%rbp), %rdi
callq 0x2200
jmp 0x4357
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x4346
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x2130
leaq -0xb1(%rbp), %rdi
callq 0x2200
jmp 0x4bfe
jmp 0x4359
movq -0x210(%rbp), %rdi
movslq -0x8c(%rbp), %rax
movq %rax, -0x250(%rbp)
callq 0x22c0
movq %rax, %rcx
movq -0x250(%rbp), %rax
cmpq %rcx, %rax
jae 0x44c8
movq -0x210(%rbp), %rdi
movslq -0x8c(%rbp), %rsi
callq 0x2380
movq %rax, -0x258(%rbp)
jmp 0x43a2
movq -0x258(%rbp), %rax
movsbl (%rax), %edi
callq 0x3e80
testb $0x1, %al
jne 0x43f4
movq -0x210(%rbp), %rdi
movslq -0x8c(%rbp), %rsi
callq 0x2380
movq %rax, -0x260(%rbp)
jmp 0x43d1
movq -0x260(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2e, %eax
je 0x43f4
movl -0x8c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0x44c8
movq -0x210(%rbp), %rdi
movslq -0x8c(%rbp), %rsi
callq 0x2380
movq %rax, -0x268(%rbp)
jmp 0x4410
movq -0x268(%rbp), %rax
movsbl (%rax), %eax
movl %eax, -0x274(%rbp)
leaq -0xd9(%rbp), %rdi
movq %rdi, -0x270(%rbp)
callq 0x2330
movl -0x274(%rbp), %edx
movq -0x270(%rbp), %rcx
leaq -0xd8(%rbp), %rdi
movl $0x1, %esi
callq 0x2150
jmp 0x4453
movq -0x38(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x2250
jmp 0x4465
leaq -0xd8(%rbp), %rdi
callq 0x2130
leaq -0xd9(%rbp), %rdi
callq 0x2200
movl -0x8c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0x4359
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x44b7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x2130
leaq -0xd9(%rbp), %rdi
callq 0x2200
jmp 0x4bfe
movq -0x38(%rbp), %rdi
movl $0x20, %esi
callq 0x2140
jmp 0x44d8
jmp 0x4b31
movsbl -0x8d(%rbp), %eax
cmpl $0x29, %eax
jne 0x464f
movb $0x0, -0xda(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x5230
movb %al, -0x275(%rbp)
jmp 0x4505
movb -0x275(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x4516
jmp 0x460e
leaq -0x100(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x5250
jmp 0x4528
xorl %eax, %eax
movl %eax, %esi
leaq -0x100(%rbp), %rdi
callq 0x2380
movq %rax, -0x280(%rbp)
jmp 0x4541
movq -0x280(%rbp), %rax
movsbl (%rax), %eax
movl %eax, -0x284(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x2130
movl -0x284(%rbp), %eax
cmpl $0x28, %eax
jne 0x45ac
leaq -0x120(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x5280
jmp 0x457a
leaq -0x120(%rbp), %rdi
callq 0x2130
movb $0x1, -0xda(%rbp)
jmp 0x460e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x2130
jmp 0x4bfe
leaq -0x140(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x5280
jmp 0x45be
movq -0x38(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0x2250
jmp 0x45d0
leaq -0x140(%rbp), %rdi
callq 0x2130
movq -0x38(%rbp), %rdi
movl $0x20, %esi
callq 0x2140
jmp 0x45ec
jmp 0x44f4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x2130
jmp 0x4bfe
testb $0x1, -0xda(%rbp)
jne 0x464a
movq 0x79b2(%rip), %rdi      # 0xbfd0
leaq 0x3a6e(%rip), %rsi      # 0x8093
callq 0x21c0
movq %rax, -0x290(%rbp)
jmp 0x4633
movq -0x290(%rbp), %rdi
movq 0x7977(%rip), %rsi      # 0xbfb8
callq 0x21f0
jmp 0x4648
jmp 0x464a
jmp 0x4b2f
movsbl -0x8d(%rbp), %edi
callq 0x3eb0
testb $0x1, %al
jne 0x4690
movq -0x210(%rbp), %rsi
leaq -0x8c(%rbp), %rdi
leaq -0x88(%rbp), %rdx
callq 0x3f40
movb %al, -0x291(%rbp)
jmp 0x4681
movb -0x291(%rbp), %al
testb $0x1, %al
jne 0x4690
jmp 0x4ab3
leaq -0x88(%rbp), %rdi
callq 0x22c0
cmpq $0x1, %rax
seta %al
andb $0x1, %al
movb %al, -0x141(%rbp)
testb $0x1, -0x141(%rbp)
jne 0x4792
movsbl -0x8d(%rbp), %eax
cmpl $0x2d, %eax
jne 0x4792
cmpl $0x0, -0x8c(%rbp)
jne 0x46d6
jmp 0x4b33
movq -0x210(%rbp), %rdi
movl -0x8c(%rbp), %eax
decl %eax
movslq %eax, %rsi
callq 0x2380
movq %rax, -0x2a0(%rbp)
jmp 0x46f6
movq -0x2a0(%rbp), %rax
movsbl (%rax), %edi
callq 0x3eb0
testb $0x1, %al
jne 0x470b
jmp 0x4710
jmp 0x4b33
movl -0x8c(%rbp), %eax
subl $0x2, %eax
cmpl $0x0, %eax
jl 0x4790
movq -0x210(%rbp), %rdi
movl -0x8c(%rbp), %eax
decl %eax
movslq %eax, %rsi
callq 0x2380
movq %rax, -0x2a8(%rbp)
jmp 0x473e
movq -0x2a8(%rbp), %rax
movsbl (%rax), %edi
callq 0x3f10
testb $0x1, %al
jne 0x4753
jmp 0x478e
movq -0x210(%rbp), %rdi
movl -0x8c(%rbp), %eax
addl $-0x2, %eax
movslq %eax, %rsi
callq 0x2380
movq %rax, -0x2b0(%rbp)
jmp 0x4774
movq -0x2b0(%rbp), %rax
movsbl (%rax), %edi
callq 0x3f10
testb $0x1, %al
jne 0x4789
jmp 0x478e
jmp 0x4b33
jmp 0x4790
jmp 0x4792
jmp 0x4794
leaq -0x30(%rbp), %rdi
callq 0x5230
movb %al, -0x2b1(%rbp)
jmp 0x47a5
movb -0x2b1(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x47b6
jmp 0x499b
leaq -0x168(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x5250
jmp 0x47c8
movsbl -0x8d(%rbp), %eax
cmpl $0x28, %eax
je 0x47fc
xorl %eax, %eax
movl %eax, %esi
leaq -0x168(%rbp), %rdi
callq 0x2380
movq %rax, -0x2c0(%rbp)
jmp 0x47ed
movq -0x2c0(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x28, %eax
jne 0x481c
movl $0xb, -0x16c(%rbp)
jmp 0x4953
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x498a
testb $0x1, -0x141(%rbp)
je 0x4834
movl $0xb, -0x16c(%rbp)
jmp 0x4953
xorl %eax, %eax
movl %eax, %esi
leaq -0x168(%rbp), %rdi
callq 0x2380
movq %rax, -0x2c8(%rbp)
jmp 0x484d
movq -0x2c8(%rbp), %rax
movsbl (%rax), %edi
callq 0x3ff0
movl %eax, -0x2cc(%rbp)
movsbl -0x8d(%rbp), %edi
callq 0x3ff0
movl %eax, %ecx
movl -0x2cc(%rbp), %eax
cmpl %ecx, %eax
jge 0x4889
movl $0xb, -0x16c(%rbp)
jmp 0x4953
xorl %eax, %eax
movl %eax, %esi
leaq -0x168(%rbp), %rdi
callq 0x2380
movq %rax, -0x2d8(%rbp)
jmp 0x48a2
movq -0x2d8(%rbp), %rax
movsbl (%rax), %edi
callq 0x3ff0
movl %eax, -0x2dc(%rbp)
movsbl -0x8d(%rbp), %edi
callq 0x3ff0
movl %eax, %ecx
movl -0x2dc(%rbp), %eax
cmpl %ecx, %eax
jne 0x4909
xorl %eax, %eax
movl %eax, %esi
leaq -0x168(%rbp), %rdi
callq 0x2380
movq %rax, -0x2e8(%rbp)
jmp 0x48e8
movq -0x2e8(%rbp), %rax
movsbl (%rax), %edi
callq 0x4060
testb $0x1, %al
jne 0x48fd
jmp 0x4909
movl $0xb, -0x16c(%rbp)
jmp 0x4953
leaq -0x190(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x5280
jmp 0x491b
movq -0x38(%rbp), %rdi
leaq -0x190(%rbp), %rsi
callq 0x2250
jmp 0x492d
leaq -0x190(%rbp), %rdi
callq 0x2130
movq -0x38(%rbp), %rdi
movl $0x20, %esi
callq 0x2140
jmp 0x4949
movl $0x0, -0x16c(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x2130
movl -0x16c(%rbp), %eax
testl %eax, %eax
je 0x496d
jmp 0x496b
jmp 0x499b
jmp 0x4794
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x190(%rbp), %rdi
callq 0x2130
leaq -0x168(%rbp), %rdi
callq 0x2130
jmp 0x4bfe
testb $0x1, -0x141(%rbp)
je 0x4a0e
leaq -0x1b0(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x20e0
jmp 0x49b9
leaq -0x30(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
callq 0x52f0
jmp 0x49cb
leaq -0x1b0(%rbp), %rdi
callq 0x2130
leaq 0x36b0(%rip), %rsi      # 0x808e
leaq -0x88(%rbp), %rdi
callq 0x2280
jmp 0x49ec
jmp 0x4ab1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0x2130
jmp 0x4bfe
movsbl -0x8d(%rbp), %eax
movl %eax, -0x2f4(%rbp)
leaq -0x1d1(%rbp), %rdi
movq %rdi, -0x2f0(%rbp)
callq 0x2330
movl -0x2f4(%rbp), %edx
movq -0x2f0(%rbp), %rcx
leaq -0x1d0(%rbp), %rdi
movl $0x1, %esi
callq 0x2150
jmp 0x4a4e
leaq -0x30(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0x52f0
jmp 0x4a60
leaq -0x1d0(%rbp), %rdi
callq 0x2130
leaq -0x1d1(%rbp), %rdi
callq 0x2200
jmp 0x4ab1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x4aa0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0x2130
leaq -0x1d1(%rbp), %rdi
callq 0x2200
jmp 0x4bfe
jmp 0x4b2d
movsbl -0x8d(%rbp), %esi
movq -0x38(%rbp), %rdi
callq 0x2140
jmp 0x4ac5
movq -0x38(%rbp), %rdi
movl $0x20, %esi
callq 0x2140
jmp 0x4ad5
movq -0x38(%rbp), %rdi
movq %rdi, %rax
addq $0x20, %rax
movq %rax, -0x300(%rbp)
callq 0x22c0
movq -0x300(%rbp), %rdi
addl $-0x2, %eax
movl %eax, -0x1d8(%rbp)
leaq -0x1d8(%rbp), %rsi
callq 0x5460
jmp 0x4b0a
movq -0x38(%rbp), %rdi
addq $0x38, %rdi
movq $0x0, -0x1e0(%rbp)
leaq -0x1e0(%rbp), %rsi
callq 0x5490
jmp 0x4b2b
jmp 0x4b2d
jmp 0x4b2f
jmp 0x4b31
jmp 0x4b33
movl -0x8c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0x4151
jmp 0x4b49
leaq -0x30(%rbp), %rdi
callq 0x5230
movb %al, -0x301(%rbp)
jmp 0x4b5a
movb -0x301(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x4b68
jmp 0x4bc4
leaq -0x200(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x5280
jmp 0x4b7a
movq -0x38(%rbp), %rdi
leaq -0x200(%rbp), %rsi
callq 0x2250
jmp 0x4b8c
leaq -0x200(%rbp), %rdi
callq 0x2130
movq -0x38(%rbp), %rdi
movl $0x20, %esi
callq 0x2140
jmp 0x4ba8
jmp 0x4b49
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x200(%rbp), %rdi
callq 0x2130
jmp 0x4bfe
movq -0x38(%rbp), %rax
movq %rax, -0x310(%rbp)
movl $0x1, -0x16c(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x2130
leaq -0x30(%rbp), %rdi
callq 0x54c0
movq -0x310(%rbp), %rax
addq $0x310, %rsp            # imm = 0x310
popq %rbp
retq
leaq -0x88(%rbp), %rdi
callq 0x2130
leaq -0x30(%rbp), %rdi
callq 0x54c0
movq -0x40(%rbp), %rdi
callq 0x2320
nopl (%rax)