// File: /workspace/github_c_makefile_star2_O3/jiribenes[P]scheme/src/write.c
// Function: write
void write(FILE *f, value_t val) {
    if (IS_NUM(val)) {
        write_number(f, AS_NUM(val));
    } else if (IS_NIL(val)) {
        fprintf(f, "()");
    } else if (IS_TRUE(val)) {
        fprintf(f, "#t");
    } else if (IS_FALSE(val)) {
        fprintf(f, "#f");
    } else if (IS_UNDEFINED(val)) {
        fprintf(f, "#<undefined>");
    } else if (IS_VOID(val)) {
        fprintf(f, "#<void>");
    } else if (IS_EOF(val)) {
        fprintf(f, "#<eof>");
    } else if (IS_PTR(val)) {
        if (IS_CONS(val)) {
            cons_t *cons = AS_CONS(val);

            fprintf(f, "(");
            write_cons(f, cons);
            fprintf(f, ")");
        } else if (IS_STRING(val)) {
            string_t *str = AS_STRING(val);
            write_string(f, str);
        } else if (IS_SYMBOL(val)) {
            symbol_t *sym = AS_SYMBOL(val);
            fprintf(f, "%s", sym->name);
        } else if (IS_PRIMITIVE(val)) {
            // TODO: A lot of repetition going on here, can we shorten this?
            primitive_t *prim = AS_PRIMITIVE(val);
            fprintf(f, "#<primitive ");
            if (prim->name != NULL) {
                display(f, PTR_VAL(prim->name));
            } else {
                fprintf(f, "?");
            }
            fprintf(f, ">");
        } else if (IS_FUNCTION(val)) {
            fprintf(f, "#<function ");
            function_t *fn = AS_FUNCTION(val);
            if (fn->name != NULL) {
                display(f, PTR_VAL(fn->name));
            } else {
                fprintf(f, "?");
            }
            fprintf(f, " ");
            write(f, fn->params);
            fprintf(f, ">");
        } else if (IS_MACRO(val)) {
            fprintf(f, "#<macro ");
            function_t *mac = AS_MACRO(val);
            if (mac->name != NULL) {
                display(f, PTR_VAL(mac->name));
            } else {
                fprintf(f, "?");
            }
            fprintf(f, ">");
        } else if (IS_VECTOR(val)) {
            vector_t *vec = AS_VECTOR(val);
            write_vector(f, vec);
        } else if (IS_ENV(val)) {
            env_t *env = (env_t *) AS_PTR(val);
            fprintf(f, "#<");
            if (env == NULL) {
                fprintf(f, "top level ");
            }
            fprintf(f, "environment>");
        } else {
            fprintf(f, "#<unknown ptrvalue>");
        }
    } else {
        fprintf(f, "#<unknown value>");
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rsi, %r14
movq %rdi, %rbx
movq %rsi, %rax
notq %rax
movabsq $0x7ffc000000000000, %rcx # imm = 0x7FFC000000000000
testq %rcx, %rax
jne 0x5a4f
movabsq $-0x7ffc000000000001, %rax # imm = 0x8003FFFFFFFFFFFF
addq %r14, %rax
cmpq $0x5, %rax
ja 0x5af5
leaq 0x12ee(%rip), %rcx      # 0x6d28
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x1316(%rip), %rdi      # 0x6d60
jmp 0x5ad0
movq %r14, %xmm0
ucomisd %xmm0, %xmm0
jp 0x5ca4
btrq $0x3f, %r14
movabsq $0x7ff0000000000000, %rax # imm = 0x7FF0000000000000
cmpq %rax, %r14
jne 0x5a85
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x5a9b
leaq 0x1370(%rip), %rdi      # 0x6df3
jmp 0x5ade
leaq 0x1375(%rip), %rsi      # 0x6e01
movq %rbx, %rdi
movb $0x1, %al
popq %rbx
popq %r14
popq %r15
jmp 0x1130
leaq 0x1358(%rip), %rdi      # 0x6dfa
jmp 0x5ade
leaq 0x12cb(%rip), %rdi      # 0x6d76
movl $0x7, %esi
jmp 0x5ae3
leaq 0x12ad(%rip), %rdi      # 0x6d66
jmp 0x5ad0
leaq 0x12a7(%rip), %rdi      # 0x6d69
movl $0xc, %esi
jmp 0x5ae3
leaq 0x1293(%rip), %rdi      # 0x6d63
movl $0x2, %esi
jmp 0x5ae3
leaq 0x12a0(%rip), %rdi      # 0x6d7e
movl $0x6, %esi
movl $0x1, %edx
movq %rbx, %rcx
popq %rbx
popq %r14
popq %r15
jmp 0x11c0
movabsq $-0x4000000000000, %r15 # imm = 0xFFFC000000000000
leaq -0x1(%r15), %rax
cmpq %rax, %r14
jbe 0x5b54
movabsq $0x3ffffffffffff, %rax  # imm = 0x3FFFFFFFFFFFF
andq %rax, %r14
movl (%r14), %eax
cmpq $0x7, %rax
ja 0x5c4c
leaq 0x1217(%rip), %rcx      # 0x6d40
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x28, %edi
movq %rbx, %rsi
callq 0x1100
movq %rbx, %rdi
movq %r14, %rsi
callq 0x5cb0
movl $0x29, %edi
jmp 0x5c97
leaq 0x127b(%rip), %rdi      # 0x6dd6
movl $0x10, %esi
jmp 0x5ae3
leaq 0x1229(%rip), %rdi      # 0x6d92
movl $0xb, %esi
movl $0x1, %edx
movq %rbx, %rcx
callq 0x11c0
movq 0x10(%r14), %rsi
testq %rsi, %rsi
je 0x5c6c
orq %r15, %rsi
movq %rbx, %rdi
callq 0x5e3b
jmp 0x5c79
addq $0x20, %r14
movq %r14, %rdi
movq %rbx, %rsi
popq %rbx
popq %r14
popq %r15
jmp 0x10d0
leaq 0x11d2(%rip), %rdi      # 0x6d85
movl $0xc, %esi
jmp 0x5c19
leaq 0x11e6(%rip), %rdi      # 0x6da7
movl $0x2, %esi
movl $0x1, %edx
movq %rbx, %rcx
callq 0x11c0
testq %r14, %r14
jne 0x5bf1
leaq 0x11cb(%rip), %rdi      # 0x6daa
movl $0xa, %esi
movl $0x1, %edx
movq %rbx, %rcx
callq 0x11c0
leaq 0x11bd(%rip), %rdi      # 0x6db5
jmp 0x5ac2
movq %rbx, %rdi
movq %r14, %rsi
popq %rbx
popq %r14
popq %r15
jmp 0x5d83
leaq 0x118a(%rip), %rdi      # 0x6d9e
movl $0x8, %esi
movl $0x1, %edx
movq %rbx, %rcx
callq 0x11c0
movq 0x10(%r14), %rsi
testq %rsi, %rsi
je 0x5c5d
orq %r15, %rsi
movq %rbx, %rdi
callq 0x5e3b
jmp 0x5c92
movq %rbx, %rdi
movq %r14, %rsi
popq %rbx
popq %r14
popq %r15
jmp 0x5e88
leaq 0x116f(%rip), %rdi      # 0x6dc2
movl $0x13, %esi
jmp 0x5ae3
movl $0x3f, %edi
movq %rbx, %rsi
callq 0x1100
jmp 0x5c92
movl $0x3f, %edi
movq %rbx, %rsi
callq 0x1100
movl $0x20, %edi
movq %rbx, %rsi
callq 0x1100
movq 0x20(%r14), %rsi
movq %rbx, %rdi
callq 0x59fc
movl $0x3e, %edi
movq %rbx, %rsi
popq %rbx
popq %r14
popq %r15
jmp 0x1100
leaq 0x1141(%rip), %rdi      # 0x6dec
jmp 0x5ade