// File: BlinfoldKing[P]lisval/src/lib/evaluator.cpp
// Function: compareList(List*, List*)
bool compareList(List* input, List* signature) {
    if (input->list.size() != signature->list.size()) {
        return false;
    }

    for (size_t i = 0; i < input->list.size(); i++) {
        if (input->list[i]->type != signature->list[i]->type) {
            if (signature->list[i]->type != TokenType::VARIABLE) {
               return false;
            }

            continue;
        } else {
            if (input->list[i]->type == TokenType::NUMBER) {
                Number* inp = static_cast<Number*>(input->list[i]);
                Number* sig = static_cast<Number*>(signature->list[i]);

                if (inp->value != sig->value) {
                    return false;
                }
            }

            if (input->list[i]->type == TokenType::BOOLEAN) {
                Boolean* inp = static_cast<Boolean*>(input->list[i]);
                Boolean* sig = static_cast<Boolean*>(signature->list[i]);

                if (inp->value != sig->value) {
                    return false;
                }
            }

            if (input->list[i]->type == TokenType::ATOM) {
                Atom* inp = static_cast<Atom*>(input->list[i]);
                Atom* sig = static_cast<Atom*>(signature->list[i]);

                if (inp->str != sig->str) {
                    return false;
                }
            }

            if (input->list[i]->type == TokenType::LIST) {
                List* inp = static_cast<List*>(input->list[i]);
                List* sig = static_cast<List*>(signature->list[i]);

                if (!compareList(inp, sig)) {
                    return false;
                }
            }

            if (input->list[i]->type == TokenType::UNARY_OPERATOR) {
                UnaryOperator* inp = static_cast<UnaryOperator*>(input->list[i]);
                UnaryOperator* sig = static_cast<UnaryOperator*>(signature->list[i]);

                if (inp->operator_type != sig->operator_type) {
                    return false;
                }
            }

            if (input->list[i]->type == TokenType::BINARY_OPERATOR) {
                BinaryOperator* inp = static_cast<BinaryOperator*>(input->list[i]);
                BinaryOperator* sig = static_cast<BinaryOperator*>(signature->list[i]);

                if (inp->operator_type != sig->operator_type) {
                    return false;
                }
            }
        }
    }


    return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
callq 0x11a60
movq %rax, -0x88(%rbp)
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
callq 0x11a60
movq %rax, %rcx
movq -0x88(%rbp), %rax
cmpq %rcx, %rax
je 0x90dc
movb $0x0, -0x1(%rbp)
jmp 0x93fe
movq $0x0, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
callq 0x11a60
movq %rax, %rcx
movq -0x90(%rbp), %rax
cmpq %rcx, %rax
jae 0x93fa
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
movl (%rax), %eax
movl %eax, -0x94(%rbp)
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq %rax, %rcx
movl -0x94(%rbp), %eax
movq (%rcx), %rcx
cmpl (%rcx), %eax
je 0x9173
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
cmpl $0x3, (%rax)
je 0x916e
movb $0x0, -0x1(%rbp)
jmp 0x93fe
jmp 0x93e9
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
cmpl $0x2, (%rax)
jne 0x91de
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rax
movss 0x4(%rax), %xmm0
movq -0x30(%rbp), %rax
ucomiss 0x4(%rax), %xmm0
jne 0x91d3
jp 0x91d3
jmp 0x91dc
movb $0x0, -0x1(%rbp)
jmp 0x93fe
jmp 0x91de
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
cmpl $0x7, (%rax)
jne 0x924f
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rax
movb 0x4(%rax), %al
andb $0x1, %al
movzbl %al, %eax
movq -0x40(%rbp), %rcx
movb 0x4(%rcx), %cl
andb $0x1, %cl
movzbl %cl, %ecx
cmpl %ecx, %eax
je 0x924d
movb $0x0, -0x1(%rbp)
jmp 0x93fe
jmp 0x924f
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
cmpl $0x0, (%rax)
jne 0x92be
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rdi
addq $0x8, %rdi
movq -0x50(%rbp), %rsi
addq $0x8, %rsi
callq 0x11f60
testb $0x1, %al
jne 0x92b3
jmp 0x92bc
movb $0x0, -0x1(%rbp)
jmp 0x93fe
jmp 0x92be
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
cmpl $0x1, (%rax)
jne 0x9323
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x58(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0x9090
testb $0x1, %al
jne 0x9321
movb $0x0, -0x1(%rbp)
jmp 0x93fe
jmp 0x9323
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
cmpl $0x4, (%rax)
jne 0x9384
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
movq %rax, -0x70(%rbp)
movq -0x68(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x70(%rbp), %rcx
cmpl 0x4(%rcx), %eax
je 0x9382
movb $0x0, -0x1(%rbp)
jmp 0x93fe
jmp 0x9384
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
cmpl $0x5, (%rax)
jne 0x93e5
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
movq %rax, -0x78(%rbp)
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
movq -0x20(%rbp), %rsi
callq 0x11a80
movq (%rax), %rax
movq %rax, -0x80(%rbp)
movq -0x78(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x80(%rbp), %rcx
cmpl 0x4(%rcx), %eax
je 0x93e3
movb $0x0, -0x1(%rbp)
jmp 0x93fe
jmp 0x93e5
jmp 0x93e7
jmp 0x93e9
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x90e4
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xa0, %rsp
popq %rbp
retq
nopl (%rax)