// File: /workspace/github_c_makefile_star2_O2/voithos[P]awl/src/types.c
// Function: awlval_convert
awlval* awlval_convert(awlval_type_t t, const awlval* v) {
    if (v->type == t) {
        return awlval_copy(v);
    }

    switch (t) {
        case AWLVAL_INT:
            switch (v->type) {
                case AWLVAL_FLOAT:
                    return awlval_int((long)v->dbl);
                    break;

                case AWLVAL_STR:
                    {
                        errno = 0;
                        char* strend = v->str;
                        long x = strtol(v->str, &strend, 10);
                        return errno != ERANGE && *strend == '\0' ? awlval_int(x) : awlval_err("invalid number: %s", v->str);
                    }
                    break;

                case AWLVAL_BOOL:
                    return awlval_int(v->bln);
                    break;

                default:
                    return awlval_err("a direct conversion from type %s to type %s does not exist",
                            awlval_type_name(v->type), awlval_type_name(t));
                    break;
            }
            break;

        case AWLVAL_FLOAT:
            switch (v->type) {
                case AWLVAL_INT:
                    return awlval_float((double)v->lng);
                    break;

                case AWLVAL_STR:
                    {
                        errno = 0;
                        char* strend = v->str;
                        double x = strtod(v->str, &strend);
                        return errno != ERANGE && *strend == '\0' ? awlval_float(x) : awlval_err("invalid float: %s", v->str);
                    }
                    break;

                case AWLVAL_BOOL:
                    return awlval_float((double)v->bln);
                    break;

                default:
                    return awlval_err("a direct conversion from type %s to type %s does not exist",
                            awlval_type_name(v->type), awlval_type_name(t));
                    break;
            }
            break;

        case AWLVAL_STR:
            if (v->type == AWLVAL_QSYM) {
                return awlval_str(v->sym);
            } else {
                char* str = awlval_to_str(v);
                awlval* res = awlval_str(str);
                free(str);
                return res;
            }
            break;

        case AWLVAL_BOOL:
            switch (v->type) {
                case AWLVAL_INT:
                    return awlval_bool(v->lng != 0 ? true : false);
                    break;

                case AWLVAL_FLOAT:
                    return awlval_bool(v->dbl != 0.0 ? true : false);
                    break;

                default:
                    return awlval_err("a direct conversion from type %s to type %s does not exist",
                            awlval_type_name(v->type), awlval_type_name(t));
                    break;
            }
            break;

        case AWLVAL_QSYM:
            switch (v->type) {
                case AWLVAL_STR:
                    return awlval_qsym(v->str);
                    break;

                default:
                    return awlval_err("a direct conversion from type %s to type %s does not exist",
                            awlval_type_name(v->type), awlval_type_name(t));
                    break;
            }
            break;

        default:
            return awlval_err("no type can be directly converted to type %s", awlval_type_name(t));
            break;
    }
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movl %edi, %eax
movl (%rsi), %edi
cmpl %eax, %edi
jne 0xe658
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0xe16d
cmpl $0x6, %eax
ja 0xe695
movl %eax, %ecx
leaq 0x305a(%rip), %rdx      # 0x116c0
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
cmpl $0x6, %edi
je 0xe7fb
cmpl $0x5, %edi
je 0xe77b
cmpl $0x1, %edi
jne 0xe81f
cvttsd2si 0x18(%rbx), %rdi
jmp 0xe7ff
movl %eax, %edi
callq 0xd97c
leaq 0x31c9(%rip), %rdi      # 0x1186c
movq %rax, %rsi
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0xdb45
cmpl $0x5, %edi
jne 0xe719
movq 0x18(%rbx), %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0xdce8
cmpl $0x6, %edi
je 0xe80b
cmpl $0x5, %edi
je 0xe7b8
testl %edi, %edi
jne 0xe82b
cvtsi2sdq 0x18(%rbx), %xmm0
jmp 0xe813
cmpl $0x4, %edi
jne 0xe728
movq 0x18(%rbx), %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0xdcf6
cmpl $0x1, %edi
je 0xe74e
testl %edi, %edi
jne 0xe76c
xorl %edi, %edi
cmpq $0x0, 0x18(%rbx)
setne %dil
jmp 0xe760
callq 0xd97c
movq %rax, %rbx
pushq $0x4
jmp 0xe835
movq %rbx, %rdi
callq 0xd498
movq %rax, %rbx
movq %rax, %rdi
callq 0xdcf6
movq %rax, %r14
movq %rbx, %rdi
callq 0x23f0
movq %r14, %rax
jmp 0xe7f3
xorpd %xmm0, %xmm0
cmpneqsd 0x18(%rbx), %xmm0
movq %xmm0, %rdi
andl $0x1, %edi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0xdd3e
callq 0xd97c
movq %rax, %rbx
pushq $0x6
jmp 0xe835
callq 0x2060
movq %rax, %r14
andl $0x0, (%rax)
movq 0x18(%rbx), %rdi
movq %rsp, %rsi
movq %rdi, (%rsi)
pushq $0xa
popq %rdx
callq 0x2260
cmpl $0x22, (%r14)
je 0xe7ab
movq (%rsp), %rcx
cmpb $0x0, (%rcx)
je 0xe856
movq 0x18(%rbx), %rsi
leaq 0x2da0(%rip), %rdi      # 0x11556
jmp 0xe7ec
callq 0x2060
movq %rax, %r14
andl $0x0, (%rax)
movq 0x18(%rbx), %rdi
movq %rsp, %rsi
movq %rdi, (%rsi)
callq 0x20b0
cmpl $0x22, (%r14)
je 0xe7e1
movq (%rsp), %rax
cmpb $0x0, (%rax)
je 0xe860
movq 0x18(%rbx), %rsi
leaq 0x2d7d(%rip), %rdi      # 0x11569
xorl %eax, %eax
callq 0xdb45
addq $0x8, %rsp
popq %rbx
popq %r14
retq
movzbl 0x18(%rbx), %edi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0xdc64
movsbl 0x18(%rbx), %eax
cvtsi2sd %eax, %xmm0
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0xdc79
callq 0xd97c
movq %rax, %rbx
xorl %edi, %edi
jmp 0xe836
callq 0xd97c
movq %rax, %rbx
pushq $0x1
popq %rdi
callq 0xd97c
leaq 0x2fef(%rip), %rdi      # 0x11831
movq %rbx, %rsi
movq %rax, %rdx
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0xdb45
movq %rax, %rdi
callq 0xdc64
jmp 0xe7f3
callq 0xdc79
jmp 0xe7f3