// File: /workspace/github_cpp_makefile_star2_O2/pixlark[P]Badge/src/lexer.cc
// Function: Lexer::next_token()
Token Lexer::next_token()
{
 reset:
	if (peek() == '\0') {
		Token token = create_token(TOKEN_EOF, 1);
		return token;
	}
	
	if (isspace(peek())) {
		advance();
		goto reset;
	}

	if (peek() == '%') {
		while (peek() != '\0' && peek() != '\n') {
			advance();
		}
		goto reset;
	}
	
	if (peek() == '"') {
		size_t start = cursor;
		advance();
		
		String_Builder builder;
		while (peek() != '"') {
			builder.add(next());
		}
		advance();
		char * s = builder.final_string();
		defer { free(s); };
		
		Token token = create_token(TOKEN_STRING_LITERAL, cursor - start);
		token.values.string = Intern::intern(s); // string literals are technically symbols
		return token;
	}
	
	if (isalpha(peek()) || peek() == '_') {
		String_Builder builder;
		while (isalnum(peek()) || peek() == '_') {
			builder.add(next());
		}
		char * s = builder.final_string();
		defer { free(s); };
		
		for (int i = 0; i < RESERVED_WORDS_COUNT; i++) {
			if (strcmp(s, reserved_words[i]) == 0) {
				return create_token((Token_Kind) (RESERVED_WORDS_BEGIN + i), builder.size());
			}
		}
		
		Token token = create_token(TOKEN_SYMBOL, builder.size());
		token.values.symbol = Intern::intern(s);
		return token;
	}

	if (isdigit(peek())) {
		String_Builder builder;
		while (isdigit(peek())) {
			builder.add(next());
		}
		char * s = builder.final_string();
		defer { free(s); };
		Token token = create_token(TOKEN_INTEGER_LITERAL, builder.size());
		token.values.integer = strtol(s, NULL, 10);
		return token;
	}
	
	switch (peek()) {
	case '+':
	case '-':
	case '*':
	case '/':
	case '.':
	case ',':
	case '(':
	case ')':
	case '{':
	case '}':
	case '@':
	case '$':
	case ':':
	case '\'':
		return create_token((Token_Kind) next(), 1);
		//return Token::with_kind((Token_Kind) next());
	case '=':
		return create_token(read_double_token('=', '=', TOKEN_EQUAL), 1);
	case '!':
		return create_token(read_double_token('!', '=', TOKEN_NOT_EQUAL), 1);
	case '>':
		return create_token(read_double_token('>', '=', TOKEN_GTE), 1);
	case '<':
		return create_token(read_double_token('<', '=', TOKEN_LTE), 1);
	case ']':
		return create_token((Token_Kind) next(), 1);
	case '[':
		advance();
		if (peek() == '-') {
			// Multi-line comment
			while (true) {
				advance();
				if (peek() == '\0') {
					fatal("Unterminated multi-line comment");
				}
				if (peek() == '-') {
					advance();
					if (peek() == ']') {
						advance();
						break;
					}
				}
			}
			goto reset;
		} else {
			return create_token((Token_Kind) '[', 1);
			//return Token::with_kind((Token_Kind) '[');
		}
	default:
		fatal_assoc(Assoc_Allocator::make(source, source_length, cursor, 1, line),
					"Line %d\nMisplaced character %c (%d)", line, peek(), peek());
		/*
	case ';':
		return Token::with_kind(read_double_token(';', ';', TOKEN_DOUBLE_SEMICOLON));*/
	}
	return (Token) {}; // @linter
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdi, %rbx
movq 0x8(%rbx), %r15
movq 0x10(%rbx), %r14
cmpq %r15, %r14
jae 0x22f3
movq (%rbx), %r12
movsbl (%r12,%r14), %r13d
testl %r13d, %r13d
je 0x22f3
movl %r13d, %edi
callq 0x1040
testl %eax, %eax
je 0x21dc
movq %rbx, %rdi
callq 0x216c
jmp 0x21a4
movzbl %r13b, %eax
cmpl $0x25, %eax
je 0x22a1
cmpl $0x22, %eax
je 0x2374
movl %r13d, %edi
callq 0x11b0
testl %eax, %eax
jne 0x2423
cmpb $0x5f, %r13b
je 0x2423
leal -0x30(%r13), %eax
cmpl $0x9, %eax
jbe 0x24ea
cmpb $0x5b, %r13b
jne 0x22c4
movq %rbx, %rdi
callq 0x216c
movq 0x10(%rbx), %rax
cmpq 0x8(%rbx), %rax
jae 0x236c
movq (%rbx), %rcx
cmpb $0x2d, (%rcx,%rax)
jne 0x236c
movq %rbx, %rdi
callq 0x216c
movq 0x10(%rbx), %rax
cmpq 0x8(%rbx), %rax
jae 0x2643
movq (%rbx), %rcx
movzbl (%rcx,%rax), %eax
cmpl $0x2d, %eax
je 0x2271
testl %eax, %eax
jne 0x2246
jmp 0x2643
movq %rbx, %rdi
callq 0x216c
movq 0x10(%rbx), %rax
cmpq 0x8(%rbx), %rax
jae 0x2246
movq (%rbx), %rcx
cmpb $0x5d, (%rcx,%rax)
jne 0x2246
jmp 0x21d2
movq %rbx, %rdi
callq 0x216c
movq 0x8(%rbx), %r15
movq 0x10(%rbx), %r14
cmpq %r15, %r14
jae 0x21a4
movq (%rbx), %rax
movzbl (%rax,%r14), %eax
testl %eax, %eax
je 0x21a4
cmpl $0xa, %eax
jne 0x2291
jmp 0x21a4
movzbl %r13b, %eax
leal -0x21(%rax), %ecx
cmpl $0x1f, %ecx
ja 0x231e
leaq 0x6d2d(%rip), %rax      # 0x9004
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq %rbx, %rdi
callq 0x212a
movsbl %al, %esi
pushq $0x1
popq %rdx
movq %rbx, %rdi
jmp 0x22fe
pushq $0x1
popq %rdx
movq %rbx, %rdi
movl $0x100, %esi            # imm = 0x100
callq 0x20ca
movq %rax, %rbx
movq %rdx, %r14
movq %rbx, %rax
movq %r14, %rdx
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x5d, %eax
je 0x22e0
cmpl $0x7d, %eax
je 0x22e0
cmpl $0x7b, %eax
je 0x22e0
movq 0x18(%rbx), %r8
pushq $0x1
popq %rcx
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x17ae
movq 0x10(%rbx), %rsi
movq 0x18(%rbx), %rdx
xorl %ecx, %ecx
cmpq 0x8(%rbx), %rsi
jae 0x2359
movq (%rbx), %rcx
movsbl (%rcx,%rsi), %ecx
leaq 0x7071(%rip), %rsi      # 0x93d1
movl %eax, %edi
movl %ecx, %r8d
xorl %eax, %eax
callq 0x1b51
pushq $0x5b
popq %rsi
jmp 0x22eb
movq %rbx, %rdi
callq 0x216c
leaq -0x60(%rbp), %r15
andq $0x0, 0x8(%r15)
movq $0x4, 0x10(%r15)
movq 0xcc3c(%rip), %rax      # 0xefd0
movq %rax, 0x18(%r15)
movq 0xcc29(%rip), %rax      # 0xefc8
movq %rax, 0x20(%r15)
pushq $0x4
popq %rdi
callq 0x1200
movq %rax, (%r15)
movq 0x10(%rbx), %rax
cmpq 0x8(%rbx), %rax
jae 0x23c1
movq (%rbx), %rcx
cmpb $0x22, (%rcx,%rax)
je 0x23d6
movq %rbx, %rdi
callq 0x212a
movsbl %al, %esi
movq %r15, %rdi
callq 0x47da
jmp 0x23ae
movq %rbx, %rdi
callq 0x216c
leaq -0x60(%rbp), %rdi
callq 0x14aa
leaq -0x38(%rbp), %rcx
movq %rax, (%rcx)
movq %rcx, -0x30(%rbp)
movq 0x10(%rbx), %rdx
subq %r14, %rdx
movq %rbx, %rdi
movl $0x118, %esi            # imm = 0x118
callq 0x20ca
movq %rax, %rbx
movq -0x38(%rbp), %rdi
callq 0x15b3
movq %rax, %r14
leaq -0x30(%rbp), %rdi
callq 0x2696
jmp 0x2635
leaq -0x60(%rbp), %r14
andq $0x0, 0x8(%r14)
movq $0x4, 0x10(%r14)
movq 0xcb95(%rip), %rax      # 0xefd0
movq %rax, 0x18(%r14)
movq 0xcb82(%rip), %rax      # 0xefc8
movq %rax, 0x20(%r14)
pushq $0x4
popq %rdi
callq 0x1200
movq %rax, (%r14)
movq 0x8(%rbx), %r12
movq 0x10(%rbx), %r15
xorl %edi, %edi
cmpq %r12, %r15
jae 0x246c
movq (%rbx), %rax
movsbl (%rax,%r15), %edi
callq 0x1100
testl %eax, %eax
jne 0x2484
cmpq %r12, %r15
jae 0x2499
movq (%rbx), %rax
cmpb $0x5f, (%rax,%r15)
jne 0x2499
movq %rbx, %rdi
callq 0x212a
movsbl %al, %esi
movq %r14, %rdi
callq 0x47da
jmp 0x2455
leaq -0x60(%rbp), %rdi
callq 0x14aa
movq %rax, %r15
leaq -0x38(%rbp), %rax
movq %r15, (%rax)
movq %rax, -0x30(%rbp)
movl $0x105, %r14d           # imm = 0x105
xorl %r12d, %r12d
leaq 0xc860(%rip), %r13      # 0xed20
cmpq $0x88, %r12
je 0x25f5
movq (%r12,%r13), %rsi
movq %r15, %rdi
callq 0x1160
testl %eax, %eax
je 0x2617
incl %r14d
addq $0x8, %r12
jmp 0x24c0
leaq -0x60(%rbp), %r14
andq $0x0, 0x8(%r14)
movq $0x4, 0x10(%r14)
movq 0xcace(%rip), %rax      # 0xefd0
movq %rax, 0x18(%r14)
movq 0xcabb(%rip), %rax      # 0xefc8
movq %rax, 0x20(%r14)
pushq $0x4
popq %rdi
callq 0x1200
movq %rax, (%r14)
movq 0x10(%rbx), %rax
cmpq 0x8(%rbx), %rax
jae 0x254a
movq (%rbx), %rcx
movsbl (%rcx,%rax), %eax
addl $-0x30, %eax
cmpl $0x9, %eax
ja 0x254a
movq %rbx, %rdi
callq 0x212a
movsbl %al, %esi
movq %r14, %rdi
callq 0x47da
jmp 0x251c
leaq -0x60(%rbp), %r14
movq %r14, %rdi
callq 0x14aa
leaq -0x38(%rbp), %rcx
movq %rax, (%rcx)
movq %rcx, -0x30(%rbp)
movq 0x8(%r14), %rdx
movq %rbx, %rdi
movl $0x117, %esi            # imm = 0x117
callq 0x20ca
movq %rax, %rbx
movq %rdx, %r14
movq -0x38(%rbp), %rdi
pushq $0xa
popq %rdx
xorl %esi, %esi
callq 0x1170
movl %eax, %eax
movabsq $-0x100000000, %rcx     # imm = 0xFFFFFFFF00000000
andq %rcx, %r14
orq %rax, %r14
leaq -0x30(%rbp), %rdi
callq 0x26b6
jmp 0x2635
pushq $0x3c
popq %rsi
pushq $0x3d
popq %rdx
movq %rbx, %rdi
movl $0x104, %ecx            # imm = 0x104
jmp 0x25e3
pushq $0x3e
popq %rsi
pushq $0x3d
popq %rdx
movq %rbx, %rdi
movl $0x103, %ecx            # imm = 0x103
jmp 0x25e3
pushq $0x3d
popq %rdx
movq %rbx, %rdi
movl %edx, %esi
movl $0x101, %ecx            # imm = 0x101
jmp 0x25e3
pushq $0x21
popq %rsi
pushq $0x3d
popq %rdx
movq %rbx, %rdi
movl $0x102, %ecx            # imm = 0x102
callq 0x26c6
pushq $0x1
popq %rdx
movq %rbx, %rdi
movl %eax, %esi
jmp 0x22fe
movq -0x58(%rbp), %rdx
movq %rbx, %rdi
movl $0x116, %esi            # imm = 0x116
callq 0x20ca
movq %rax, %rbx
movq -0x38(%rbp), %rdi
callq 0x15b3
movq %rax, %r14
jmp 0x262c
movq -0x58(%rbp), %rdx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x20ca
movq %rax, %rbx
movq %rdx, %r14
leaq -0x30(%rbp), %rdi
callq 0x26a6
leaq -0x60(%rbp), %rdi
callq 0x1404
jmp 0x2309
leaq 0x6d67(%rip), %rdi      # 0x93b1
xorl %eax, %eax
callq 0x1928
jmp 0x2661
movq %rax, %rbx
leaq -0x30(%rbp), %rdi
callq 0x26b6
jmp 0x2684
movq %rax, %rbx
leaq -0x30(%rbp), %rdi
callq 0x26a6
jmp 0x2684
movq %rax, %rbx
leaq -0x30(%rbp), %rdi
callq 0x2696
jmp 0x2684
jmp 0x2681
jmp 0x2681
movq %rax, %rbx
leaq -0x60(%rbp), %rdi
callq 0x1404
movq %rbx, %rdi
callq 0x11c0
nop