// File: /workspace/github_c_makefile_star2_O0/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
subq $0x20, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x0, %eax
je 0x3f44
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %edi
callq 0x6130
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x20, %eax
je 0x3a85
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0xa, %eax
je 0x3a85
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x0, %eax
jne 0x3a99
movq -0x10(%rbp), %rdi
callq 0x3f60
movq -0x18(%rbp), %rdi
callq 0x1030
jmp 0x3a3c
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x2b, %eax
jne 0x3ac6
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0x5, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x2d, %eax
jne 0x3af3
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0x6, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x2f, %eax
jne 0x3b20
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0x8, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x2a, %eax
jne 0x3b4d
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0x7, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x28, %eax
jne 0x3b7a
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0xc, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x29, %eax
jne 0x3ba7
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0xd, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x7b, %eax
jne 0x3bd4
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0xe, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x7d, %eax
jne 0x3c01
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0xf, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x3b, %eax
jne 0x3c2e
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0x14, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x2e, %eax
jne 0x3c5b
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0x15, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x2c, %eax
jne 0x3c88
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0x10, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x3c, %eax
jne 0x3cb5
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0x16, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x3e, %eax
jne 0x3ce2
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0x17, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x3d, %eax
jne 0x3d45
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x3d, %eax
jne 0x3d25
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0x24, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0x1b, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x5b, %eax
jne 0x3d72
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0x22, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x5d, %eax
jne 0x3d9f
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x18(%rbp), %rsi
movl $0x23, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x22, %eax
jne 0x3dd4
movq -0x18(%rbp), %rdi
callq 0x1030
movq -0x10(%rbp), %rdi
callq 0x3fc0
movq %rax, %rsi
movl $0x3, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x23, %eax
jne 0x3e24
movq -0x18(%rbp), %rdi
callq 0x1030
movq -0x10(%rbp), %rdi
callq 0x39e0
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x21, %eax
je 0x3e1f
movq -0x10(%rbp), %rdi
callq 0x40a0
movq %rax, %rsi
movl $0x20, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
jmp 0x3f09
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x27, %eax
jne 0x3e59
movq -0x18(%rbp), %rdi
callq 0x1030
movq -0x10(%rbp), %rdi
callq 0x4180
movq %rax, %rsi
movl $0x26, %edi
callq 0x61f0
movq %rax, -0x8(%rbp)
jmp 0x3f56
callq 0x1150
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movsbl 0x8(%rcx), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
je 0x3e95
movq -0x18(%rbp), %rdi
callq 0x1030
movq -0x10(%rbp), %rdi
callq 0x4290
movq %rax, -0x8(%rbp)
jmp 0x3f56
callq 0x1150
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movsbl 0x8(%rcx), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x3eed
movq -0x18(%rbp), %rdi
callq 0x1030
movq -0x10(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
callq 0x40a0
movq %rax, %rsi
movl $0x1, %edi
callq 0x61f0
movq -0x20(%rbp), %rdi
movq %rax, %rsi
callq 0x5a20
movq %rax, -0x8(%rbp)
jmp 0x3f56
movq -0x18(%rbp), %rsi
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %edx
leaq 0x3304(%rip), %rdi      # 0x7204
movb $0x0, %al
callq 0x1080
jmp 0x3f44
jmp 0x3f0b
jmp 0x3f0d
jmp 0x3f0f
jmp 0x3f11
jmp 0x3f13
jmp 0x3f15
jmp 0x3f17
jmp 0x3f19
jmp 0x3f1b
jmp 0x3f1d
jmp 0x3f1f
jmp 0x3f21
jmp 0x3f23
jmp 0x3f25
jmp 0x3f27
jmp 0x3f29
jmp 0x3f2b
jmp 0x3f2d
movq -0x18(%rbp), %rdi
callq 0x1030
movq -0x10(%rbp), %rdi
callq 0x39e0
jmp 0x3a3c
xorl %edi, %edi
leaq 0x32d4(%rip), %rsi      # 0x7221
callq 0x61f0
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x20, %rsp
popq %rbp
retq