// File: /workspace/github_c_makefile_star2_O2/hikalium[P]compilium/tokenizer.c
// Function: CreateNextToken
static struct Node *CreateNextToken(const char *p, const char *src, int *line) {
  assert(line);
  if (!*p) return NULL;
  if (*p == ' ') {
    return AllocToken(src, *line, p, 1, kTokenDelimiter);
  }
  if (*p == '\n') {
    (*line)++;
    return AllocToken(src, *line, p, 1, kTokenDelimiter);
  }
  if (p[0] == '\\' && p[1] == '\n') {
    (*line)++;
    return AllocToken(src, *line, p, 2, kTokenZeroWidthNoBreakSpace);
  }
  if ('1' <= *p && *p <= '9') {
    int length = 0;
    while ('0' <= p[length] && p[length] <= '9') {
      length++;
    }
    return AllocToken(src, *line, p, length, kTokenIntegerConstant);
  } else if ('0' == *p) {
    int length = 0;
    if (p[1] == 'x') {
      // Hexadecimal
      length += 2;
      while (('0' <= p[length] && p[length] <= '9') ||
             ('A' <= p[length] && p[length] <= 'F') ||
             ('a' <= p[length] && p[length] <= 'f')) {
        length++;
      }
    } else {
      // Octal
      while ('0' <= p[length] && p[length] <= '7') {
        length++;
      }
    }
    return AllocToken(src, *line, p, length, kTokenIntegerConstant);
  } else if (('A' <= *p && *p <= 'Z') || ('a' <= *p && *p <= 'z') ||
             *p == '_') {
    int length = 0;
    while (('A' <= p[length] && p[length] <= 'Z') ||
           ('a' <= p[length] && p[length] <= 'z') || p[length] == '_' ||
           ('0' <= p[length] && p[length] <= '9')) {
      length++;
    }
    struct Node *t = AllocToken(src, *line, p, length, kTokenIdent);
    if (IsEqualTokenWithCStr(t, "break")) t->token_type = kTokenKwBreak;
    if (IsEqualTokenWithCStr(t, "char")) t->token_type = kTokenKwChar;
    if (IsEqualTokenWithCStr(t, "const")) t->token_type = kTokenKwConst;
    if (IsEqualTokenWithCStr(t, "continue")) t->token_type = kTokenKwContinue;
    if (IsEqualTokenWithCStr(t, "else")) t->token_type = kTokenKwElse;
    if (IsEqualTokenWithCStr(t, "extern")) t->token_type = kTokenKwExtern;
    if (IsEqualTokenWithCStr(t, "for")) t->token_type = kTokenKwFor;
    if (IsEqualTokenWithCStr(t, "if")) t->token_type = kTokenKwIf;
    if (IsEqualTokenWithCStr(t, "int")) t->token_type = kTokenKwInt;
    if (IsEqualTokenWithCStr(t, "long")) t->token_type = kTokenKwLong;
    if (IsEqualTokenWithCStr(t, "return")) t->token_type = kTokenKwReturn;
    if (IsEqualTokenWithCStr(t, "sizeof")) t->token_type = kTokenKwSizeof;
    if (IsEqualTokenWithCStr(t, "static")) t->token_type = kTokenKwStatic;
    if (IsEqualTokenWithCStr(t, "struct")) t->token_type = kTokenKwStruct;
    if (IsEqualTokenWithCStr(t, "typedef")) t->token_type = kTokenKwTypedef;
    if (IsEqualTokenWithCStr(t, "unsigned")) t->token_type = kTokenKwUnsigned;
    if (IsEqualTokenWithCStr(t, "void")) t->token_type = kTokenKwVoid;
    if (IsEqualTokenWithCStr(t, "while")) t->token_type = kTokenKwWhile;
    return t;
  } else if ('\'' == *p) {
    int length = 1;
    while (p[length] && p[length] != '\'') {
      if (p[length] == '\\' && p[length + 1]) {
        length++;
      }
      length++;
    }
    if (p[length] != '\'') {
      Error("Expected end of char literal (')");
    }
    length++;
    return AllocToken(src, *line, p, length, kTokenCharLiteral);
  } else if ('"' == *p) {
    int length = 1;
    while (p[length] && p[length] != '"') {
      if (p[length] == '\\' && p[length + 1]) {
        length++;
      }
      length++;
    }
    if (p[length] != '"') {
      Error("Expected end of string literal (\")");
    }
    length++;
    return AllocToken(src, *line, p, length, kTokenStringLiteral);
  } else if ('#' == *p) {
    if (p[1] == '#') {
      return AllocToken(src, *line, p, 2, kTokenPunctuator);
    }
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('&' == *p) {
    if (p[1] == '&') {
      return AllocToken(src, *line, p, 2, kTokenPunctuator);
    }
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('|' == *p) {
    if (p[1] == '|') {
      return AllocToken(src, *line, p, 2, kTokenPunctuator);
    }
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('<' == *p) {
    if (p[1] == '<') {
      if (p[2] == '=') {
        return AllocToken(src, *line, p, 3, kTokenPunctuator);
      }
      return AllocToken(src, *line, p, 2, kTokenPunctuator);
    } else if (p[1] == '=') {
      return AllocToken(src, *line, p, 2, kTokenPunctuator);
    }
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('>' == *p) {
    if (p[1] == '>') {
      if (p[2] == '=') {
        return AllocToken(src, *line, p, 3, kTokenPunctuator);
      }
      return AllocToken(src, *line, p, 2, kTokenPunctuator);
    } else if (p[1] == '=') {
      return AllocToken(src, *line, p, 2, kTokenPunctuator);
    }
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('=' == *p) {
    if (p[1] == '=') {
      return AllocToken(src, *line, p, 2, kTokenPunctuator);
    }
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('!' == *p) {
    if (p[1] == '=') {
      return AllocToken(src, *line, p, 2, kTokenPunctuator);
    }
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('^' == *p) {
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('+' == *p) {
    if (p[1] == '+') {
      return AllocToken(src, *line, p, 2, kTokenPunctuator);
    }
    if (p[1] == '=') {
      return AllocToken(src, *line, p, 2, kTokenPunctuator);
    }
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('-' == *p) {
    if (p[1] == '-' || p[1] == '=' || p[1] == '>') {
      return AllocToken(src, *line, p, 2, kTokenPunctuator);
    }
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('*' == *p) {
    if (p[1] == '/') {
      return AllocToken(src, *line, p, 2, kTokenBlockCommentEnd);
    }
    if (p[1] == '=') {
      return AllocToken(src, *line, p, 2, kTokenPunctuator);
    }
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('/' == *p) {
    if (p[1] == '/') {
      return AllocToken(src, *line, p, 2, kTokenLineComment);
    }
    if (p[1] == '*') {
      return AllocToken(src, *line, p, 2, kTokenBlockCommentBegin);
    }
    if (p[1] == '=') {
      return AllocToken(src, *line, p, 2, kTokenPunctuator);
    }
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('%' == *p) {
    if (p[1] == '=') {
      return AllocToken(src, *line, p, 2, kTokenPunctuator);
    }
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('~' == *p) {
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('?' == *p) {
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if (':' == *p) {
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if (',' == *p) {
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if (';' == *p) {
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('{' == *p) {
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('}' == *p) {
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('(' == *p) {
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if (')' == *p) {
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('.' == *p) {
    if (p[1] == '.' && p[2] == '.') {
      return AllocToken(src, *line, p, 3, kTokenPunctuator);
    }
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if ('[' == *p) {
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  } else if (']' == *p) {
    return AllocToken(src, *line, p, 1, kTokenPunctuator);
  }
  return AllocToken(src, *line, p, 1, kTokenUnknownChar);
}

// Assembly:
pushq %rbx
testq %rdx, %rdx
je 0x93a3
movq %rdi, %rax
movzbl (%rdi), %edi
testl %edi, %edi
je 0x8eaf
cmpl $0xa, %edi
je 0x8e81
cmpl $0x5c, %edi
je 0x8e9b
cmpl $0x20, %edi
jne 0x8eb6
movl (%rdx), %ecx
jmp 0x8e87
movl (%rdx), %ecx
incl %ecx
movl %ecx, (%rdx)
pushq $0x1
popq %r8
movq %rsi, %rdi
movl %ecx, %esi
movq %rax, %rdx
movl %r8d, %ecx
jmp 0x9221
cmpb $0xa, 0x1(%rax)
jne 0x9211
movl (%rdx), %ecx
incl %ecx
movl %ecx, (%rdx)
pushq $0x2
jmp 0x8e89
xorl %ebx, %ebx
movq %rbx, %rax
popq %rbx
retq
leal -0x31(%rdi), %ecx
cmpb $0x8, %cl
ja 0x8ee6
xorl %ecx, %ecx
movb (%rax,%rcx), %dil
addb $-0x30, %dil
incq %rcx
cmpb $0xa, %dil
jb 0x8ec0
decl %ecx
movl (%rdx), %edx
pushq $0x3
popq %r8
movq %rsi, %rdi
movl %edx, %esi
movq %rax, %rdx
jmp 0x9221
cmpb $0x30, %dil
jne 0x8f2a
cmpb $0x78, 0x1(%rax)
jne 0x9194
pushq $0x2
popq %rcx
movabsq $0x3f0000003f, %rdi     # imm = 0x3F0000003F
movb (%rax,%rcx), %r8b
leal -0x30(%r8), %r9d
cmpb $0xa, %r9b
jb 0x8f25
movzbl %r8b, %r8d
addl $-0x41, %r8d
cmpl $0x25, %r8d
ja 0x8ed3
btq %r8, %rdi
jae 0x8ed3
incq %rcx
jmp 0x8f03
movl %edi, %ecx
andb $-0x21, %cl
addb $-0x41, %cl
cmpb $0x1a, %cl
jae 0x91ae
xorl %ecx, %ecx
leal -0x41(%rdi), %r8d
cmpb $0x1a, %r8b
jb 0x8f61
leal -0x30(%rdi), %r8d
cmpb $0xa, %r8b
jb 0x8f61
cmpb $0x5f, %dil
je 0x8f61
addb $-0x61, %dil
cmpb $0x19, %dil
ja 0x8f6b
movb 0x1(%rax,%rcx), %dil
incq %rcx
jmp 0x8f3d
movl (%rdx), %edx
pushq $0x4
popq %r8
movq %rsi, %rdi
movl %edx, %esi
movq %rax, %rdx
callq 0x86ce
movq %rax, %rbx
leaq 0x3855(%rip), %rsi      # 0xc7dd
movq %rax, %rdi
callq 0x87de
testl %eax, %eax
je 0x8f9e
movl $0x5, 0x108(%rbx)
leaq 0x20c7(%rip), %rsi      # 0xb06c
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x8fbb
movl $0x6, 0x108(%rbx)
leaq 0x3821(%rip), %rsi      # 0xc7e3
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x8fd8
movl $0x7, 0x108(%rbx)
leaq 0x380a(%rip), %rsi      # 0xc7e9
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x8ff5
movl $0x8, 0x108(%rbx)
leaq 0x33ef(%rip), %rsi      # 0xc3eb
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x9012
movl $0x9, 0x108(%rbx)
leaq 0x37d9(%rip), %rsi      # 0xc7f2
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x902f
movl $0xa, 0x108(%rbx)
leaq 0x37c3(%rip), %rsi      # 0xc7f9
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x904c
movl $0xb, 0x108(%rbx)
leaq 0x33a0(%rip), %rsi      # 0xc3f3
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x9069
movl $0xc, 0x108(%rbx)
leaq 0x1ff8(%rip), %rsi      # 0xb068
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x9086
movl $0xd, 0x108(%rbx)
leaq 0x3770(%rip), %rsi      # 0xc7fd
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x90a3
movl $0xe, 0x108(%rbx)
leaq 0x3758(%rip), %rsi      # 0xc802
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x90c0
movl $0xf, 0x108(%rbx)
leaq 0x3742(%rip), %rsi      # 0xc809
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x90dd
movl $0x10, 0x108(%rbx)
leaq 0x372c(%rip), %rsi      # 0xc810
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x90fa
movl $0x11, 0x108(%rbx)
leaq 0x1fd4(%rip), %rsi      # 0xb0d5
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x9117
movl $0x12, 0x108(%rbx)
leaq 0x36f9(%rip), %rsi      # 0xc817
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x9134
movl $0x13, 0x108(%rbx)
leaq 0x36e4(%rip), %rsi      # 0xc81f
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x9151
movl $0x14, 0x108(%rbx)
leaq 0x36d0(%rip), %rsi      # 0xc828
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x916e
movl $0x15, 0x108(%rbx)
leaq 0x36b8(%rip), %rsi      # 0xc82d
movq %rbx, %rdi
callq 0x87de
testl %eax, %eax
je 0x8eb1
movl $0x16, 0x108(%rbx)
jmp 0x8eb1
pushq $-0x1
popq %rcx
movb 0x1(%rax,%rcx), %dil
andb $-0x8, %dil
incq %rcx
cmpb $0x30, %dil
je 0x9197
jmp 0x8ed3
leal -0x21(%rdi), %ecx
cmpl $0x1e, %ecx
ja 0x91cf
leaq 0x356f(%rip), %rdi      # 0xc72c
movslq (%rdi,%rcx,4), %rcx
addq %rdi, %rcx
jmpq *%rcx
cmpb $0x3d, 0x1(%rax)
jmp 0x934e
leal -0x5b(%rdi), %ecx
cmpl $0x4, %ecx
jbe 0x91f8
addl $-0x7b, %edi
cmpl $0x3, %edi
ja 0x9211
leaq 0x35d6(%rip), %rcx      # 0xc7bc
movslq (%rcx,%rdi,4), %rdi
addq %rcx, %rdi
jmpq *%rdi
cmpb $0x7c, 0x1(%rax)
jmp 0x934e
leaq 0x35a9(%rip), %r8       # 0xc7a8
movslq (%r8,%rcx,4), %rcx
addq %r8, %rcx
jmpq *%rcx
movl (%rdx), %edx
pushq $0x1
jmp 0x937a
movl (%rdx), %edx
pushq $0x1
popq %rcx
movq %rsi, %rdi
movl %edx, %esi
movq %rax, %rdx
xorl %r8d, %r8d
popq %rbx
jmp 0x86ce
movzbl 0x1(%rax), %ecx
movl (%rdx), %edx
cmpl $0x2a, %ecx
je 0x939c
cmpl $0x3d, %ecx
je 0x9378
cmpl $0x2f, %ecx
jne 0x920a
pushq $0x2
popq %rcx
pushq $0x1a
jmp 0x937d
movzbl 0x1(%rax), %ecx
movl (%rdx), %edx
cmpl $0x3d, %ecx
je 0x9378
cmpl $0x2f, %ecx
jne 0x920a
pushq $0x2
popq %rcx
pushq $0x1c
jmp 0x937d
cmpb $0x2e, 0x1(%rax)
jne 0x9208
cmpb $0x2e, 0x2(%rax)
jne 0x9208
movl (%rdx), %edx
jmp 0x9372
movzbl 0x1(%rax), %ecx
cmpl $0x3d, %ecx
je 0x9376
cmpl $0x3e, %ecx
je 0x936a
jmp 0x9208
pushq $0x1
popq %rcx
movslq %ecx, %r8
movzbl (%rax,%r8), %edi
cmpl $0x5c, %edi
je 0x92bc
cmpl $0x22, %edi
je 0x938c
testl %edi, %edi
jne 0x92cb
jmp 0x93b9
cmpb $0x0, 0x1(%rax,%r8)
leaq 0x1(%r8), %rdi
cmovel %ecx, %edi
movl %edi, %ecx
incl %ecx
jmp 0x929d
movzbl 0x1(%rax), %ecx
movl (%rdx), %edx
cmpl $0x3d, %ecx
je 0x9378
cmpl $0x2b, %ecx
je 0x9378
jmp 0x920a
pushq $0x1
popq %rcx
movslq %ecx, %r8
movzbl (%rax,%r8), %edi
cmpl $0x5c, %edi
je 0x930e
cmpl $0x27, %edi
je 0x9394
testl %edi, %edi
jne 0x931d
jmp 0x93c2
cmpb $0x0, 0x1(%rax,%r8)
leaq 0x1(%r8), %rdi
cmovel %ecx, %edi
movl %edi, %ecx
incl %ecx
jmp 0x92ef
cmpb $0x23, 0x1(%rax)
jmp 0x934e
movzbl 0x1(%rax), %ecx
cmpq $0x3e, %rcx
ja 0x9208
movabsq $0x6000200000000000, %rdi # imm = 0x6000200000000000
btq %rcx, %rdi
jb 0x9376
jmp 0x9208
cmpb $0x26, 0x1(%rax)
movl (%rdx), %edx
jne 0x920a
jmp 0x9378
movzbl 0x1(%rax), %ecx
cmpl $0x3d, %ecx
je 0x9376
cmpl $0x3c, %ecx
jne 0x9208
cmpb $0x3d, 0x2(%rax)
movl (%rdx), %edx
jne 0x9378
pushq $0x3
jmp 0x937a
movl (%rdx), %edx
pushq $0x2
popq %rcx
pushq $0x19
popq %r8
movq %rsi, %rdi
movl %edx, %esi
movq %rax, %rdx
jmp 0x9221
incl %ecx
movl (%rdx), %edx
pushq $0x18
jmp 0x937d
incl %ecx
movl (%rdx), %edx
pushq $0x17
jmp 0x937d
pushq $0x2
popq %rcx
pushq $0x1b
jmp 0x937d
leaq 0x3422(%rip), %rdi      # 0xc7cc
leaq 0x3420(%rip), %rsi      # 0xc7d1
pushq $0x4
popq %rdx
callq 0x3cc4
leaq 0x3494(%rip), %rdi      # 0xc854
jmp 0x93c9
leaq 0x346a(%rip), %rdi      # 0xc833
xorl %eax, %eax
callq 0x3bf8