// File: cphinton42[P]hinton-language/src/parse.cpp
// Function: make_number_ast(Token)
internal Number_AST make_number_ast(Token number)
{
    Number_AST result;
    result.type = AST_Type::number_ast;
    result.flags = 0;
    result.s = next_serial++;
    result.line_number = number.line_number;
    result.line_offset = number.line_offset;
    result.literal = number.contents;
    result.types_count = 0;
    result.resolved_type = nullptr;
    String literal = result.literal;
    u64 i_value = 0;
    
    // TODO: cleanup: better precision
    
    u64 i = 0;
    while(i < literal.count && '0' <= literal[i] && literal[i] <= '9')
    {
        i_value *= 10;
        i_value += literal[i] - '0';
        ++i;
    }
    
    if(i < literal.count)
    {
        assert(literal[i] == '.');
        ++i;
        
        f64 factor = 1.0;
        u64 fractional = 0;
        
        while(i < literal.count && '0' <= literal[i] && literal[i] <= '9')
        {
            fractional *= 10;
            fractional += literal[i] - '0';
            factor *= 0.1;
            ++i;
        }
        
        if(i < literal.count)
        {
            assert(literal[i] == 'e' || literal[i] == 'E');
            ++i;
            assert(i < literal.count);
            bool exponent_positive = true;
            if(literal[i] == '+')
            {
                exponent_positive = true;
            }
            else if(literal[i] == '-')
            {
                exponent_positive = false;
            }
            
            u64 exponent = 0;
            while(i < literal.count && '0' <= literal[i] && literal[i] <= '9')
            {
                exponent *= 10;
                exponent += literal[i] - '0';
                ++i;
            }
            
            if(exponent_positive)
            {
                for(u64 j = 0; j < exponent; ++j)
                {
                    factor *= 10.0;
                }
            }
            else
            {
                for(u64 j = 0; j < exponent; ++j)
                {
                    factor *= 0.1;
                }
            }
        }
        
        result.float_value = ((f64)i_value) + ((f64)fractional * factor);
        result.flags |= NUMBER_FLAG_FLOATLIKE;
    }
    else
    {
        result.int_value = i_value;
    }
    
    return result;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x60(%rbp)
movq %rdi, %rax
movq %rax, -0x58(%rbp)
leaq 0x10(%rbp), %rax
movw $0xd, (%rdi)
movw $0x0, 0x2(%rdi)
movl 0xb168(%rip), %ecx      # 0x1fc90
movl %ecx, %edx
addl $0x1, %edx
movl %edx, 0xb15d(%rip)      # 0x1fc90
movl %ecx, 0x4(%rdi)
movl 0x8(%rax), %ecx
movl %ecx, 0x8(%rdi)
movl 0xc(%rax), %ecx
movl %ecx, 0xc(%rdi)
movq 0x10(%rax), %rcx
movq %rcx, 0x20(%rdi)
movq 0x18(%rax), %rax
movq %rax, 0x28(%rdi)
movq $0x0, 0x10(%rdi)
movq $0x0, 0x18(%rdi)
movq 0x20(%rdi), %rax
movq %rax, -0x10(%rbp)
movq 0x28(%rdi), %rax
movq %rax, -0x8(%rbp)
movq $0x0, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x20(%rbp), %rcx
xorl %eax, %eax
cmpq -0x10(%rbp), %rcx
movb %al, -0x61(%rbp)
jae 0x14bc8
movq -0x20(%rbp), %rsi
leaq -0x10(%rbp), %rdi
callq 0x17130
movsbl (%rax), %edx
xorl %eax, %eax
movl $0x30, %ecx
cmpl %edx, %ecx
movb %al, -0x61(%rbp)
jg 0x14bc8
movq -0x20(%rbp), %rsi
leaq -0x10(%rbp), %rdi
callq 0x17130
movsbl (%rax), %eax
cmpl $0x39, %eax
setle %al
movb %al, -0x61(%rbp)
movb -0x61(%rbp), %al
testb $0x1, %al
jne 0x14bd1
jmp 0x14c08
imulq $0xa, -0x18(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x20(%rbp), %rsi
leaq -0x10(%rbp), %rdi
callq 0x17130
movsbl (%rax), %eax
subl $0x30, %eax
cltq
addq -0x18(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x14b82
movq -0x20(%rbp), %rax
cmpq -0x10(%rbp), %rax
jae 0x14f41
movq -0x20(%rbp), %rsi
leaq -0x10(%rbp), %rdi
callq 0x17130
movsbl (%rax), %eax
cmpl $0x2e, %eax
jne 0x14c2d
jmp 0x14c4c
leaq 0x65b8(%rip), %rdi      # 0x1b1ec
leaq 0x625e(%rip), %rsi      # 0x1ae99
movl $0x84, %edx
leaq 0x65b7(%rip), %rcx      # 0x1b1fe
callq 0x3080
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
movsd 0x50a8(%rip), %xmm0     # 0x19d08
movsd %xmm0, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x20(%rbp), %rcx
xorl %eax, %eax
cmpq -0x10(%rbp), %rcx
movb %al, -0x62(%rbp)
jae 0x14cb3
movq -0x20(%rbp), %rsi
leaq -0x10(%rbp), %rdi
callq 0x17130
movsbl (%rax), %edx
xorl %eax, %eax
movl $0x30, %ecx
cmpl %edx, %ecx
movb %al, -0x62(%rbp)
jg 0x14cb3
movq -0x20(%rbp), %rsi
leaq -0x10(%rbp), %rdi
callq 0x17130
movsbl (%rax), %eax
cmpl $0x39, %eax
setle %al
movb %al, -0x62(%rbp)
movb -0x62(%rbp), %al
testb $0x1, %al
jne 0x14cbc
jmp 0x14d05
imulq $0xa, -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x20(%rbp), %rsi
leaq -0x10(%rbp), %rdi
callq 0x17130
movsbl (%rax), %eax
subl $0x30, %eax
cltq
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movsd 0x5026(%rip), %xmm0     # 0x19d10
mulsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x28(%rbp)
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x14c6d
movq -0x20(%rbp), %rax
cmpq -0x10(%rbp), %rax
jae 0x14edf
movq -0x20(%rbp), %rsi
leaq -0x10(%rbp), %rdi
callq 0x17130
movsbl (%rax), %ecx
movb $0x1, %al
cmpl $0x65, %ecx
movb %al, -0x63(%rbp)
je 0x14d46
movq -0x20(%rbp), %rsi
leaq -0x10(%rbp), %rdi
callq 0x17130
movsbl (%rax), %eax
cmpl $0x45, %eax
sete %al
movb %al, -0x63(%rbp)
movb -0x63(%rbp), %al
testb $0x1, %al
jne 0x14d4f
jmp 0x14d51
jmp 0x14d70
leaq 0x64c8(%rip), %rdi      # 0x1b220
leaq 0x613a(%rip), %rsi      # 0x1ae99
movl $0x94, %edx
leaq 0x6493(%rip), %rcx      # 0x1b1fe
callq 0x3080
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x10(%rbp), %rax
jae 0x14d88
jmp 0x14da7
leaq 0x64b8(%rip), %rdi      # 0x1b247
leaq 0x6103(%rip), %rsi      # 0x1ae99
movl $0x96, %edx
leaq 0x645c(%rip), %rcx      # 0x1b1fe
callq 0x3080
movb $0x1, -0x31(%rbp)
movq -0x20(%rbp), %rsi
leaq -0x10(%rbp), %rdi
callq 0x17130
movsbl (%rax), %eax
cmpl $0x2b, %eax
jne 0x14dc6
movb $0x1, -0x31(%rbp)
jmp 0x14de1
movq -0x20(%rbp), %rsi
leaq -0x10(%rbp), %rdi
callq 0x17130
movsbl (%rax), %eax
cmpl $0x2d, %eax
jne 0x14ddf
movb $0x0, -0x31(%rbp)
jmp 0x14de1
movq $0x0, -0x40(%rbp)
movq -0x20(%rbp), %rcx
xorl %eax, %eax
cmpq -0x10(%rbp), %rcx
movb %al, -0x64(%rbp)
jae 0x14e2f
movq -0x20(%rbp), %rsi
leaq -0x10(%rbp), %rdi
callq 0x17130
movsbl (%rax), %edx
xorl %eax, %eax
movl $0x30, %ecx
cmpl %edx, %ecx
movb %al, -0x64(%rbp)
jg 0x14e2f
movq -0x20(%rbp), %rsi
leaq -0x10(%rbp), %rdi
callq 0x17130
movsbl (%rax), %eax
cmpl $0x39, %eax
setle %al
movb %al, -0x64(%rbp)
movb -0x64(%rbp), %al
testb $0x1, %al
jne 0x14e38
jmp 0x14e6f
imulq $0xa, -0x40(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x20(%rbp), %rsi
leaq -0x10(%rbp), %rdi
callq 0x17130
movsbl (%rax), %eax
subl $0x30, %eax
cltq
addq -0x40(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x14de9
testb $0x1, -0x31(%rbp)
je 0x14ea9
movq $0x0, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpq -0x40(%rbp), %rax
jae 0x14ea7
movsd 0x4e89(%rip), %xmm0     # 0x19d18
mulsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x28(%rbp)
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x14e7d
jmp 0x14edd
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
cmpq -0x40(%rbp), %rax
jae 0x14edb
movsd 0x4e4d(%rip), %xmm0     # 0x19d10
mulsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x28(%rbp)
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x14eb1
jmp 0x14edd
jmp 0x14edf
movq -0x60(%rbp), %rax
movq -0x18(%rbp), %xmm1
movaps 0x4e31(%rip), %xmm3     # 0x19d20
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
movapd 0x4e35(%rip), %xmm2     # 0x19d30
subpd %xmm2, %xmm1
movaps %xmm1, %xmm0
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm0, %xmm1
movq -0x30(%rbp), %xmm0
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
subpd %xmm2, %xmm0
movaps %xmm0, %xmm2
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm2, %xmm0
movsd -0x28(%rbp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x30(%rax)
movzwl 0x2(%rax), %ecx
orl $0x40, %ecx
movw %cx, 0x2(%rax)
jmp 0x14f4d
movq -0x60(%rbp), %rax
movq -0x18(%rbp), %rcx
movq %rcx, 0x30(%rax)
movq -0x58(%rbp), %rax
addq $0x70, %rsp
popq %rbp
retq
nopw (%rax,%rax)