// File: /workspace/github_cpp_makefile_star2_O1/rfotino[P]consolite-assembler/src/parser.cpp
// Function: Parser::firstPass()
bool Parser::firstPass() {
  _tokenizer->reset();
  if (_tokenizer->hasError()) {
    return false;
  }

  bool error = false;
  unsigned line = 0;
  unsigned byte_pos = 0;
  std::vector<Token> tokens;
  while (true) {
    // Get the next line of tokens
    _tokenizer->getLineOfTokens(tokens);
    line++;
    // If there is an error or the tokenizer is
    // empty, break out of the loop
    if (_tokenizer->isEmpty()) {
      line--;
      break;
    }
    if (_tokenizer->hasError()) {
      error = true;
      std::cerr << "Error reading from input file on line "
                << line << "." << std::endl;
      break;
    }
    // If it's an empty line, do nothing
    if (0 == tokens.size()) {
      continue;
    }
    // If there's an unknown token, that's an error
    bool has_unknown = false;
    for (auto token = tokens.begin(); token != tokens.end(); token++) {
      if (UNKNOWN == token->getType()) {
        error = true;
        has_unknown = true;
        std::cerr << "Error: Unknown token '" << token->getData()
                  << "' on line " << line << "." << std::endl;
        break;
      }
    }
    // If there's an unknown token don't validate any further
    if (has_unknown) {
      continue;
    }
    // Validate based on lead token
    switch (tokens[0].getType()) {
    case OPCODE:
      // Validate further based on specific opcode
      if (_validateInstruction(tokens, line)) {
        byte_pos += 4;
      } else {
        error = true;
      }
      break;
    case REGISTER:
      error = true;
      std::cerr << "Error: REG '" << tokens[0].getData()
                << "' not allowed at start of instruction on line " << line
                << "." << std::endl;
      break;
    case DATA:
      // Make sure all tokens on this line are data, and
      // add their sizes to the byte offset at this point
      for (auto token = tokens.begin(); token != tokens.end(); token++) {
        if (DATA == token->getType()) {
          byte_pos += token->getSize();
        } else {
          error = true;
          std::cerr << "Error: Unknown token '" << token->getData()
               << "', expected DATA on line " << line
               << "." << std::endl;
          break;
        }
      }
      // Pad data to 4 bytes so that instructions that
      // follow are aligned correctly
      while (0 != byte_pos % 4) {
        byte_pos++;
      }
      break;
    case LABELDECL:
      {
        const std::string label = tokens[0].getData();
        if (1 == tokens.size()) {
          if (_labels.find(label) == _labels.end()) {
            _labels[label] = byte_pos;
          } else {
            error = true;
            std::cerr << "Error: Duplicate LABEL '" << label
                      << "' on line " << line << "." << std::endl;
          }
        } else {
          error = true;
          std::cerr << "Error: Invalid syntax, LABEL '" << label
                    << "' must be by itself on line " << line
                    << "." << std::endl;
        }
      }
      break;
    case LABELREF:
    case UNKNOWN:
      error = true;
      std::cerr << "Error: Unknown token '" << tokens[0].getData()
                << "' on line " << line << "." << std::endl;
      break;
    }
  }

  if (!error) {
    // Check that all of the label references have a corresponding
    // label. If not, that is another error.
    for (auto ref = _labelRefs.begin(); ref != _labelRefs.end(); ref++) {
      std::string ref_label = ref->first;
      unsigned ref_line = ref->second;
      if (_labels.find(ref_label) == _labels.end()) {
        error = true;
        std::cerr << "Error: Could not find LABEL for reference '"
                  << ref_label << "' on line " << ref_line
                  << "." << std::endl;
      }
    }
    // Check if the total size of the output will be too large,
    // which would be another error.
    if (MAX_OUTPUT_SIZE < byte_pos) {
      error = true;
      std::cerr << "Error: Output would be " << byte_pos
                << " bytes, which is larger than the maximum output size of "
                << MAX_OUTPUT_SIZE << " bytes." << std::endl;
    }
  }

  return !error;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rdi, %rbx
movq (%rdi), %rdi
callq 0x4a42
movq (%rbx), %rax
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
xorl %r15d, %r15d
testb $0x5, 0x20(%rax,%rcx)
movl $0x0, %ebp
jne 0x6abb
leaq 0xc(%rsp), %rdx
movl $0x0, (%rdx)
xorps %xmm0, %xmm0
leaq 0x40(%rsp), %r12
movaps %xmm0, (%r12)
movq $0x0, 0x10(%r12)
leaq 0x8(%rbx), %rax
movq %rax, 0x38(%rsp)
leaq 0x10(%rbx), %rax
movq %rax, 0x60(%rsp)
movq $0x0, 0x30(%rsp)
xorl %ebp, %ebp
movq (%rbx), %rdi
movq %r12, %rsi
callq 0x48e0
movq (%rbx), %rcx
movq (%rcx), %rax
movq -0x18(%rax), %rax
movl 0x20(%rcx,%rax), %eax
testb $0x2, %al
je 0x62c8
cmpl $0x0, 0x208(%rcx)
je 0x688e
incl %r15d
testb $0x5, %al
jne 0x6895
movq 0x40(%rsp), %r14
movq 0x48(%rsp), %rax
cmpq %r14, %rax
je 0x629e
cmpl $0x5, (%r14)
jne 0x62ed
xorl %r13d, %r13d
jmp 0x6312
addq $0x28, %r14
cmpq %rax, %r14
sete %r13b
je 0x63de
leaq 0x28(%r14), %rcx
cmpl $0x5, (%r14)
movq %rcx, %r14
jne 0x62f1
addq $-0x28, %rcx
movq %rcx, %r14
movl $0x16, %edx
movq 0x4cd2(%rip), %rdi      # 0xaff0
leaq 0x1f6e(%rip), %rsi      # 0x8293
callq 0x21f0
leaq 0x20(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x8(%r14), %rsi
movq 0x10(%r14), %rdx
addq %rsi, %rdx
leaq 0x10(%rsp), %rdi
callq 0x4caa
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdx
movq 0x4c96(%rip), %rdi      # 0xaff0
callq 0x21f0
movq %rax, %r14
movl $0xa, %edx
movq %rax, %rdi
leaq 0x1f39(%rip), %rsi      # 0x82aa
callq 0x21f0
movl %r15d, %esi
movq %r14, %rdi
callq 0x2100
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x1d64(%rip), %rsi      # 0x80f7
callq 0x21f0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2190
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2110
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x63db
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x21b0
movb $0x1, %bpl
testb %r13b, %r13b
leaq 0xc(%rsp), %rdx
leaq 0x1d27(%rip), %rcx      # 0x8114
movl $0x1, %r13d
je 0x629e
movq 0x40(%rsp), %r14
movl (%r14), %eax
cmpq $0x5, %rax
ja 0x629e
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x16, %edx
movq 0x4bd0(%rip), %rdi      # 0xaff0
leaq 0x1e6c(%rip), %rsi      # 0x8293
callq 0x21f0
movq 0x40(%rsp), %rax
leaq 0x20(%rsp), %rcx
movq %rcx, 0x10(%rsp)
movq 0x8(%rax), %rsi
movq 0x10(%rax), %rdx
addq %rsi, %rdx
leaq 0x10(%rsp), %rdi
callq 0x4caa
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdx
movq 0x4b8f(%rip), %rdi      # 0xaff0
callq 0x21f0
movq %rax, %r14
movl $0xa, %edx
movq %rax, %rdi
leaq 0x1e32(%rip), %rsi      # 0x82aa
callq 0x21f0
movl %r15d, %esi
movq %r14, %rdi
callq 0x2100
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x1c5d(%rip), %rsi      # 0x80f7
callq 0x21f0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2190
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2110
jmp 0x657d
movl $0xc, %edx
movq 0x4b19(%rip), %rdi      # 0xaff0
leaq 0x1dd7(%rip), %rsi      # 0x82b5
callq 0x21f0
movq 0x40(%rsp), %rax
leaq 0x20(%rsp), %rcx
movq %rcx, 0x10(%rsp)
movq 0x8(%rax), %rsi
movq 0x10(%rax), %rdx
addq %rsi, %rdx
leaq 0x10(%rsp), %rdi
callq 0x4caa
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdx
movq 0x4ad8(%rip), %rdi      # 0xaff0
callq 0x21f0
movq %rax, %r14
movl $0x2e, %edx
movq %rax, %rdi
leaq 0x1d93(%rip), %rsi      # 0x82c2
callq 0x21f0
movl %r15d, %esi
movq %r14, %rdi
callq 0x2100
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x1ba6(%rip), %rsi      # 0x80f7
callq 0x21f0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2190
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2110
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x6599
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x21b0
movb $0x1, %bpl
jmp 0x629e
leaq 0x20(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x8(%r14), %rsi
movq 0x10(%r14), %rdx
addq %rsi, %rdx
leaq 0x10(%rsp), %rdi
callq 0x4caa
movq 0x48(%rsp), %rax
subq 0x40(%rsp), %rax
cmpq $0x28, %rax
jne 0x666b
movq 0x38(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x7518
cmpq 0x60(%rsp), %rax
je 0x6721
movl $0x18, %edx
movq 0x49f6(%rip), %rdi      # 0xaff0
leaq 0x1d0a(%rip), %rsi      # 0x830b
callq 0x21f0
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdx
movq 0x49d9(%rip), %rdi      # 0xaff0
callq 0x21f0
movq %rax, %r14
movl $0xa, %edx
movq %rax, %rdi
leaq 0x1c7c(%rip), %rsi      # 0x82aa
callq 0x21f0
movl %r15d, %esi
movq %r14, %rdi
callq 0x2100
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x1aa7(%rip), %rsi      # 0x80f7
callq 0x21f0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2190
jmp 0x66e6
movl $0x1e, %edx
movq 0x4979(%rip), %rdi      # 0xaff0
leaq 0x1ca6(%rip), %rsi      # 0x8324
callq 0x21f0
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdx
movq 0x495c(%rip), %rdi      # 0xaff0
callq 0x21f0
movq %rax, %r14
movl $0x1c, %edx
movq %rax, %rdi
leaq 0x1c98(%rip), %rsi      # 0x8343
callq 0x21f0
movl %r15d, %esi
movq %r14, %rdi
callq 0x2100
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x1a2a(%rip), %rsi      # 0x80f7
callq 0x21f0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2190
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movb $0x1, %bpl
movq %rax, %rdi
callq 0x2110
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x629e
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x21b0
jmp 0x629e
movq 0x38(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x7054
movq 0x30(%rsp), %rcx
movl %ecx, (%rax)
jmp 0x66fc
movl %r15d, 0xc(%rsp)
movq %rbx, %rdi
movq %r12, %rsi
callq 0x56a8
movq 0x30(%rsp), %rdx
leal 0x4(%rdx), %ecx
testb %al, %al
cmovel %edx, %ecx
movzbl %bpl, %ebp
cmovel %r13d, %ebp
movl %ecx, %eax
movq %rax, 0x30(%rsp)
jmp 0x629e
movl %r15d, 0xc(%rsp)
movq 0x48(%rsp), %rax
cmpq %rax, %r14
je 0x6876
addq $0x10, %r14
cmpl $0x2, -0x10(%r14)
jne 0x67ab
movq 0x30(%rsp), %rcx
addl (%r14), %ecx
movq %rcx, 0x30(%rsp)
leaq -0x10(%r14), %rcx
addq $0x28, %r14
addq $0x28, %rcx
cmpq %rax, %rcx
jne 0x6781
jmp 0x6876
movl $0x16, %edx
movq 0x4839(%rip), %rdi      # 0xaff0
leaq 0x1ad5(%rip), %rsi      # 0x8293
callq 0x21f0
leaq 0x20(%rsp), %rax
movq %rax, 0x10(%rsp)
movq -0x8(%r14), %rsi
movq (%r14), %rdx
addq %rsi, %rdx
leaq 0x10(%rsp), %rdi
callq 0x4caa
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdx
movq 0x47fe(%rip), %rdi      # 0xaff0
callq 0x21f0
movq %rax, %r14
movl $0x19, %edx
movq %rax, %rdi
leaq 0x1ae8(%rip), %rsi      # 0x82f1
callq 0x21f0
movl %r15d, %esi
movq %r14, %rdi
callq 0x2100
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x18cc(%rip), %rsi      # 0x80f7
callq 0x21f0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2190
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2110
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x6873
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x21b0
movb $0x1, %bpl
movq 0x30(%rsp), %rcx
movl %ecx, %eax
negl %eax
andl $0x3, %eax
addl %eax, %ecx
movq %rcx, 0x30(%rsp)
jmp 0x629e
movl %r15d, 0xc(%rsp)
jmp 0x6902
movl %r15d, 0xc(%rsp)
movq 0x474f(%rip), %rdi      # 0xaff0
leaq 0x19c4(%rip), %rsi      # 0x826c
movl $0x26, %edx
callq 0x21f0
movl %r15d, %esi
movq 0x4734(%rip), %rdi      # 0xaff0
callq 0x2100
movq %rax, %r14
leaq 0x182c(%rip), %rsi      # 0x80f7
movl $0x1, %edx
movq %rax, %rdi
callq 0x21f0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2190
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movb $0x1, %bpl
movq %rax, %rdi
callq 0x2110
testb $0x1, %bpl
jne 0x6aad
movq 0x38(%rbx), %r13
cmpq 0x40(%rbx), %r13
je 0x6a12
leaq 0x10(%rsp), %r15
movq 0x46ca(%rip), %r12      # 0xaff0
leaq 0x20(%rsp), %rax
movq %rax, 0x10(%rsp)
movq (%r13), %rsi
movq 0x8(%r13), %rdx
addq %rsi, %rdx
movq %r15, %rdi
callq 0x4caa
movl 0x20(%r13), %r14d
movq 0x38(%rsp), %rdi
movq %r15, %rsi
callq 0x7518
cmpq 0x60(%rsp), %rax
jne 0x69e8
movl $0x2b, %edx
movq %r12, %rdi
leaq 0x19f2(%rip), %rsi      # 0x8360
callq 0x21f0
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdx
movq %r12, %rdi
callq 0x21f0
movq %rax, %rbp
movl $0xa, %edx
movq %rax, %rdi
leaq 0x1913(%rip), %rsi      # 0x82aa
callq 0x21f0
movq %rbp, %rdi
movq %r14, %rsi
callq 0x2100
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x173e(%rip), %rsi      # 0x80f7
callq 0x21f0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2190
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movb $0x1, %bpl
movq %rax, %rdi
callq 0x2110
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x6a04
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x21b0
addq $0x28, %r13
cmpq 0x40(%rbx), %r13
jne 0x6926
cmpl $0x10000, 0x30(%rsp)    # imm = 0x10000
jbe 0x6aad
movq 0x45c9(%rip), %rdi      # 0xaff0
leaq 0x195e(%rip), %rsi      # 0x838c
movl $0x17, %edx
callq 0x21f0
movl 0x30(%rsp), %esi
movq 0x45ad(%rip), %rdi      # 0xaff0
callq 0x2100
movq %rax, %rbx
leaq 0x1952(%rip), %rsi      # 0x83a4
movl $0x38, %edx
movq %rax, %rdi
callq 0x21f0
movq %rbx, %rdi
movl $0x10000, %esi          # imm = 0x10000
callq 0x2280
movq %rax, %rbx
leaq 0x1967(%rip), %rsi      # 0x83dd
movl $0x7, %edx
movq %rax, %rdi
callq 0x21f0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2190
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movb $0x1, %bpl
movq %rax, %rdi
callq 0x2110
xorb $0x1, %bpl
leaq 0x40(%rsp), %rdi
callq 0x70d0
andb $0x1, %bpl
movl %ebp, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x6af8
jmp 0x6af8
jmp 0x6af8
jmp 0x6b09
jmp 0x6aec
jmp 0x6aff
jmp 0x6aff
jmp 0x6aff
jmp 0x6aff
jmp 0x6aec
jmp 0x6aec
jmp 0x6aff
jmp 0x6aff
jmp 0x6aec
movq %rax, %rbx
movl %r15d, 0xc(%rsp)
jmp 0x6b0c
jmp 0x6af8
movq %rax, %rbx
jmp 0x6b28
jmp 0x6b09
movq %rax, %rbx
movl %r15d, 0xc(%rsp)
jmp 0x6b28
movq %rax, %rbx
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x6b28
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x21b0
leaq 0x40(%rsp), %rdi
callq 0x70d0
movq %rbx, %rdi
callq 0x2290