// File: /workspace/github_cpp_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq 0x8(%rdi), %rbx
movq 0x10(%rdi), %rax
movq %rax, %r14
subq %rbx, %r14
movq 0x8(%rsi), %r15
movq 0x10(%rsi), %rcx
subq %r15, %rcx
cmpq %rcx, %r14
jne 0x70e6
cmpq %rbx, %rax
je 0x70ea
sarq $0x3, %r14
cmpq $0x1, %r14
movq %r14, %r12
adcq $0x0, %r12
xorl %r13d, %r13d
leaq 0x7ffd(%rip), %r8       # 0xf058
movq (%rbx,%r13,8), %rdi
movl (%rdi), %eax
movq (%r15,%r13,8), %rsi
movl (%rsi), %ecx
cmpl %ecx, %eax
jne 0x7085
cmpl $0x7, %eax
ja 0x708a
movl %eax, %eax
movslq (%r8,%rax,4), %rax
addq %r8, %rax
jmpq *%rax
movl 0x4(%rdi), %eax
cmpl 0x4(%rsi), %eax
je 0x708a
jmp 0x70e6
cmpl $0x3, %ecx
jne 0x70e6
incq %r13
cmpq %r13, %r12
jne 0x705b
jmp 0x70ee
movb 0x4(%rdi), %al
cmpb 0x4(%rsi), %al
je 0x708a
jmp 0x70e6
movss 0x4(%rdi), %xmm0
ucomiss 0x4(%rsi), %xmm0
jne 0x70e6
jnp 0x708a
jmp 0x70e6
movq 0x10(%rdi), %rdx
cmpq 0x10(%rsi), %rdx
jne 0x70e6
testq %rdx, %rdx
je 0x708a
movq 0x8(%rsi), %rsi
movq 0x8(%rdi), %rdi
callq 0x31d0
leaq 0x7f88(%rip), %r8       # 0xf058
testl %eax, %eax
je 0x708a
jmp 0x70e6
callq 0x7009
leaq 0x7f76(%rip), %r8       # 0xf058
testb %al, %al
jne 0x708a
xorl %eax, %eax
jmp 0x70f4
movb $0x1, %al
jmp 0x70f4
cmpq %r14, %r13
setae %al
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq