// File: mbottini[P]CS250lab2/main.cpp
// Function: evalRPN(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>> const&, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, bool, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, bool>>> const&)
bool evalRPN(const stringVector& RPNVector, const boolMap& bmap) {
    std::stack<string> variableStack;
    string arg1, arg2;

    if(RPNVector.empty()) {
        return false;
    }

    // If it's just one variable in the statement, return the variable.
    if(RPNVector.size() == 1) {
        if(evalExpression(RPNVector[0], "", "", bmap) == "t") {
            return true;
        }

        else {
            return false;
        }
    }

    for(stringIter i = RPNVector.begin(); i != RPNVector.end(); ++i) {
        if(isVariable(*i)) {
            variableStack.push(*i);
        }

        // Otherwise, it's an operator.
        else {
            // Unary operator takes one argument.
            if(*i == "!") {
                if(variableStack.size() > 0) {
                    arg1 = variableStack.top();
                    variableStack.pop();
                    arg2 = "";
                    // Evaluate the arguments and push the result onto the
                    // stack.
                    variableStack.push(evalExpression(arg1, arg2, *i, bmap));
                }

                else {
                    std::cout << "Invalid expression! Not enough arguments.\n";
                    return false;
                }
            }

            // Otherwise, it's a binary operator and takes two.
            else {
                if(variableStack.size() > 1) {
                    arg1 = variableStack.top();
                    variableStack.pop();
                    arg2 = variableStack.top();
                    variableStack.pop();
                    variableStack.push(evalExpression(arg2, arg1, *i, bmap));
                }

                else {
                    std::cout << "Invalid expression! Not enough arguments.\n";
                    return false;
                }
            }
        }
    }

    // We should have a single expression at this point - either c or t.

    if(variableStack.size() != 1) {
        std::cout << "Invalid expression! Too many arguments.\n";
        return false;
    }

    if(variableStack.top() == "t") {
        return true;
    }

    else {
        if(variableStack.top() != "c") {
            std::cout << "Invalid expression! It didn't simplify to t or c.\n";
        }
        return false;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1f0, %rsp            # imm = 0x1F0
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x53f0
leaq -0x88(%rbp), %rdi
callq 0x2240
leaq -0xa8(%rbp), %rdi
callq 0x2240
movq -0x10(%rbp), %rdi
callq 0x5520
testb $0x1, %al
jne 0x3c03
jmp 0x3c16
movb $0x0, -0x1(%rbp)
movl $0x1, -0xac(%rbp)
jmp 0x41ca
movq -0x10(%rbp), %rdi
callq 0x4f40
cmpq $0x1, %rax
jne 0x3ddd
movq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x5560
movq %rax, -0x190(%rbp)
leaq -0xf1(%rbp), %rdi
movq %rdi, -0x188(%rbp)
callq 0x22d0
movq -0x188(%rbp), %rdx
leaq 0x84a7(%rip), %rsi      # 0xc105
leaq -0xf0(%rbp), %rdi
callq 0x2230
jmp 0x3c6c
leaq -0x129(%rbp), %rdi
movq %rdi, -0x198(%rbp)
callq 0x22d0
movq -0x198(%rbp), %rdx
leaq 0x8478(%rip), %rsi      # 0xc105
leaq -0x128(%rbp), %rdi
callq 0x2230
jmp 0x3c9b
movq -0x190(%rbp), %rsi
movq -0x18(%rbp), %r8
leaq -0xd0(%rbp), %rdi
leaq -0xf0(%rbp), %rdx
leaq -0x128(%rbp), %rcx
callq 0x4930
jmp 0x3cc2
leaq 0x84e3(%rip), %rsi      # 0xc1ac
leaq -0xd0(%rbp), %rdi
callq 0x5140
movb %al, -0x199(%rbp)
jmp 0x3cdd
leaq -0xd0(%rbp), %rdi
callq 0x2100
leaq -0x128(%rbp), %rdi
callq 0x2100
leaq -0x129(%rbp), %rdi
callq 0x21d0
leaq -0xf0(%rbp), %rdi
callq 0x2100
leaq -0xf1(%rbp), %rdi
callq 0x21d0
movb -0x199(%rbp), %al
testb $0x1, %al
jne 0x3d28
jmp 0x3dca
movb $0x1, -0x1(%rbp)
movl $0x1, -0xac(%rbp)
jmp 0x41ca
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x100(%rbp)
movl %eax, -0x104(%rbp)
jmp 0x3db9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x100(%rbp)
movl %eax, -0x104(%rbp)
jmp 0x3da1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x100(%rbp)
movl %eax, -0x104(%rbp)
jmp 0x3d95
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x100(%rbp)
movl %eax, -0x104(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0x2100
leaq -0x128(%rbp), %rdi
callq 0x2100
leaq -0x129(%rbp), %rdi
callq 0x21d0
leaq -0xf0(%rbp), %rdi
callq 0x2100
leaq -0xf1(%rbp), %rdi
callq 0x21d0
jmp 0x41f9
movb $0x0, -0x1(%rbp)
movl $0x1, -0xac(%rbp)
jmp 0x41ca
movq -0x10(%rbp), %rdi
callq 0x52a0
movq %rax, -0x138(%rbp)
movq -0x10(%rbp), %rdi
callq 0x5310
movq %rax, -0x140(%rbp)
leaq -0x138(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0x52d0
testb $0x1, %al
jne 0x3e19
jmp 0x40dc
leaq -0x138(%rbp), %rdi
callq 0x5040
movq %rax, %rdi
callq 0x4350
testb $0x1, %al
jne 0x3e33
jmp 0x3e69
leaq -0x138(%rbp), %rdi
callq 0x5040
movq %rax, %rsi
leaq -0x68(%rbp), %rdi
callq 0x54a0
jmp 0x3e4d
jmp 0x40c9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x100(%rbp)
movl %eax, -0x104(%rbp)
jmp 0x41f9
leaq -0x138(%rbp), %rdi
callq 0x5040
movq %rax, %rdi
leaq 0x81bd(%rip), %rsi      # 0xc03c
callq 0x5140
movb %al, -0x19a(%rbp)
jmp 0x3e8c
movb -0x19a(%rbp), %al
testb $0x1, %al
jne 0x3e9b
jmp 0x3fa4
leaq -0x68(%rbp), %rdi
callq 0x5580
movq %rax, -0x1a8(%rbp)
jmp 0x3ead
movq -0x1a8(%rbp), %rax
cmpq $0x0, %rax
jbe 0x3f77
leaq -0x68(%rbp), %rdi
callq 0x5460
movq %rax, -0x1b0(%rbp)
jmp 0x3ed0
movq -0x1b0(%rbp), %rsi
leaq -0x88(%rbp), %rdi
callq 0x2040
jmp 0x3ee5
leaq -0x68(%rbp), %rdi
callq 0x5480
jmp 0x3ef0
leaq 0x820e(%rip), %rsi      # 0xc105
leaq -0xa8(%rbp), %rdi
callq 0x2220
jmp 0x3f05
leaq -0x138(%rbp), %rdi
callq 0x5040
movq %rax, %rcx
movq -0x18(%rbp), %r8
leaq -0x160(%rbp), %rdi
leaq -0x88(%rbp), %rsi
leaq -0xa8(%rbp), %rdx
callq 0x4930
jmp 0x3f34
leaq -0x68(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x55a0
jmp 0x3f46
leaq -0x160(%rbp), %rdi
callq 0x2100
jmp 0x3f9f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x100(%rbp)
movl %eax, -0x104(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x2100
jmp 0x41f9
movq 0xe052(%rip), %rdi      # 0x11fd0
leaq 0x8183(%rip), %rsi      # 0xc108
callq 0x2190
jmp 0x3f8c
movb $0x0, -0x1(%rbp)
movl $0x1, -0xac(%rbp)
jmp 0x41ca
jmp 0x40c7
leaq -0x68(%rbp), %rdi
callq 0x5580
movq %rax, -0x1b8(%rbp)
jmp 0x3fb6
movq -0x1b8(%rbp), %rax
cmpq $0x1, %rax
jbe 0x409d
leaq -0x68(%rbp), %rdi
callq 0x5460
movq %rax, -0x1c0(%rbp)
jmp 0x3fd9
movq -0x1c0(%rbp), %rsi
leaq -0x88(%rbp), %rdi
callq 0x2040
jmp 0x3fee
leaq -0x68(%rbp), %rdi
callq 0x5480
jmp 0x3ff9
leaq -0x68(%rbp), %rdi
callq 0x5460
movq %rax, -0x1c8(%rbp)
jmp 0x400b
movq -0x1c8(%rbp), %rsi
leaq -0xa8(%rbp), %rdi
callq 0x2040
jmp 0x4020
leaq -0x68(%rbp), %rdi
callq 0x5480
jmp 0x402b
leaq -0x138(%rbp), %rdi
callq 0x5040
movq %rax, %rcx
movq -0x18(%rbp), %r8
leaq -0x180(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
leaq -0x88(%rbp), %rdx
callq 0x4930
jmp 0x405a
leaq -0x68(%rbp), %rdi
leaq -0x180(%rbp), %rsi
callq 0x55a0
jmp 0x406c
leaq -0x180(%rbp), %rdi
callq 0x2100
jmp 0x40c5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x100(%rbp)
movl %eax, -0x104(%rbp)
leaq -0x180(%rbp), %rdi
callq 0x2100
jmp 0x41f9
movq 0xdf2c(%rip), %rdi      # 0x11fd0
leaq 0x805d(%rip), %rsi      # 0xc108
callq 0x2190
jmp 0x40b2
movb $0x0, -0x1(%rbp)
movl $0x1, -0xac(%rbp)
jmp 0x41ca
jmp 0x40c7
jmp 0x40c9
jmp 0x40cb
leaq -0x138(%rbp), %rdi
callq 0x5060
jmp 0x3ded
leaq -0x68(%rbp), %rdi
callq 0x5580
movq %rax, -0x1d0(%rbp)
jmp 0x40ee
movq -0x1d0(%rbp), %rax
cmpq $0x1, %rax
je 0x4123
movq 0xdece(%rip), %rdi      # 0x11fd0
leaq 0x802a(%rip), %rsi      # 0xc133
callq 0x2190
jmp 0x4110
movb $0x0, -0x1(%rbp)
movl $0x1, -0xac(%rbp)
jmp 0x41ca
leaq -0x68(%rbp), %rdi
callq 0x5460
movq %rax, -0x1d8(%rbp)
jmp 0x4135
movq -0x1d8(%rbp), %rdi
leaq 0x8069(%rip), %rsi      # 0xc1ac
callq 0x5140
movb %al, -0x1d9(%rbp)
jmp 0x4150
movb -0x1d9(%rbp), %al
testb $0x1, %al
jne 0x415c
jmp 0x416c
movb $0x1, -0x1(%rbp)
movl $0x1, -0xac(%rbp)
jmp 0x41ca
leaq -0x68(%rbp), %rdi
callq 0x5460
movq %rax, -0x1e8(%rbp)
jmp 0x417e
movq -0x1e8(%rbp), %rdi
leaq 0x7e9f(%rip), %rsi      # 0xc02b
callq 0x54d0
movb %al, -0x1e9(%rbp)
jmp 0x4199
movb -0x1e9(%rbp), %al
testb $0x1, %al
jne 0x41a5
jmp 0x41bc
movq 0xde24(%rip), %rdi      # 0x11fd0
leaq 0x7fa9(%rip), %rsi      # 0xc15c
callq 0x2190
jmp 0x41ba
jmp 0x41bc
movb $0x0, -0x1(%rbp)
movl $0x1, -0xac(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x2100
leaq -0x88(%rbp), %rdi
callq 0x2100
leaq -0x68(%rbp), %rdi
callq 0x5500
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x1f0, %rsp            # imm = 0x1F0
popq %rbp
retq
leaq -0xa8(%rbp), %rdi
callq 0x2100
leaq -0x88(%rbp), %rdi
callq 0x2100
leaq -0x68(%rbp), %rdi
callq 0x5500
movq -0x100(%rbp), %rdi
callq 0x22c0
nopw %cs:(%rax,%rax)