// File: /workspace/github_c_makefile_star2_O3/sebbekarlsson[P]cola/src/lex.c
// Function: lex_get_next_token
token* lex_get_next_token(lex_state* state) {
    while (state->current_char != '\0') {
        char* str = char_to_string(state->current_char); 

        if (state->current_char == ' ' || (int)state->current_char == 10 || state->current_char == '\0') {
            lex_skip_whitespace(state);
            free(str);
            continue;
        }

        else if (state->current_char == '+') {
            lex_advance(state);
            return init_token(_OP_PLUS, str);
        }

        else if (state->current_char == '-') {
            lex_advance(state);
            return init_token(_OP_SUBTRACT, str);
        }

        else if (state->current_char == '/') {
            lex_advance(state);
            return init_token(_OP_DIVIDE, str);
        }

        else if (state->current_char == '*') {
            lex_advance(state);
            return init_token(_OP_MULTIPLY, str);
        }

        else if (state->current_char == '(') {
            lex_advance(state);
            return init_token(_LPAREN, str);
        }

        else if (state->current_char == ')') {
            lex_advance(state);
            return init_token(_RPAREN, str);
        }

        else if (state->current_char == '{') {
            lex_advance(state);
            return init_token(_LBRACE, str);
        }

        else if (state->current_char == '}') {
            lex_advance(state);
            return init_token(_RBRACE, str);
        }

        else if (state->current_char == ';') {
            lex_advance(state);
            return init_token(_SEMI, str);
        }

        else if (state->current_char == '.') {
            lex_advance(state);
            return init_token(_DOT, str);
        }

        else if (state->current_char == ',') {
            lex_advance(state);
            return init_token(_COMMA, str);
        }

        else if (state->current_char == '<') {
            lex_advance(state);
            return init_token(_LESS_THAN, str);
        }
        
        else if (state->current_char == '>') {
            lex_advance(state);
            return init_token(_LARGER_THAN, str);
        }

        else if (state->current_char == '=') {
            lex_advance(state);
            if (state->current_char == '=') {
                lex_advance(state);
                return init_token(_EQUALS_EQUALS, str);
            } else {
                lex_advance(state);
                return init_token(_EQUALS, str);
            }
        }

        else if (state->current_char == '[') {
            lex_advance(state);
            return init_token(_LBRACKET, str);
        }

        else if (state->current_char == ']') {
            lex_advance(state);
            return init_token(_RBRACKET, str);
        }

        else if (state->current_char == '"') {
            free(str);
            return init_token(_STRING, lex_parse_string(state));
        }

        else if (state->current_char == '#') {
            free(str);
            lex_advance(state);
            if (state->current_char != '!') {
                return init_token(_INTERPRETER_INSTR, lex_parse_id(state));
            }
        }

        else if (state->current_char == '\'') {
            free(str);
            return init_token(_CHAR, lex_parse_char(state));
        }

        else if (isdigit(state->current_char)) {
            free(str);
            return lex_parse_number(state);
        }

        else if (isalnum(state->current_char)) {
            free(str);
            return parse_id(state, init_token(_ID, lex_parse_id(state)));
        } else {
            printf("Unexpected token: `%s` (%d) \n", str, (int) state->current_char);
            break;
        }

        free(str);
        lex_advance(state);
    }

    return init_token(_EOF, "");
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movb 0x8(%rdi), %al
testb %al, %al
je 0x2e95
movq %rdi, %rbx
leaq 0x2567(%rip), %r15      # 0x527c
movsbl %al, %edi
callq 0x4850
movq %rax, %r14
movzbl 0x8(%rbx), %eax
cmpl $0x5a, %eax
jg 0x2dbc
leal -0x20(%rax), %ecx
cmpl $0x1e, %ecx
ja 0x2d63
movslq (%r15,%rcx,4), %rcx
addq %r15, %rcx
jmpq *%rcx
movq %r14, %rdi
callq 0x1030
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x2d8c
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
jmp 0x2d8f
testl %eax, %eax
je 0x2d70
cmpl $0xa, %eax
jne 0x2e64
movq %rbx, %rdi
callq 0x3133
movq %r14, %rdi
callq 0x1030
movb 0x8(%rbx), %al
testb %al, %al
jne 0x2d15
jmp 0x2e95
movb 0x8(%rbx), %al
cmpb $0x21, %al
jne 0x3103
movq %r14, %rdi
callq 0x1030
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x2d80
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
jmp 0x2d83
cmpl $0x7a, %eax
jg 0x2df1
cmpl $0x5b, %eax
je 0x2e1d
cmpl $0x5d, %eax
jne 0x2e64
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x2dea
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0x23, %edi
jmp 0x2e5f
cmpl $0x7b, %eax
je 0x2e3f
cmpl $0x7d, %eax
jne 0x2e64
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x2e16
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0xf, %edi
jmp 0x2e5f
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x2e38
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0x22, %edi
jmp 0x2e5f
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x2e5a
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0xe, %edi
movq %r14, %rsi
jmp 0x2e9e
movsbl %al, %r15d
callq 0x1170
movq (%rax), %rax
movslq %r15d, %rcx
movzwl (%rax,%rcx,2), %eax
btl $0xb, %eax
jb 0x2ead
testb $0x8, %al
jne 0x2ec7
leaq 0x2470(%rip), %rdi      # 0x52f8
movq %r14, %rsi
movl %r15d, %edx
xorl %eax, %eax
callq 0x10a0
leaq 0x2479(%rip), %rsi      # 0x5315
xorl %edi, %edi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x48cc
movq %r14, %rdi
callq 0x1030
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x3455
movq %r14, %rdi
callq 0x1030
movq %rbx, %rdi
callq 0x3257
movl $0x1, %edi
movq %rax, %rsi
callq 0x48cc
movq %rbx, %rdi
movq %rax, %rsi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x43b8
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x2f14
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0x17, %edi
jmp 0x2e5f
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x2f39
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0x14, %edi
jmp 0x2e5f
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x2f5e
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0x16, %edi
jmp 0x2e5f
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x2f83
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0x5, %edi
jmp 0x2e5f
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x2fa8
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0x6, %edi
jmp 0x2e5f
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x2fcd
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0x7, %edi
jmp 0x2e5f
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x3012
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movzbl 0x1(%rax,%rcx), %edx
movb %dl, 0x8(%rbx)
testl %edx, %edx
je 0x3129
cmpl $0x3d, %edx
jne 0x3118
leaq 0x2(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x2(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0x24, %edi
jmp 0x2e5f
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x3037
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0xd, %edi
jmp 0x2e5f
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x305c
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0x10, %edi
jmp 0x2e5f
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x3081
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0x15, %edi
jmp 0x2e5f
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x30a6
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0x8, %edi
jmp 0x2e5f
movq %r14, %rdi
callq 0x1030
movq %rbx, %rdi
callq 0x3180
movl $0x3, %edi
jmp 0x3110
movq %r14, %rdi
callq 0x1030
movq %rbx, %rdi
callq 0x3329
movl $0x26, %edi
jmp 0x3110
movq (%rbx), %rax
movslq 0xc(%rbx), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x30f9
leaq 0x1(%rcx), %rdx
movl %edx, 0xc(%rbx)
movb 0x1(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0xc, %edi
jmp 0x2e5f
movq %rbx, %rdi
callq 0x3257
movl $0x20, %edi
movq %rax, %rsi
jmp 0x2e9e
movq %rcx, %rdx
addq $0x2, %rdx
movl %edx, 0xc(%rbx)
movb 0x2(%rax,%rcx), %al
movb %al, 0x8(%rbx)
movl $0x1b, %edi
jmp 0x2e5f