// File: /workspace/github_c_makefile_star2_O0/jiribenes[P]scheme/src/value.c
// Function: val_equal
bool val_equal(value_t a, value_t b) {
    if (val_eq(a, b)) {
        return true;
    }

    if (IS_VAL(a) || IS_VAL(b)) {
        // if both are only plain values,
        // they should have been equal by <eq?>
        return false;
    }

    ptrvalue_t *pa = AS_PTR(a);
    ptrvalue_t *pb = AS_PTR(b);

    if (pa->type != pb->type) {
        return false;
    }

    if (pa->type == T_CONS) {
        cons_t *consa = (cons_t *) pa;
        cons_t *consb = (cons_t *) pb;

        return val_equal(consa->car, consb->car) &&
               val_equal(consa->cdr, consb->cdr);
    } else if (pa->type == T_STRING) {
        string_t *stra = (string_t *) pa;
        string_t *strb = (string_t *) pb;

        return stra->len == strb->len && stra->hash == strb->hash &&
               memcmp(stra->value, strb->value, stra->len * sizeof(char)) == 0;

    } else if (pa->type == T_SYMBOL) {
        symbol_t *syma = (symbol_t *) pa;
        symbol_t *symb = (symbol_t *) pb;
        if ((syma->len == symb->len) &&
            (memcmp(syma->name, symb->name, syma->len * sizeof(char)) == 0)) {
            // we should never get here! - two symbols with same name are eq?
            fprintf(stderr, "Error: symbol not interned!");
        }
        return false;
    } else if (pa->type == T_VECTOR) {
        vector_t *veca = (vector_t *) pa;
        vector_t *vecb = (vector_t *) pb;

        if (veca->count != vecb->count) {
            return false;
        }

        for (uint32_t i = 0; i < veca->count; i++) {
            if (!val_equal(veca->data[i], vecb->data[i])) {
                return false;
            }
        }
        return true;
    }

    return false;
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x68(%rsp)
movq %rsi, 0x60(%rsp)
movq 0x68(%rsp), %rdi
movq 0x60(%rsp), %rsi
callq 0x6f70
testb $0x1, %al
jne 0x7083
jmp 0x708d
movb $0x1, 0x77(%rsp)
jmp 0x7333
movabsq $-0x4000000000000, %rax # imm = 0xFFFC000000000000
andq 0x68(%rsp), %rax
movabsq $-0x4000000000000, %rcx # imm = 0xFFFC000000000000
cmpq %rcx, %rax
jne 0x70c9
movabsq $-0x4000000000000, %rax # imm = 0xFFFC000000000000
andq 0x60(%rsp), %rax
movabsq $-0x4000000000000, %rcx # imm = 0xFFFC000000000000
cmpq %rcx, %rax
je 0x70d3
movb $0x0, 0x77(%rsp)
jmp 0x7333
movabsq $0x3ffffffffffff, %rax  # imm = 0x3FFFFFFFFFFFF
andq 0x68(%rsp), %rax
movq %rax, 0x58(%rsp)
movabsq $0x3ffffffffffff, %rax  # imm = 0x3FFFFFFFFFFFF
andq 0x60(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x58(%rsp), %rax
movl (%rax), %eax
movq 0x50(%rsp), %rcx
cmpl (%rcx), %eax
je 0x7115
movb $0x0, 0x77(%rsp)
jmp 0x7333
movq 0x58(%rsp), %rax
cmpl $0x0, (%rax)
jne 0x7183
movq 0x58(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x50(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x48(%rsp), %rax
movq 0x10(%rax), %rdi
movq 0x40(%rsp), %rax
movq 0x10(%rax), %rsi
callq 0x7060
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, 0xb(%rsp)
jne 0x7159
jmp 0x7174
movq 0x48(%rsp), %rax
movq 0x18(%rax), %rdi
movq 0x40(%rsp), %rax
movq 0x18(%rax), %rsi
callq 0x7060
movb %al, 0xb(%rsp)
movb 0xb(%rsp), %al
andb $0x1, %al
movb %al, 0x77(%rsp)
jmp 0x7333
movq 0x58(%rsp), %rax
cmpl $0x1, (%rax)
jne 0x7213
movq 0x58(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x50(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x38(%rsp), %rax
movl 0x10(%rax), %ecx
movq 0x30(%rsp), %rdx
xorl %eax, %eax
cmpl 0x10(%rdx), %ecx
movb %al, 0xa(%rsp)
jne 0x7204
movq 0x38(%rsp), %rax
movl 0x14(%rax), %ecx
movq 0x30(%rsp), %rdx
xorl %eax, %eax
cmpl 0x14(%rdx), %ecx
movb %al, 0xa(%rsp)
jne 0x7204
movq 0x38(%rsp), %rdi
addq $0x18, %rdi
movq 0x30(%rsp), %rsi
addq $0x18, %rsi
movq 0x38(%rsp), %rax
movl 0x10(%rax), %eax
movl %eax, %edx
shlq $0x0, %rdx
callq 0x10f0
cmpl $0x0, %eax
sete %al
movb %al, 0xa(%rsp)
movb 0xa(%rsp), %al
andb $0x1, %al
movb %al, 0x77(%rsp)
jmp 0x7333
movq 0x58(%rsp), %rax
cmpl $0x2, (%rax)
jne 0x728f
movq 0x58(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x50(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x28(%rsp), %rax
movl 0x10(%rax), %eax
movq 0x20(%rsp), %rcx
cmpl 0x10(%rcx), %eax
jne 0x7285
movq 0x28(%rsp), %rdi
addq $0x20, %rdi
movq 0x20(%rsp), %rsi
addq $0x20, %rsi
movq 0x28(%rsp), %rax
movl 0x10(%rax), %eax
movl %eax, %edx
shlq $0x0, %rdx
callq 0x10f0
cmpl $0x0, %eax
jne 0x7285
movq 0x6d84(%rip), %rax      # 0xdff8
movq (%rax), %rdi
leaq 0x3728(%rip), %rsi      # 0xa9a6
movb $0x0, %al
callq 0x1120
movb $0x0, 0x77(%rsp)
jmp 0x7333
movq 0x58(%rsp), %rax
cmpl $0x6, (%rax)
jne 0x7328
movq 0x58(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x50(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x18(%rsp), %rax
movl 0x14(%rax), %eax
movq 0x10(%rsp), %rcx
cmpl 0x14(%rcx), %eax
je 0x72ca
movb $0x0, 0x77(%rsp)
jmp 0x7333
movl $0x0, 0xc(%rsp)
movl 0xc(%rsp), %eax
movq 0x18(%rsp), %rcx
cmpl 0x14(%rcx), %eax
jae 0x7321
movq 0x18(%rsp), %rax
movq 0x18(%rax), %rax
movl 0xc(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
movq 0x10(%rsp), %rax
movq 0x18(%rax), %rax
movl 0xc(%rsp), %ecx
movq (%rax,%rcx,8), %rsi
callq 0x7060
testb $0x1, %al
jne 0x7312
movb $0x0, 0x77(%rsp)
jmp 0x7333
jmp 0x7314
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
jmp 0x72d2
movb $0x1, 0x77(%rsp)
jmp 0x7333
jmp 0x732a
jmp 0x732c
jmp 0x732e
movb $0x0, 0x77(%rsp)
movb 0x77(%rsp), %al
andb $0x1, %al
addq $0x78, %rsp
retq
nop