// File: /workspace/github_c_makefile_star2_O0/Yamsman[P]scc/src/lex.c
// Function: lex_num
void lex_num(lexer *lx, token *t) {
	char cur = lex_cur(lx);
	s_pos *loc = &lx->tgt->loc;

	//Read sign
	int sign = 1;
	if (cur == '-' || cur == '+') {
		sign = (cur == '-') ? -1 : 1;
		cur = lex_advc(lx);
	}

	//Read base prefix
	int base = 10;
	if (cur == '0' && isalnum(lex_peekc(lx))) {
		base = 8;
		char nextc = tolower(lex_peekc(lx));
		switch (nextc) {
			case 'x': case 'X':
				base = 16;
				lex_advc(lx);
				break;
			case 'b': case 'B':
				base = 2;
				lex_advc(lx);
				break;
			default:
				if (!isdigit(nextc)) {
					//invalid prefix ...
				}
				break;
		}
		lex_advc(lx);
	}

	//Read number
	int dec_state = S_NONE; 
	int exp_state = S_NONE;
	unsigned long long int_val = 0;
	unsigned long long frac_val = 0;
	unsigned long long exp_val = 0;
	unsigned long long *tgt_val = &int_val;
	for (;; cur = lex_advc(lx)) {
		char digit = tolower(cur);
		int dval = digit - '0';

		//Handle floating-point characters
		if (digit == '.') {
			if (dec_state != S_NONE) {
				c_error(loc, "Multiple decimal points in constant\n");
				goto n_end;
			}
			dec_state = S_INIT;
			tgt_val = &frac_val;
			continue;
		} else if (tolower(digit) == 'e' && base != 16) {
			if (exp_state != S_NONE) {
				c_error(loc, "Multiple exponents in constant\n");
				goto n_end;
			}
			exp_state = S_INIT;
			tgt_val = &exp_val;
			continue;
		}

		//Read digits
		//Cases fall through from top to bottom to verify input
		switch (digit) {
		case 'f': case 'e': case 'd':
		case 'c': case 'b': case 'a':
			if (base == 10)
				goto n_end;
			dval = 10 + (digit - 'a');
		case '9': case '8':
			if (base == 8) {
				c_error(loc, "Invalid digit in octal constant\n");
				goto n_end;
			}
		case '7': case '6': case '5':
		case '4': case '3': case '2':
			if (base == 2) {
				c_error(loc, "Invalid digit in binary constant\n");
				goto n_end;
			}
		case '1': case '0':
			if (dec_state == S_INIT) dec_state = S_DONE;
			if (exp_state == S_INIT) exp_state = S_DONE;
			*(tgt_val) *= base;
			*(tgt_val) += dval;
			break;

		default: goto n_end;
		}
	}
n_end:  if (dec_state != S_NONE && base != 10)
		c_error(loc, "Decimal point in non-base 10 constant\n");
	if (exp_state == S_INIT)
		c_error(loc, "Missing exponent in constant\n");

	//Determine kind
	s_type *ty = type_new(TYPE_INT);
	if (dec_state != S_NONE || exp_state == S_DONE)
		ty->kind = TYPE_FLOAT;
	ty->size = SIZE_LONG;
	ty->is_signed = 1;
	t->dtype = ty;

	//Read suffix
	s_pos suffix_loc = *loc;
	int l_count = 0, u_count = 0, f_count = 0;
	while (isalpha(cur)) {
		switch (tolower(cur)) {
			case 'l': //Long flag
				l_count++; 
				break;
			case 'u': //Unsigned flag
				u_count++;
				break;
			case 'f': //Float flag
				ty->kind = TYPE_FLOAT;
				f_count++;
				break;
			default: goto s_end;
		}
		cur = lex_advc(lx);
	}

	//Suffix verification
	if (f_count > 1) goto s_err;
	if (ty->kind == TYPE_INT) {
		if (u_count > 1) goto s_err;
		if (l_count > 2) goto s_err;
		if (l_count == 2) //Promote to long long
			ty->size = SIZE_LONG_LONG;
	} else {
		if (u_count > 0) goto s_err;
		if (l_count > 1) goto s_err;
		if (l_count != 0) //Promote to double
			ty->size = SIZE_LONG_LONG;
	}

	//Set token data
s_end:	if (ty->kind == TYPE_INT) {
		if (!ty->is_signed) {
			t->dat.uval = int_val;
		} else {
			t->dat.ival = int_val * sign;
		}
	} else {
		//Calculate value from integer, fraction, and exponent parts
		double dec = frac_val/pow(10, floor(log10(frac_val)+1));
		t->dat.fval = int_val;
		if (frac_val != 0) t->dat.fval += dec;
		t->dat.fval *= pow(10, exp_val);
	}
	return;

	//Suffix error handling
s_err:	c_error(&suffix_loc, "Invalid suffix on constant\n");
	goto s_end;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
callq 0x81b0
movb %al, -0x11(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
addq $0x28, %rax
movq %rax, -0x20(%rbp)
movl $0x1, -0x24(%rbp)
movsbl -0x11(%rbp), %eax
cmpl $0x2d, %eax
je 0x83d7
movsbl -0x11(%rbp), %eax
cmpl $0x2b, %eax
jne 0x83fa
movsbl -0x11(%rbp), %edx
movl $0x1, %eax
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpl $0x2d, %edx
cmovel %ecx, %eax
movl %eax, -0x24(%rbp)
movq -0x8(%rbp), %rdi
callq 0x81f0
movb %al, -0x11(%rbp)
movl $0xa, -0x28(%rbp)
movsbl -0x11(%rbp), %eax
cmpl $0x30, %eax
jne 0x84e6
callq 0x3240
movq (%rax), %rax
movq %rax, -0xa0(%rbp)
movq -0x8(%rbp), %rdi
callq 0x8280
movb %al, %cl
movq -0xa0(%rbp), %rax
movsbl %cl, %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x84e6
movl $0x8, -0x28(%rbp)
movq -0x8(%rbp), %rdi
callq 0x8280
movsbl %al, %edi
callq 0x3180
movb %al, -0x29(%rbp)
movsbl -0x29(%rbp), %eax
movl %eax, -0xa4(%rbp)
subl $0x42, %eax
je 0x84aa
jmp 0x8471
movl -0xa4(%rbp), %eax
subl $0x58, %eax
je 0x8498
jmp 0x847e
movl -0xa4(%rbp), %eax
subl $0x62, %eax
je 0x84aa
jmp 0x848b
movl -0xa4(%rbp), %eax
subl $0x78, %eax
jne 0x84bc
jmp 0x8498
movl $0x10, -0x28(%rbp)
movq -0x8(%rbp), %rdi
callq 0x81f0
jmp 0x84dd
movl $0x2, -0x28(%rbp)
movq -0x8(%rbp), %rdi
callq 0x81f0
jmp 0x84dd
callq 0x3240
movq (%rax), %rax
movsbl -0x29(%rbp), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
jne 0x84db
jmp 0x84db
jmp 0x84dd
movq -0x8(%rbp), %rdi
callq 0x81f0
movl $0x0, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movq $0x0, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
movq $0x0, -0x50(%rbp)
leaq -0x40(%rbp), %rax
movq %rax, -0x58(%rbp)
movsbl -0x11(%rbp), %edi
callq 0x3180
movb %al, -0x59(%rbp)
movsbl -0x59(%rbp), %eax
subl $0x30, %eax
movl %eax, -0x60(%rbp)
movsbl -0x59(%rbp), %eax
cmpl $0x2e, %eax
jne 0x8564
cmpl $0x0, -0x30(%rbp)
je 0x8550
movq -0x20(%rbp), %rdi
leaq 0x99c9(%rip), %rsi      # 0x11f0d
movb $0x0, %al
callq 0x3880
jmp 0x8679
movl $0x1, -0x30(%rbp)
leaq -0x48(%rbp), %rax
movq %rax, -0x58(%rbp)
jmp 0x8668
movsbl -0x59(%rbp), %edi
callq 0x3180
cmpl $0x65, %eax
jne 0x85a9
cmpl $0x10, -0x28(%rbp)
je 0x85a9
cmpl $0x0, -0x34(%rbp)
je 0x8595
movq -0x20(%rbp), %rdi
leaq 0x99a9(%rip), %rsi      # 0x11f32
movb $0x0, %al
callq 0x3880
jmp 0x8679
movl $0x1, -0x34(%rbp)
leaq -0x50(%rbp), %rax
movq %rax, -0x58(%rbp)
jmp 0x8668
jmp 0x85ab
movsbl -0x59(%rbp), %eax
addl $-0x30, %eax
movl %eax, %ecx
movq %rcx, -0xb0(%rbp)
subl $0x36, %eax
ja 0x8664
movq -0xb0(%rbp), %rax
leaq 0x9302(%rip), %rcx      # 0x118d4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
cmpl $0xa, -0x28(%rbp)
jne 0x85e6
jmp 0x8679
movsbl -0x59(%rbp), %eax
subl $0x61, %eax
addl $0xa, %eax
movl %eax, -0x60(%rbp)
cmpl $0x8, -0x28(%rbp)
jne 0x860d
movq -0x20(%rbp), %rdi
leaq 0x994e(%rip), %rsi      # 0x11f52
movb $0x0, %al
callq 0x3880
jmp 0x8679
jmp 0x860f
cmpl $0x2, -0x28(%rbp)
jne 0x8629
movq -0x20(%rbp), %rdi
leaq 0x9953(%rip), %rsi      # 0x11f73
movb $0x0, %al
callq 0x3880
jmp 0x8679
jmp 0x862b
cmpl $0x1, -0x30(%rbp)
jne 0x8638
movl $0x2, -0x30(%rbp)
cmpl $0x1, -0x34(%rbp)
jne 0x8645
movl $0x2, -0x34(%rbp)
movslq -0x28(%rbp), %rcx
movq -0x58(%rbp), %rax
imulq (%rax), %rcx
movq %rcx, (%rax)
movslq -0x60(%rbp), %rcx
movq -0x58(%rbp), %rax
addq (%rax), %rcx
movq %rcx, (%rax)
jmp 0x8666
jmp 0x8679
jmp 0x8668
movq -0x8(%rbp), %rdi
callq 0x81f0
movb %al, -0x11(%rbp)
jmp 0x8514
cmpl $0x0, -0x30(%rbp)
je 0x8697
cmpl $0xa, -0x28(%rbp)
je 0x8697
movq -0x20(%rbp), %rdi
leaq 0x9905(%rip), %rsi      # 0x11f95
movb $0x0, %al
callq 0x3880
cmpl $0x1, -0x34(%rbp)
jne 0x86af
movq -0x20(%rbp), %rdi
leaq 0x9914(%rip), %rsi      # 0x11fbc
movb $0x0, %al
callq 0x3880
movl $0x6, %edi
callq 0xf720
movq %rax, -0x68(%rbp)
cmpl $0x0, -0x30(%rbp)
jne 0x86c9
cmpl $0x2, -0x34(%rbp)
jne 0x86d3
movq -0x68(%rbp), %rax
movl $0x7, (%rax)
movq -0x68(%rbp), %rax
movl $0x4, 0x4(%rax)
movq -0x68(%rbp), %rax
movl $0x1, 0xc(%rax)
movq -0x68(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x20(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x80(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x78(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x70(%rbp)
movl $0x0, -0x84(%rbp)
movl $0x0, -0x88(%rbp)
movl $0x0, -0x8c(%rbp)
callq 0x3240
movq (%rax), %rax
movsbl -0x11(%rbp), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x400, %eax            # imm = 0x400
cmpl $0x0, %eax
je 0x87d4
movsbl -0x11(%rbp), %edi
callq 0x3180
movl %eax, %ecx
movl %ecx, -0xb4(%rbp)
subl $0x66, %eax
je 0x87a3
jmp 0x8767
movl -0xb4(%rbp), %eax
subl $0x6c, %eax
je 0x8781
jmp 0x8774
movl -0xb4(%rbp), %eax
subl $0x75, %eax
je 0x8792
jmp 0x87be
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x87c3
movl -0x88(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x88(%rbp)
jmp 0x87c3
movq -0x68(%rbp), %rax
movl $0x7, (%rax)
movl -0x8c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0x87c3
jmp 0x8851
movq -0x8(%rbp), %rdi
callq 0x81f0
movb %al, -0x11(%rbp)
jmp 0x872e
cmpl $0x1, -0x8c(%rbp)
jle 0x87e2
jmp 0x899c
movq -0x68(%rbp), %rax
cmpl $0x6, (%rax)
jne 0x881d
cmpl $0x1, -0x88(%rbp)
jle 0x87f9
jmp 0x899c
cmpl $0x2, -0x84(%rbp)
jle 0x8807
jmp 0x899c
cmpl $0x2, -0x84(%rbp)
jne 0x881b
movq -0x68(%rbp), %rax
movl $0x8, 0x4(%rax)
jmp 0x884f
cmpl $0x0, -0x88(%rbp)
jle 0x882b
jmp 0x899c
cmpl $0x1, -0x84(%rbp)
jle 0x8839
jmp 0x899c
cmpl $0x0, -0x84(%rbp)
je 0x884d
movq -0x68(%rbp), %rax
movl $0x8, 0x4(%rax)
jmp 0x884f
jmp 0x8851
movq -0x68(%rbp), %rax
cmpl $0x6, (%rax)
jne 0x888b
movq -0x68(%rbp), %rax
cmpl $0x0, 0xc(%rax)
jne 0x8872
movq -0x40(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
jmp 0x8886
movq -0x40(%rbp), %rcx
movslq -0x24(%rbp), %rax
imulq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
jmp 0x8993
movq -0x48(%rbp), %xmm0
movaps 0x9519(%rip), %xmm1     # 0x11db0
movaps %xmm1, -0xe0(%rbp)
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0x9516(%rip), %xmm1     # 0x11dc0
movaps %xmm1, -0xd0(%rbp)
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movsd %xmm0, -0xc0(%rbp)
callq 0x3130
movsd 0x94fb(%rip), %xmm1     # 0x11dd0
addsd %xmm1, %xmm0
callq 0x3220
movaps %xmm0, %xmm1
movsd 0x94ef(%rip), %xmm0     # 0x11dd8
callq 0x3090
movaps -0xe0(%rbp), %xmm2
movaps -0xd0(%rbp), %xmm1
movaps %xmm0, %xmm3
movsd -0xc0(%rbp), %xmm0
divsd %xmm3, %xmm0
movsd %xmm0, -0x98(%rbp)
movq -0x40(%rbp), %xmm0
punpckldq %xmm2, %xmm0    # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movq -0x10(%rbp), %rax
movsd %xmm0, 0x20(%rax)
cmpq $0x0, -0x48(%rbp)
je 0x8951
movsd -0x98(%rbp), %xmm0
movq -0x10(%rbp), %rax
addsd 0x20(%rax), %xmm0
movsd %xmm0, 0x20(%rax)
movaps 0x9458(%rip), %xmm0     # 0x11db0
movq -0x50(%rbp), %xmm1
punpckldq %xmm0, %xmm1    # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
movapd 0x9457(%rip), %xmm0     # 0x11dc0
subpd %xmm0, %xmm1
movaps %xmm1, %xmm0
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm0, %xmm1
movsd 0x9458(%rip), %xmm0     # 0x11dd8
callq 0x3090
movq -0x10(%rbp), %rax
mulsd 0x20(%rax), %xmm0
movsd %xmm0, 0x20(%rax)
addq $0xe0, %rsp
popq %rbp
retq
leaq -0x80(%rbp), %rdi
leaq 0x9633(%rip), %rsi      # 0x11fda
movb $0x0, %al
callq 0x3880
jmp 0x8851
nopw %cs:(%rax,%rax)