// File: mbottini[P]CS250lab2/main.cpp
// Function: evalExpression(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, 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&)
string evalExpression(const string& arg1, const string& arg2,
                           const string& op, const boolMap& bmap) {
    bool bArg1, bArg2;
    std::string result;

    if(op == "") {
        bArg1 = bmap.at(arg1);
        if(bArg1) {
            return "t";
        }

        else {
            return "c";
        }
    }

    else if(op == "!") {
        bArg1 = bmap.at(arg1);
        if(bArg1) {
            result = "c";
        }

        else {
            result = "t";
        }
    }

    else {
        bArg1 = bmap.at(arg1);
        bArg2 = bmap.at(arg2);

        // Logical AND.
        if(op == "^") {
            if(bArg1 && bArg2) {
                result = "t";
            }

            else {
                result = "c";
            }
        }

        // Logical OR.
        else if(op == "v") {
            if(bArg1 || bArg2) {
                result = "t";
            }

            else {
                result = "c";
            }
        }

        // Logical XOR.
        else if(op == "XOR") {
            if((bArg1 || bArg2) && !(bArg1 && bArg2)) {
                result = "t";
            }

            else {
                result = "c";
            }
        }

        // Implies operator.
        else if(op == "->") {
            if(!bArg1 || bArg2) {
                result = "t";
            }

            else {
                result = "c";
            }
        }

        // If and only if operator.
        else if(op == "<->") {
            if((bArg1 && bArg2) || (!bArg1 && !bArg2)) {
                result = "t";
            }

            else {
                result = "c";
            }
        }

        else {
            std::cout << "Invalid operator!\n";
            result = "c";
        }
    }

    // std::cout << result << "\n";
    return result;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x78(%rbp)
movq %rdi, %rax
movq %rax, -0x70(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x2240
movq -0x20(%rbp), %rdi
leaq 0x7797(%rip), %rsi      # 0xc105
callq 0x5140
movb %al, -0x66(%rbp)
jmp 0x4978
movb -0x66(%rbp), %al
testb $0x1, %al
jne 0x4984
jmp 0x4a69
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x55d0
movq %rax, -0x80(%rbp)
jmp 0x4997
movq -0x80(%rbp), %rax
movb (%rax), %al
andb $0x1, %al
movb %al, -0x29(%rbp)
testb $0x1, -0x29(%rbp)
je 0x4a11
leaq -0x5d(%rbp), %rdi
movq %rdi, -0x88(%rbp)
callq 0x22d0
movq -0x78(%rbp), %rdi
movq -0x88(%rbp), %rdx
leaq 0x77e2(%rip), %rsi      # 0xc1ac
callq 0x2230
jmp 0x49d1
leaq -0x5d(%rbp), %rdi
callq 0x21d0
movl $0x1, -0x64(%rbp)
jmp 0x4d5b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x4d71
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x5d(%rbp), %rdi
callq 0x21d0
jmp 0x4d71
leaq -0x65(%rbp), %rdi
movq %rdi, -0x90(%rbp)
callq 0x22d0
movq -0x78(%rbp), %rdi
movq -0x90(%rbp), %rdx
leaq 0x75f8(%rip), %rsi      # 0xc02b
callq 0x2230
jmp 0x4a3a
leaq -0x65(%rbp), %rdi
callq 0x21d0
movl $0x1, -0x64(%rbp)
jmp 0x4d5b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x65(%rbp), %rdi
callq 0x21d0
jmp 0x4d71
movq -0x20(%rbp), %rdi
leaq 0x75c8(%rip), %rsi      # 0xc03c
callq 0x5140
movb %al, -0x91(%rbp)
jmp 0x4a81
movb -0x91(%rbp), %al
testb $0x1, %al
jne 0x4a8d
jmp 0x4ae4
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x55d0
movq %rax, -0xa0(%rbp)
jmp 0x4aa3
movq -0xa0(%rbp), %rax
movb (%rax), %al
andb $0x1, %al
movb %al, -0x29(%rbp)
testb $0x1, -0x29(%rbp)
je 0x4acb
leaq 0x756d(%rip), %rsi      # 0xc02b
leaq -0x50(%rbp), %rdi
callq 0x2220
jmp 0x4ac9
jmp 0x4adf
leaq 0x76da(%rip), %rsi      # 0xc1ac
leaq -0x50(%rbp), %rdi
callq 0x2220
jmp 0x4add
jmp 0x4adf
jmp 0x4d45
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x55d0
movq %rax, -0xa8(%rbp)
jmp 0x4afa
movq -0xa8(%rbp), %rax
movb (%rax), %al
andb $0x1, %al
movb %al, -0x29(%rbp)
movq -0x28(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x55d0
movq %rax, -0xb0(%rbp)
jmp 0x4b1e
movq -0xb0(%rbp), %rax
movb (%rax), %al
andb $0x1, %al
movb %al, -0x2a(%rbp)
movq -0x20(%rbp), %rdi
leaq 0x7581(%rip), %rsi      # 0xc0b8
callq 0x5140
movb %al, -0xb1(%rbp)
jmp 0x4b44
movb -0xb1(%rbp), %al
testb $0x1, %al
jne 0x4b50
jmp 0x4b89
testb $0x1, -0x29(%rbp)
je 0x4b70
testb $0x1, -0x2a(%rbp)
je 0x4b70
leaq 0x7649(%rip), %rsi      # 0xc1ac
leaq -0x50(%rbp), %rdi
callq 0x2220
jmp 0x4b6e
jmp 0x4b84
leaq 0x74b4(%rip), %rsi      # 0xc02b
leaq -0x50(%rbp), %rdi
callq 0x2220
jmp 0x4b82
jmp 0x4b84
jmp 0x4d43
movq -0x20(%rbp), %rdi
leaq 0x7522(%rip), %rsi      # 0xc0b6
callq 0x5140
movb %al, -0xb2(%rbp)
jmp 0x4ba1
movb -0xb2(%rbp), %al
testb $0x1, %al
jne 0x4bad
jmp 0x4be6
testb $0x1, -0x29(%rbp)
jne 0x4bb9
testb $0x1, -0x2a(%rbp)
je 0x4bcd
leaq 0x75ec(%rip), %rsi      # 0xc1ac
leaq -0x50(%rbp), %rdi
callq 0x2220
jmp 0x4bcb
jmp 0x4be1
leaq 0x7457(%rip), %rsi      # 0xc02b
leaq -0x50(%rbp), %rdi
callq 0x2220
jmp 0x4bdf
jmp 0x4be1
jmp 0x4d41
movq -0x20(%rbp), %rdi
leaq 0x74bd(%rip), %rsi      # 0xc0ae
callq 0x5140
movb %al, -0xb3(%rbp)
jmp 0x4bfe
movb -0xb3(%rbp), %al
testb $0x1, %al
jne 0x4c0a
jmp 0x4c4f
testb $0x1, -0x29(%rbp)
jne 0x4c16
testb $0x1, -0x2a(%rbp)
je 0x4c36
testb $0x1, -0x29(%rbp)
je 0x4c22
testb $0x1, -0x2a(%rbp)
jne 0x4c36
leaq 0x7583(%rip), %rsi      # 0xc1ac
leaq -0x50(%rbp), %rdi
callq 0x2220
jmp 0x4c34
jmp 0x4c4a
leaq 0x73ee(%rip), %rsi      # 0xc02b
leaq -0x50(%rbp), %rdi
callq 0x2220
jmp 0x4c48
jmp 0x4c4a
jmp 0x4d3f
movq -0x20(%rbp), %rdi
leaq 0x7459(%rip), %rsi      # 0xc0b3
callq 0x5140
movb %al, -0xb4(%rbp)
jmp 0x4c67
movb -0xb4(%rbp), %al
testb $0x1, %al
jne 0x4c73
jmp 0x4cac
testb $0x1, -0x29(%rbp)
je 0x4c7f
testb $0x1, -0x2a(%rbp)
je 0x4c93
leaq 0x7526(%rip), %rsi      # 0xc1ac
leaq -0x50(%rbp), %rdi
callq 0x2220
jmp 0x4c91
jmp 0x4ca7
leaq 0x7391(%rip), %rsi      # 0xc02b
leaq -0x50(%rbp), %rdi
callq 0x2220
jmp 0x4ca5
jmp 0x4ca7
jmp 0x4d3d
movq -0x20(%rbp), %rdi
leaq 0x73fb(%rip), %rsi      # 0xc0b2
callq 0x5140
movb %al, -0xb5(%rbp)
jmp 0x4cc4
movb -0xb5(%rbp), %al
testb $0x1, %al
jne 0x4cd0
jmp 0x4d12
testb $0x1, -0x29(%rbp)
je 0x4cdc
testb $0x1, -0x2a(%rbp)
jne 0x4ce8
testb $0x1, -0x29(%rbp)
jne 0x4cfc
testb $0x1, -0x2a(%rbp)
jne 0x4cfc
leaq 0x74bd(%rip), %rsi      # 0xc1ac
leaq -0x50(%rbp), %rdi
callq 0x2220
jmp 0x4cfa
jmp 0x4d10
leaq 0x7328(%rip), %rsi      # 0xc02b
leaq -0x50(%rbp), %rdi
callq 0x2220
jmp 0x4d0e
jmp 0x4d10
jmp 0x4d3b
movq 0xd2b7(%rip), %rdi      # 0x11fd0
leaq 0x746f(%rip), %rsi      # 0xc18f
callq 0x2190
jmp 0x4d27
leaq 0x72fd(%rip), %rsi      # 0xc02b
leaq -0x50(%rbp), %rdi
callq 0x2220
jmp 0x4d39
jmp 0x4d3b
jmp 0x4d3d
jmp 0x4d3f
jmp 0x4d41
jmp 0x4d43
jmp 0x4d45
jmp 0x4d47
movq -0x78(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x20f0
movl $0x1, -0x64(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x2100
movq -0x70(%rbp), %rax
addq $0xc0, %rsp
popq %rbp
retq
leaq -0x50(%rbp), %rdi
callq 0x2100
movq -0x58(%rbp), %rdi
callq 0x22c0
nopw %cs:(%rax,%rax)
nopl (%rax)