// File: /workspace/github_c_makefile_star2_O3/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 0x9e9e
movq %rdi, %rax
movb (%rdi), %dil
movzbl %dil, %ecx
cmpl $0x1f, %ecx
jg 0x98d8
testl %ecx, %ecx
je 0x9930
cmpl $0xa, %ecx
jne 0x98fc
movl (%rdx), %ecx
incl %ecx
movl %ecx, (%rdx)
jmp 0x98e4
cmpl $0x5c, %ecx
je 0x9937
cmpl $0x20, %ecx
jne 0x98fc
movl (%rdx), %ecx
movq %rsi, %rdi
movl %ecx, %esi
movq %rax, %rdx
movl $0x1, %ecx
movl $0x1, %r8d
jmp 0x9cbc
leal -0x31(%rdi), %r8d
cmpb $0x8, %r8b
ja 0x995f
xorl %ecx, %ecx
movb (%rax,%rcx), %dil
addb $-0x30, %dil
incq %rcx
cmpb $0xa, %dil
jb 0x9908
decl %ecx
movl (%rdx), %edx
movq %rsi, %rdi
movl %edx, %esi
movq %rax, %rdx
movl $0x3, %r8d
jmp 0x9cbc
xorl %ebx, %ebx
movq %rbx, %rax
popq %rbx
retq
cmpb $0xa, 0x1(%rax)
jne 0x9caa
movl (%rdx), %ecx
incl %ecx
movl %ecx, (%rdx)
movq %rsi, %rdi
movl %ecx, %esi
movq %rax, %rdx
movl $0x2, %ecx
movl $0x2, %r8d
jmp 0x9cbc
cmpb $0x30, %dil
jne 0x99a9
cmpb $0x78, 0x1(%rax)
jne 0x9c19
movl $0x2, %ecx
movabsq $0x3f0000003f, %rdi     # imm = 0x3F0000003F
movb (%rax,%rcx), %r8b
leal -0x30(%r8), %r9d
cmpb $0xa, %r9b
jb 0x99a4
movzbl %r8b, %r8d
addl $-0x41, %r8d
cmpl $0x25, %r8d
ja 0x991b
btq %r8, %rdi
jae 0x991b
incq %rcx
jmp 0x997e
movl %edi, %r8d
andb $-0x21, %r8b
addb $-0x41, %r8b
cmpb $0x1a, %r8b
jae 0x9c37
xorl %ecx, %ecx
leal -0x41(%rdi), %r8d
cmpb $0x1a, %r8b
jb 0x99e4
leal -0x30(%rdi), %r8d
cmpb $0xa, %r8b
jb 0x99e4
cmpb $0x5f, %dil
je 0x99e4
addb $-0x61, %dil
cmpb $0x19, %dil
ja 0x99ee
movb 0x1(%rax,%rcx), %dil
incq %rcx
jmp 0x99c0
movl (%rdx), %edx
movq %rsi, %rdi
movl %edx, %esi
movq %rax, %rdx
movl $0x4, %r8d
callq 0x90ea
movq %rax, %rbx
leaq 0x2dd0(%rip), %rsi      # 0xc7dd
movq %rax, %rdi
callq 0x9210
testl %eax, %eax
je 0x9a23
movl $0x5, 0x108(%rbx)
leaq 0x1642(%rip), %rsi      # 0xb06c
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9a40
movl $0x6, 0x108(%rbx)
leaq 0x2d9c(%rip), %rsi      # 0xc7e3
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9a5d
movl $0x7, 0x108(%rbx)
leaq 0x2d85(%rip), %rsi      # 0xc7e9
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9a7a
movl $0x8, 0x108(%rbx)
leaq 0x296a(%rip), %rsi      # 0xc3eb
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9a97
movl $0x9, 0x108(%rbx)
leaq 0x2d54(%rip), %rsi      # 0xc7f2
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9ab4
movl $0xa, 0x108(%rbx)
leaq 0x2d3e(%rip), %rsi      # 0xc7f9
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9ad1
movl $0xb, 0x108(%rbx)
leaq 0x291b(%rip), %rsi      # 0xc3f3
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9aee
movl $0xc, 0x108(%rbx)
leaq 0x1573(%rip), %rsi      # 0xb068
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9b0b
movl $0xd, 0x108(%rbx)
leaq 0x2ceb(%rip), %rsi      # 0xc7fd
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9b28
movl $0xe, 0x108(%rbx)
leaq 0x2cd3(%rip), %rsi      # 0xc802
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9b45
movl $0xf, 0x108(%rbx)
leaq 0x2cbd(%rip), %rsi      # 0xc809
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9b62
movl $0x10, 0x108(%rbx)
leaq 0x2ca7(%rip), %rsi      # 0xc810
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9b7f
movl $0x11, 0x108(%rbx)
leaq 0x154f(%rip), %rsi      # 0xb0d5
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9b9c
movl $0x12, 0x108(%rbx)
leaq 0x2c74(%rip), %rsi      # 0xc817
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9bb9
movl $0x13, 0x108(%rbx)
leaq 0x2c5f(%rip), %rsi      # 0xc81f
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9bd6
movl $0x14, 0x108(%rbx)
leaq 0x2c4b(%rip), %rsi      # 0xc828
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9bf3
movl $0x15, 0x108(%rbx)
leaq 0x2c33(%rip), %rsi      # 0xc82d
movq %rbx, %rdi
callq 0x9210
testl %eax, %eax
je 0x9932
movl $0x16, 0x108(%rbx)
jmp 0x9932
movq $-0x1, %rcx
movb 0x1(%rax,%rcx), %dil
andb $-0x8, %dil
incq %rcx
cmpb $0x30, %dil
je 0x9c20
jmp 0x991b
leal -0x21(%rcx), %r8d
cmpl $0x1e, %r8d
ja 0x9c5a
leaq 0x2ae4(%rip), %rcx      # 0xc72c
movslq (%rcx,%r8,4), %rdi
addq %rcx, %rdi
jmpq *%rdi
cmpb $0x3d, 0x1(%rax)
jmp 0x9e0b
leal -0x5b(%rcx), %r8d
cmpl $0x4, %r8d
jbe 0x9c85
addl $-0x7b, %ecx
cmpl $0x3, %ecx
ja 0x9caa
leaq 0x2b49(%rip), %rdi      # 0xc7bc
movslq (%rdi,%rcx,4), %rcx
addq %rdi, %rcx
jmpq *%rcx
cmpb $0x7c, 0x1(%rax)
jmp 0x9e0b
leaq 0x2b1c(%rip), %rcx      # 0xc7a8
movslq (%rcx,%r8,4), %r8
addq %rcx, %r8
jmpq *%r8
movl (%rdx), %ecx
movq %rsi, %rdi
movl %ecx, %esi
movq %rax, %rdx
movl $0x1, %ecx
jmp 0x9e4d
movl (%rdx), %ecx
movq %rsi, %rdi
movl %ecx, %esi
movq %rax, %rdx
movl $0x1, %ecx
xorl %r8d, %r8d
popq %rbx
jmp 0x90ea
movzbl 0x1(%rax), %edi
movl (%rdx), %ecx
cmpl $0x2a, %edi
je 0x9e86
cmpl $0x3d, %edi
je 0x9e40
cmpl $0x2f, %edi
jne 0x9c98
movq %rsi, %rdi
movl %ecx, %esi
movq %rax, %rdx
movl $0x2, %ecx
movl $0x1a, %r8d
jmp 0x9cbc
movzbl 0x1(%rax), %edi
movl (%rdx), %ecx
cmpl $0x3d, %edi
je 0x9e40
cmpl $0x2f, %edi
jne 0x9c98
movq %rsi, %rdi
movl %ecx, %esi
movq %rax, %rdx
movl $0x2, %ecx
movl $0x1c, %r8d
jmp 0x9cbc
cmpb $0x2e, 0x1(%rax)
jne 0x9c96
cmpb $0x2e, 0x2(%rax)
jne 0x9c96
movl (%rdx), %ecx
jmp 0x9e2f
movzbl 0x1(%rax), %ecx
cmpl $0x3d, %ecx
je 0x9e3e
cmpl $0x3e, %ecx
je 0x9e27
jmp 0x9c96
movl $0x1, %ecx
movslq %ecx, %r8
movzbl (%rax,%r8), %edi
cmpl $0x5c, %edi
je 0x9d77
cmpl $0x22, %edi
je 0x9e58
testl %edi, %edi
jne 0x9d86
jmp 0x9eb6
cmpb $0x0, 0x1(%rax,%r8)
leaq 0x1(%r8), %rdi
cmovel %ecx, %edi
movl %edi, %ecx
incl %ecx
jmp 0x9d58
movzbl 0x1(%rax), %edi
movl (%rdx), %ecx
cmpl $0x3d, %edi
je 0x9e40
cmpl $0x2b, %edi
je 0x9e40
jmp 0x9c98
movl $0x1, %ecx
movslq %ecx, %r8
movzbl (%rax,%r8), %edi
cmpl $0x5c, %edi
je 0x9dcb
cmpl $0x27, %edi
je 0x9e6f
testl %edi, %edi
jne 0x9dda
jmp 0x9ebf
cmpb $0x0, 0x1(%rax,%r8)
leaq 0x1(%r8), %rdi
cmovel %ecx, %edi
movl %edi, %ecx
incl %ecx
jmp 0x9dac
cmpb $0x23, 0x1(%rax)
jmp 0x9e0b
movzbl 0x1(%rax), %ecx
cmpq $0x3e, %rcx
ja 0x9c96
movabsq $0x6000200000000000, %rdi # imm = 0x6000200000000000
btq %rcx, %rdi
jb 0x9e3e
jmp 0x9c96
cmpb $0x26, 0x1(%rax)
movl (%rdx), %ecx
jne 0x9c98
jmp 0x9e40
movzbl 0x1(%rax), %ecx
cmpl $0x3d, %ecx
je 0x9e3e
cmpl $0x3c, %ecx
jne 0x9c96
cmpb $0x3d, 0x2(%rax)
movl (%rdx), %ecx
jne 0x9e40
movq %rsi, %rdi
movl %ecx, %esi
movq %rax, %rdx
movl $0x3, %ecx
jmp 0x9e4d
movl (%rdx), %ecx
movq %rsi, %rdi
movl %ecx, %esi
movq %rax, %rdx
movl $0x2, %ecx
movl $0x19, %r8d
jmp 0x9cbc
incl %ecx
movl (%rdx), %edx
movq %rsi, %rdi
movl %edx, %esi
movq %rax, %rdx
movl $0x18, %r8d
jmp 0x9cbc
incl %ecx
movl (%rdx), %edx
movq %rsi, %rdi
movl %edx, %esi
movq %rax, %rdx
movl $0x17, %r8d
jmp 0x9cbc
movq %rsi, %rdi
movl %ecx, %esi
movq %rax, %rdx
movl $0x2, %ecx
movl $0x1b, %r8d
jmp 0x9cbc
leaq 0x2927(%rip), %rdi      # 0xc7cc
leaq 0x2925(%rip), %rsi      # 0xc7d1
movl $0x4, %edx
callq 0x46d0
leaq 0x2997(%rip), %rdi      # 0xc854
jmp 0x9ec6
leaq 0x296d(%rip), %rdi      # 0xc833
xorl %eax, %eax
callq 0x45fc