// File: /workspace/github_c_makefile_star2_O0/chgzm[P]minic/tokenizer.c
// Function: read_identifier
static Token* read_identifier(const char* p, int* pos) {
    Token* token = calloc(1, sizeof(Token));
    token->type = TK_IDENT; // Default

    int len = 0;
    while (isdigit(p[*pos + len]) || isalpha(p[*pos + len]) || p[*pos + len] == '_') {
        ++len;
    }

    //
    // Check if string equals to keywords.
    // For speed, avoid comparing with all keywords by using head character.
    //

    switch (p[*pos]) {
    case 'b': {
        if (len != 5) {
            break;
        }

        if (strncmp("break", &p[*pos], 5) == 0) {
            token->type = TK_BREAK;
        }

        break;
    }
    case 'c': {
        if (len != 4 && len != 5 && len != 8) {
            break;
        }

        if      (strncmp("char",     &p[*pos], 4) == 0) { token->type = TK_CHAR;     }
        else if (strncmp("case",     &p[*pos], 4) == 0) { token->type = TK_CASE;     }
        else if (strncmp("const",    &p[*pos], 5) == 0) { token->type = TK_CONST;    }
        else if (strncmp("continue", &p[*pos], 8) == 0) { token->type = TK_CONTINUE; }

        break;
    }
    case 'd': {
        if (len != 6 && len != 7) {
            break;
        }

        if      (strncmp("double",  &p[*pos], 6) == 0) { token->type = TK_DOUBLE;  }
        else if (strncmp("default", &p[*pos], 7) == 0) { token->type = TK_DEFAULT; }

        break;
    }
    case 'e': {
        if (len != 4) {
            break;
        }

        if      (strncmp("else",   &p[*pos], 4) == 0) { token->type = TK_ELSE; } 
        else if (strncmp("enum",   &p[*pos], 4) == 0) { token->type = TK_ENUM; }

        break;
    }
    case 'f': {
        if (len != 3) {
            break;
        }

        if (strncmp("for",&p[*pos], 3) == 0) { 
            token->type = TK_FOR;   
        }

        break;
    }
    case 'i': {
        if (len != 2 && len != 3) {
            break;
        }

        if      (strncmp("if",  &p[*pos], 2) == 0) { token->type = TK_IF;  }
        else if (strncmp("int", &p[*pos], 3) == 0) { token->type = TK_INT; }

        break;
    }
    case 'r': {
        if (len != 6) {
            break;
        }

        if (strncmp("return", &p[*pos], 6) == 0) {
            token->type = TK_RETURN;   
        }

        break;
    }
    case 's': {
        if (len != 6) {
            break;
        }

        if      (strncmp("struct", &p[*pos], 6) == 0) { token->type = TK_STRUCT; }
        else if (strncmp("switch", &p[*pos], 6) == 0) { token->type = TK_SWITCH; }
        else if (strncmp("static", &p[*pos], 6) == 0) { token->type = TK_STATIC; }
        else if (strncmp("sizeof", &p[*pos], 6) == 0) { token->type = TK_SIZEOF; }

        break;
    }
    case 't': {
        if (len != 7) {
            break;
        }

        if (strncmp("typedef", &p[*pos], 7) == 0) { 
            token->type = TK_TYPEDEF;
        }

        break;
    }
    case 'v': {
        if (len != 4) {
            break;
        }

        if (strncmp("void", &p[*pos], 4) == 0) { 
            token->type = TK_VOID;
        }

        break;
    }
    case 'w': {
        if (len != 5) {
            break;
        }

        if (strncmp("while", &p[*pos], 5) == 0) {
            token->type = TK_WHILE;
        }

        break;
    }
    default: {
        break;
    }
    }

    if (token->type == TK_IDENT) {
        token->str    = calloc(1, sizeof(char) * len + 1);
        token->strlen = len + 1;
        strncpy(token->str, &p[*pos], len);
        token->str[len] = '\0';
    }

    *(pos) += len;

    return token;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x1, %edi
movl $0x18, %esi
callq 0x10b0
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movl $0x3, (%rax)
movl $0x0, -0x1c(%rbp)
callq 0x1180
movq (%rax), %rax
movq -0x8(%rbp), %rcx
movq -0x10(%rbp), %rdx
movl (%rdx), %edx
addl -0x1c(%rbp), %edx
movslq %edx, %rdx
movsbl (%rcx,%rdx), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %ecx
andl $0x800, %ecx            # imm = 0x800
movb $0x1, %al
cmpl $0x0, %ecx
movb %al, -0x1d(%rbp)
jne 0xda47
callq 0x1180
movq (%rax), %rax
movq -0x8(%rbp), %rcx
movq -0x10(%rbp), %rdx
movl (%rdx), %edx
addl -0x1c(%rbp), %edx
movslq %edx, %rdx
movsbl (%rcx,%rdx), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %ecx
andl $0x400, %ecx            # imm = 0x400
movb $0x1, %al
cmpl $0x0, %ecx
movb %al, -0x1d(%rbp)
jne 0xda47
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movl (%rcx), %ecx
addl -0x1c(%rbp), %ecx
movslq %ecx, %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x5f, %eax
sete %al
movb %al, -0x1d(%rbp)
movb -0x1d(%rbp), %al
testb $0x1, %al
jne 0xda50
jmp 0xda5e
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0xd9c4
movq -0x8(%rbp), %rax
movq -0x10(%rbp), %rcx
movslq (%rcx), %rcx
movsbl (%rax,%rcx), %eax
addl $-0x62, %eax
movl %eax, %ecx
movq %rcx, -0x28(%rbp)
subl $0x15, %eax
ja 0xdf0e
movq -0x28(%rbp), %rax
leaq 0x313e(%rip), %rcx      # 0x10bc8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
cmpl $0x5, -0x1c(%rbp)
je 0xda9e
jmp 0xdf10
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x35a4(%rip), %rdi      # 0x11057
movl $0x5, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xdacc
movq -0x18(%rbp), %rax
movl $0x14, (%rax)
jmp 0xdf10
cmpl $0x4, -0x1c(%rbp)
je 0xdae8
cmpl $0x5, -0x1c(%rbp)
je 0xdae8
cmpl $0x8, -0x1c(%rbp)
je 0xdae8
jmp 0xdf10
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x3560(%rip), %rdi      # 0x1105d
movl $0x4, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xdb1b
movq -0x18(%rbp), %rax
movl $0x7, (%rax)
jmp 0xdbaf
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x3532(%rip), %rdi      # 0x11062
movl $0x4, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xdb4b
movq -0x18(%rbp), %rax
movl $0x12, (%rax)
jmp 0xdbad
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x3507(%rip), %rdi      # 0x11067
movl $0x5, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xdb7b
movq -0x18(%rbp), %rax
movl $0xc, (%rax)
jmp 0xdbab
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x34dd(%rip), %rdi      # 0x1106d
movl $0x8, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xdba9
movq -0x18(%rbp), %rax
movl $0x15, (%rax)
jmp 0xdbab
jmp 0xdbad
jmp 0xdbaf
jmp 0xdf10
cmpl $0x6, -0x1c(%rbp)
je 0xdbc5
cmpl $0x7, -0x1c(%rbp)
je 0xdbc5
jmp 0xdf10
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x349c(%rip), %rdi      # 0x11076
movl $0x6, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xdbf5
movq -0x18(%rbp), %rax
movl $0x9, (%rax)
jmp 0xdc25
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x3473(%rip), %rdi      # 0x1107d
movl $0x7, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xdc23
movq -0x18(%rbp), %rax
movl $0x13, (%rax)
jmp 0xdc25
jmp 0xdf10
cmpl $0x4, -0x1c(%rbp)
je 0xdc35
jmp 0xdf10
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x2c88(%rip), %rdi      # 0x108d2
movl $0x4, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xdc65
movq -0x18(%rbp), %rax
movl $0xe, (%rax)
jmp 0xdc95
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x340b(%rip), %rdi      # 0x11085
movl $0x4, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xdc93
movq -0x18(%rbp), %rax
movl $0xb, (%rax)
jmp 0xdc95
jmp 0xdf10
cmpl $0x3, -0x1c(%rbp)
je 0xdca5
jmp 0xdf10
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x33d0(%rip), %rdi      # 0x1108a
movl $0x3, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xdcd3
movq -0x18(%rbp), %rax
movl $0xf, (%rax)
jmp 0xdf10
cmpl $0x2, -0x1c(%rbp)
je 0xdce9
cmpl $0x3, -0x1c(%rbp)
je 0xdce9
jmp 0xdf10
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x2bdc(%rip), %rdi      # 0x108da
movl $0x2, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xdd19
movq -0x18(%rbp), %rax
movl $0xd, (%rax)
jmp 0xdd49
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x3360(%rip), %rdi      # 0x1108e
movl $0x3, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xdd47
movq -0x18(%rbp), %rax
movl $0x8, (%rax)
jmp 0xdd49
jmp 0xdf10
cmpl $0x6, -0x1c(%rbp)
je 0xdd59
jmp 0xdf10
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x3324(%rip), %rdi      # 0x11092
movl $0x6, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xdd87
movq -0x18(%rbp), %rax
movl $0x16, (%rax)
jmp 0xdf10
cmpl $0x6, -0x1c(%rbp)
je 0xdd97
jmp 0xdf10
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x32ed(%rip), %rdi      # 0x11099
movl $0x6, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xddca
movq -0x18(%rbp), %rax
movl $0xa, (%rax)
jmp 0xde5e
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x32c1(%rip), %rdi      # 0x110a0
movl $0x6, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xddfa
movq -0x18(%rbp), %rax
movl $0x11, (%rax)
jmp 0xde5c
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x3298(%rip), %rdi      # 0x110a7
movl $0x6, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xde2a
movq -0x18(%rbp), %rax
movl $0x4, (%rax)
jmp 0xde5a
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x326f(%rip), %rdi      # 0x110ae
movl $0x6, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xde58
movq -0x18(%rbp), %rax
movl $0x17, (%rax)
jmp 0xde5a
jmp 0xde5c
jmp 0xde5e
jmp 0xdf10
cmpl $0x7, -0x1c(%rbp)
je 0xde6e
jmp 0xdf10
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x3232(%rip), %rdi      # 0x110b5
movl $0x7, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xde9c
movq -0x18(%rbp), %rax
movl $0x5, (%rax)
jmp 0xdf10
cmpl $0x4, -0x1c(%rbp)
je 0xdea6
jmp 0xdf10
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x3202(%rip), %rdi      # 0x110bd
movl $0x4, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xded4
movq -0x18(%rbp), %rax
movl $0x6, (%rax)
jmp 0xdf10
cmpl $0x5, -0x1c(%rbp)
je 0xdede
jmp 0xdf10
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
leaq 0x31cf(%rip), %rdi      # 0x110c2
movl $0x5, %edx
callq 0x1060
cmpl $0x0, %eax
jne 0xdf0c
movq -0x18(%rbp), %rax
movl $0x10, (%rax)
jmp 0xdf10
jmp 0xdf10
movq -0x18(%rbp), %rax
cmpl $0x3, (%rax)
jne 0xdf76
movslq -0x1c(%rbp), %rsi
shlq $0x0, %rsi
addq $0x1, %rsi
movl $0x1, %edi
callq 0x10b0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movl -0x1c(%rbp), %ecx
addl $0x1, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rsi
movslq -0x1c(%rbp), %rdx
callq 0x1050
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x1c(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movl -0x1c(%rbp), %ecx
movq -0x10(%rbp), %rax
addl (%rax), %ecx
movl %ecx, (%rax)
movq -0x18(%rbp), %rax
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax,%rax)