// File: /workspace/github_cpp_makefile_star2_O2/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 %r12
pushq %rbx
movq %rsi, %rbx
movq 0x8(%rdi), %rax
movq 0x10(%rdi), %rcx
movq %rcx, %rdx
subq %rax, %rdx
movq 0x10(%rsi), %rsi
subq 0x8(%rbx), %rsi
cmpq %rsi, %rdx
jne 0x5acc
movq %rdi, %r14
xorl %r12d, %r12d
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %rcx, %r12
setae %r15b
jae 0x5acf
movq (%rax,%r12,8), %rdi
movl (%rdi), %ecx
movq 0x8(%rbx), %rdx
movq (%rdx,%r12,8), %rsi
movl (%rsi), %edx
cmpl %edx, %ecx
jne 0x5a5a
testl %ecx, %ecx
je 0x5a6b
cmpl $0x7, %ecx
je 0x5a61
cmpl $0x2, %ecx
jne 0x5a86
movss 0x4(%rdi), %xmm0
ucomiss 0x4(%rsi), %xmm0
jne 0x5acf
jnp 0x5aa0
jmp 0x5acf
cmpl $0x3, %edx
je 0x5ac0
jmp 0x5acf
movb 0x4(%rdi), %cl
cmpb 0x4(%rsi), %cl
je 0x5aa0
jmp 0x5acf
addq $0x8, %rdi
addq $0x8, %rsi
callq 0x7614
testb %al, %al
jne 0x5acf
movq 0x8(%r14), %rax
movq (%rax,%r12,8), %rdi
movl (%rdi), %ecx
cmpl $0x1, %ecx
jne 0x5aa0
movq 0x8(%rbx), %rax
movq (%rax,%r12,8), %rsi
callq 0x59e2
testb %al, %al
je 0x5acf
movq 0x8(%r14), %rax
movq (%rax,%r12,8), %rcx
movl (%rcx), %edx
cmpl $0x5, %edx
je 0x5ab0
cmpl $0x4, %edx
jne 0x5ac0
movq 0x8(%rbx), %rdx
movq (%rdx,%r12,8), %rdx
movl 0x4(%rcx), %ecx
cmpl 0x4(%rdx), %ecx
jne 0x5acf
incq %r12
movq 0x10(%r14), %rcx
jmp 0x5a15
xorl %r15d, %r15d
movl %r15d, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq