// File: CoinXu[P]reviser-compiler/src/tokenizer.cpp
// Function: reviser::compiler::Tokenizer::Next()
bool Tokenizer::Next() {
  previous = current;

  if (pos >= input.size()) {
    current.type = TOKEN_CODE_END;
    current.text = "";
    return false;
  }

  ConsumeCharacters<Whitespace>();
  ConsumeComment();

  current.text = peek;

  int start_line = line;
  int start_column = column;
  int start_pos = pos;

  switch (peek) {
    case EOF:
      current.type = TOKEN_CODE_END;
      current.text = "";
      break;

    case TOKEN_ASSIGN:
    case TOKEN_LEFT_BRACE:
    case TOKEN_RIGHT_BRACE:
    case TOKEN_SEMICOLON:
    case TOKEN_COMMA:
    case TOKEN_CONNECTION:
    case TOKEN_LEFT_BRACKET:
    case TOKEN_RIGHT_BRACKET:
      current.type = (TokenType)peek;
      NextChar();
      break;

    case TOKEN_QUOTE:
      current.type = TOKEN_LETTER;
      NextChar();
      TryConsumeCharacters<CharQuote>();
      NextChar();
      current.text = input.substr(start_pos, pos - start_pos - 2);
      break;

    case TOKEN_PLUS:
    case TOKEN_HYPHEN:
      current.type = TOKEN_DIGIT;
      NextChar();
      ConsumeNumber();
      current.text = input.substr(start_pos - 1, pos - start_pos);
      break;

    default:
      if (InCharacters<CharDigit>()) {
        current.type = TOKEN_DIGIT;
        ConsumeNumber();
        current.text = input.substr(start_pos - 1, pos - start_pos);
      } else if (InCharacters<Identifier>()) {
        ConsumeCharacters<Identifier>();
        current.text = input.substr(start_pos - 1, pos - start_pos);

        if (TypeIdentifier(current.text)) {
          current.type = TOKEN_DATA_TYPE;
        } else if (DecoraterIdentifier(current.text)) {
          current.type = TOKEN_DECORATER;
        } else if (current.text == ReservedWordMap[RESERVED_STRUCT]) {
          current.type = TOKEN_STRUCT;
        } else if (current.text == ReservedWordMap[RESERVED_ENUM]) {
          current.type = TOKEN_ENUM;
        } else {
          current.type = TOKEN_ID;
        }
      } else {
        TryConsumeCharacters<NewLine>();
        const string content = input.substr(start_pos - 1,  pos - start_pos);
        message.Runtime("unkown token error: \n  " + content + "\n  ^");
      }
  }

  current.start_line = start_line;
  current.end_line = line;
  current.column_start = start_column;
  current.column_end = column - 1;
  current.pos_start = start_pos;
  current.pos_end = pos;

  return current.type != TOKEN_CODE_END;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1c0, %rsp            # imm = 0x1C0
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x168(%rbp)
movq %rdi, %rsi
addq $0x78, %rsi
addq $0xb8, %rdi
callq 0xaae40
movq -0x168(%rbp), %rdi
movslq 0xfc(%rdi), %rax
movq %rax, -0x160(%rbp)
callq 0x99350
movq %rax, %rcx
movq -0x160(%rbp), %rax
cmpq %rcx, %rax
jb 0xae9b1
movq -0x168(%rbp), %rdi
movl $0x9, 0x78(%rdi)
addq $0x78, %rdi
addq $0x8, %rdi
leaq 0x5220c(%rip), %rsi     # 0x100baf
callq 0x99630
movb $0x0, -0x1(%rbp)
jmp 0xaf012
movq -0x168(%rbp), %rdi
callq 0xafda0
movq -0x168(%rbp), %rdi
callq 0xae3f0
movq -0x168(%rbp), %rdi
movsbl 0xf8(%rdi), %esi
subq $-0x80, %rdi
callq 0x997a0
movq -0x168(%rbp), %rax
movl 0x100(%rax), %ecx
movl %ecx, -0x14(%rbp)
movl 0x104(%rax), %ecx
movl %ecx, -0x18(%rbp)
movl 0xfc(%rax), %ecx
movl %ecx, -0x1c(%rbp)
movsbl 0xf8(%rax), %eax
movl %eax, -0x16c(%rbp)
subl $-0x1, %eax
je 0xaeabc
jmp 0xaea1a
movl -0x16c(%rbp), %eax
subl $0x22, %eax
je 0xaeafe
jmp 0xaea2b
movl -0x16c(%rbp), %eax
subl $0x2b, %eax
je 0xaeb72
jmp 0xaea3c
movl -0x16c(%rbp), %eax
subl $0x2c, %eax
je 0xaeae3
jmp 0xaea4d
movl -0x16c(%rbp), %eax
subl $0x2d, %eax
je 0xaeb72
jmp 0xaea5e
movl -0x16c(%rbp), %eax
subl $0x2e, %eax
je 0xaeae3
jmp 0xaea6b
movl -0x16c(%rbp), %eax
subl $0x3b, %eax
je 0xaeae3
jmp 0xaea78
movl -0x16c(%rbp), %eax
subl $0x3d, %eax
je 0xaeae3
jmp 0xaea85
movl -0x16c(%rbp), %eax
subl $0x5b, %eax
je 0xaeae3
jmp 0xaea92
movl -0x16c(%rbp), %eax
subl $0x5d, %eax
je 0xaeae3
jmp 0xaea9f
movl -0x16c(%rbp), %eax
subl $0x7b, %eax
je 0xaeae3
jmp 0xaeaac
movl -0x16c(%rbp), %eax
subl $0x7d, %eax
je 0xaeae3
jmp 0xaebdc
movq -0x168(%rbp), %rdi
movl $0x9, 0x78(%rdi)
addq $0x78, %rdi
addq $0x8, %rdi
leaq 0x520d6(%rip), %rsi     # 0x100baf
callq 0x99630
jmp 0xaefbd
movq -0x168(%rbp), %rdi
movsbl 0xf8(%rdi), %eax
movl %eax, 0x78(%rdi)
callq 0xae140
jmp 0xaefbd
movq -0x168(%rbp), %rdi
movl $0x5, 0x78(%rdi)
callq 0xae140
movq -0x168(%rbp), %rdi
callq 0xaff10
movq -0x168(%rbp), %rdi
callq 0xae140
movq -0x168(%rbp), %rsi
movslq -0x1c(%rbp), %rdx
movl 0xfc(%rsi), %eax
subl -0x1c(%rbp), %eax
subl $0x2, %eax
movslq %eax, %rcx
leaq -0x40(%rbp), %rdi
callq 0x994a0
movq -0x168(%rbp), %rdi
addq $0x78, %rdi
addq $0x8, %rdi
leaq -0x40(%rbp), %rsi
callq 0x99590
leaq -0x40(%rbp), %rdi
callq 0x992c0
jmp 0xaefbd
movq -0x168(%rbp), %rdi
movl $0x6, 0x78(%rdi)
callq 0xae140
movq -0x168(%rbp), %rdi
callq 0xae4c0
movq -0x168(%rbp), %rsi
movl -0x1c(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rdx
movl 0xfc(%rsi), %eax
subl -0x1c(%rbp), %eax
movslq %eax, %rcx
leaq -0x60(%rbp), %rdi
callq 0x994a0
movq -0x168(%rbp), %rdi
addq $0x78, %rdi
addq $0x8, %rdi
leaq -0x60(%rbp), %rsi
callq 0x99590
leaq -0x60(%rbp), %rdi
callq 0x992c0
jmp 0xaefbd
movq -0x168(%rbp), %rdi
callq 0xaff50
testb $0x1, %al
jne 0xaebee
jmp 0xaec4c
movq -0x168(%rbp), %rdi
movl $0x6, 0x78(%rdi)
callq 0xae4c0
movq -0x168(%rbp), %rsi
movl -0x1c(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rdx
movl 0xfc(%rsi), %eax
subl -0x1c(%rbp), %eax
movslq %eax, %rcx
leaq -0x80(%rbp), %rdi
callq 0x994a0
movq -0x168(%rbp), %rdi
addq $0x78, %rdi
addq $0x8, %rdi
leaq -0x80(%rbp), %rsi
callq 0x99590
leaq -0x80(%rbp), %rdi
callq 0x992c0
jmp 0xaefbb
movq -0x168(%rbp), %rdi
callq 0xaff80
testb $0x1, %al
jne 0xaec61
jmp 0xaee99
movq -0x168(%rbp), %rdi
callq 0xaffb0
movq -0x168(%rbp), %rsi
movl -0x1c(%rbp), %ecx
movl %ecx, %eax
decl %eax
movslq %eax, %rdx
movl 0xfc(%rsi), %eax
subl %ecx, %eax
movslq %eax, %rcx
leaq -0xa0(%rbp), %rdi
movq %rdi, -0x188(%rbp)
callq 0x994a0
movq -0x188(%rbp), %rsi
movq -0x168(%rbp), %rdi
subq $-0x80, %rdi
movq %rdi, -0x180(%rbp)
callq 0x99590
movq -0x188(%rbp), %rdi
callq 0x992c0
movq -0x180(%rbp), %rsi
leaq -0xc0(%rbp), %rdi
movq %rdi, -0x178(%rbp)
callq 0x991c0
movq -0x168(%rbp), %rdi
movq -0x178(%rbp), %rsi
callq 0xae2f0
movb %al, -0x16d(%rbp)
jmp 0xaecfb
leaq -0xc0(%rbp), %rdi
callq 0x992c0
movb -0x16d(%rbp), %al
testb $0x1, %al
jne 0xaed13
jmp 0xaed49
movq -0x168(%rbp), %rax
movl $0x0, 0x78(%rax)
jmp 0xaee94
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0x992c0
jmp 0xaf020
movq -0x168(%rbp), %rsi
subq $-0x80, %rsi
leaq -0xf0(%rbp), %rdi
movq %rdi, -0x198(%rbp)
callq 0x991c0
movq -0x168(%rbp), %rdi
movq -0x198(%rbp), %rsi
callq 0xae370
movb %al, -0x189(%rbp)
jmp 0xaed82
leaq -0xf0(%rbp), %rdi
callq 0x992c0
movb -0x189(%rbp), %al
testb $0x1, %al
jne 0xaed9a
jmp 0xaedd0
movq -0x168(%rbp), %rax
movl $0x1, 0x78(%rax)
jmp 0xaee92
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x992c0
jmp 0xaf020
movq -0x168(%rbp), %rax
addq $0x78, %rax
addq $0x8, %rax
movq %rax, -0x1a0(%rbp)
movl $0x0, -0xf4(%rbp)
leaq 0x81c49(%rip), %rdi     # 0x130a40
leaq -0xf4(%rbp), %rsi
callq 0xa48c0
movq -0x1a0(%rbp), %rdi
movq %rax, %rsi
callq 0xa4830
testb $0x1, %al
jne 0xaee18
jmp 0xaee28
movq -0x168(%rbp), %rax
movl $0x2, 0x78(%rax)
jmp 0xaee90
movq -0x168(%rbp), %rax
addq $0x78, %rax
addq $0x8, %rax
movq %rax, -0x1a8(%rbp)
movl $0x1, -0xf8(%rbp)
leaq 0x81bf1(%rip), %rdi     # 0x130a40
leaq -0xf8(%rbp), %rsi
callq 0xa48c0
movq -0x1a8(%rbp), %rdi
movq %rax, %rsi
callq 0xa4830
testb $0x1, %al
jne 0xaee70
jmp 0xaee80
movq -0x168(%rbp), %rax
movl $0x3, 0x78(%rax)
jmp 0xaee8e
movq -0x168(%rbp), %rax
movl $0x4, 0x78(%rax)
jmp 0xaee90
jmp 0xaee92
jmp 0xaee94
jmp 0xaefb9
movq -0x168(%rbp), %rdi
callq 0xafcf0
movq -0x168(%rbp), %rsi
movl -0x1c(%rbp), %ecx
movl %ecx, %eax
decl %eax
movslq %eax, %rdx
movl 0xfc(%rsi), %eax
subl %ecx, %eax
movslq %eax, %rcx
leaq -0x118(%rbp), %rdi
movq %rdi, -0x1b8(%rbp)
callq 0x994a0
movq -0x168(%rbp), %rax
movq -0x1b8(%rbp), %rdx
addq $0x50, %rax
movq %rax, -0x1b0(%rbp)
leaq 0x50951(%rip), %rsi     # 0xff845
leaq -0x158(%rbp), %rdi
callq 0xa6e30
jmp 0xaef02
leaq 0x50954(%rip), %rdx     # 0xff85d
leaq -0x138(%rbp), %rdi
leaq -0x158(%rbp), %rsi
callq 0xa10c0
jmp 0xaef1e
movq -0x1b0(%rbp), %rdi
leaq -0x138(%rbp), %rsi
callq 0xa6bb0
jmp 0xaef33
leaq -0x138(%rbp), %rdi
callq 0x992c0
leaq -0x158(%rbp), %rdi
callq 0x992c0
leaq -0x118(%rbp), %rdi
callq 0x992c0
jmp 0xaefb9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0xaefab
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0xaef9f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0x138(%rbp), %rdi
callq 0x992c0
leaq -0x158(%rbp), %rdi
callq 0x992c0
leaq -0x118(%rbp), %rdi
callq 0x992c0
jmp 0xaf020
jmp 0xaefbb
jmp 0xaefbd
movq -0x168(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, 0xa0(%rax)
movl 0x100(%rax), %ecx
movl %ecx, 0xa4(%rax)
movl -0x18(%rbp), %ecx
movl %ecx, 0xa8(%rax)
movl 0x104(%rax), %ecx
subl $0x1, %ecx
movl %ecx, 0xac(%rax)
movl -0x1c(%rbp), %ecx
movl %ecx, 0xb0(%rax)
movl 0xfc(%rax), %ecx
movl %ecx, 0xb4(%rax)
cmpl $0x9, 0x78(%rax)
setne %al
andb $0x1, %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x1c0, %rsp            # imm = 0x1C0
popq %rbp
retq
movq -0xc8(%rbp), %rdi
callq 0x99840
nopl (%rax)