// File: /workspace/github_cpp_makefile_star2_O3/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 0x49c0
movq (%rbx), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
xorl %r13d, %r13d
testb $0x5, 0x20(%rdi,%rax)
movl $0x0, %ebp
jne 0x697d
leaq 0x3c(%rsp), %r15
movl $0x0, (%r15)
xorps %xmm0, %xmm0
leaq 0x40(%rsp), %r12
movaps %xmm0, (%r12)
movq $0x0, 0x10(%r12)
leaq 0x8(%rbx), %rax
movq %rax, 0x30(%rsp)
leaq 0x10(%rbx), %rax
movq %rax, 0x60(%rsp)
movq $0x0, 0x28(%rsp)
xorl %ebp, %ebp
movq %r12, %rsi
callq 0x4862
movq (%rbx), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
movl 0x20(%rdi,%rax), %eax
testb $0x2, %al
je 0x6204
cmpl $0x0, 0x208(%rdi)
je 0x676f
incl %r13d
testb $0x5, %al
jne 0x6907
movq 0x40(%rsp), %rax
movq 0x48(%rsp), %rcx
cmpq %rax, %rcx
je 0x61dd
movl %r13d, 0x3c(%rsp)
movq %rax, %r14
cmpl $0x5, (%r14)
je 0x630c
addq $0x28, %r14
cmpq %rcx, %r14
jne 0x6226
movl (%rax), %edx
cmpq $0x5, %rdx
ja 0x63d8
leaq 0x1ec8(%rip), %rsi      # 0x8114
movslq (%rsi,%rdx,4), %rdx
addq %rsi, %rdx
jmpq *%rdx
movl $0x16, %edx
movq 0x4d8f(%rip), %rdi      # 0xaff0
leaq 0x202b(%rip), %rsi      # 0x8293
callq 0x21f0
movq 0x40(%rsp), %rax
leaq 0x18(%rsp), %rcx
movq %rcx, 0x8(%rsp)
movq 0x8(%rax), %rsi
movq 0x10(%rax), %rdx
addq %rsi, %rdx
leaq 0x8(%rsp), %rdi
callq 0x4c28
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq 0x4d4e(%rip), %rdi      # 0xaff0
callq 0x21f0
movq %rax, %r14
movl $0xa, %edx
movq %rax, %rdi
leaq 0x1ff1(%rip), %rsi      # 0x82aa
callq 0x21f0
movl %r13d, %esi
movq %r14, %rdi
callq 0x2100
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x1e1c(%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 0x63b9
movl $0x16, %edx
movq 0x4cd8(%rip), %rdi      # 0xaff0
leaq 0x1f74(%rip), %rsi      # 0x8293
callq 0x21f0
leaq 0x18(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x8(%r14), %rsi
movq 0x10(%r14), %rdx
addq %rsi, %rdx
leaq 0x8(%rsp), %rdi
callq 0x4c28
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq 0x4c9c(%rip), %rdi      # 0xaff0
callq 0x21f0
movq %rax, %r14
movl $0xa, %edx
movq %rax, %rdi
leaq 0x1f3f(%rip), %rsi      # 0x82aa
callq 0x21f0
movl %r13d, %esi
movq %r14, %rdi
callq 0x2100
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x1d6a(%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 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x63d5
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x21b0
movb $0x1, %bpl
movq (%rbx), %rdi
jmp 0x61dd
addq $0x28, %rax
movq 0x28(%rsp), %rdx
addl -0x18(%rax), %edx
movq %rdx, 0x28(%rsp)
cmpq %rcx, %rax
je 0x64d2
leaq 0x28(%rax), %r14
cmpl $0x2, (%rax)
movq %r14, %rax
je 0x63e4
movl $0x16, %edx
movq 0x4bde(%rip), %rdi      # 0xaff0
leaq 0x1e7a(%rip), %rsi      # 0x8293
callq 0x21f0
leaq 0x18(%rsp), %rax
movq %rax, 0x8(%rsp)
movq -0x20(%r14), %rsi
movq -0x18(%r14), %rdx
addq %rsi, %rdx
leaq 0x8(%rsp), %rdi
callq 0x4c28
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq 0x4ba2(%rip), %rdi      # 0xaff0
callq 0x21f0
movq %rax, %r14
movl $0x19, %edx
movq %rax, %rdi
leaq 0x1e8c(%rip), %rsi      # 0x82f1
callq 0x21f0
movl %r13d, %esi
movq %r14, %rdi
callq 0x2100
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x1c70(%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 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x64cf
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x21b0
movb $0x1, %bpl
movq 0x28(%rsp), %rcx
movl %ecx, %eax
negl %eax
andl $0x3, %eax
addl %eax, %ecx
movq %rcx, 0x28(%rsp)
jmp 0x63d8
leaq 0x18(%rsp), %rcx
movq %rcx, 0x8(%rsp)
movq 0x8(%rax), %rsi
movq 0x10(%rax), %rdx
addq %rsi, %rdx
leaq 0x8(%rsp), %rdi
callq 0x4c28
movq 0x48(%rsp), %rax
subq 0x40(%rsp), %rax
cmpq $0x28, %rax
jne 0x66a1
movq 0x30(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x73d0
cmpq 0x60(%rsp), %rax
je 0x6757
movl $0x18, %edx
movq 0x4aad(%rip), %rdi      # 0xaff0
leaq 0x1dc1(%rip), %rsi      # 0x830b
callq 0x21f0
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq 0x4a90(%rip), %rdi      # 0xaff0
callq 0x21f0
movq %rax, %r14
movl $0xa, %edx
movq %rax, %rdi
leaq 0x1d33(%rip), %rsi      # 0x82aa
callq 0x21f0
movl %r13d, %esi
movq %r14, %rdi
callq 0x2100
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x1b5e(%rip), %rsi      # 0x80f7
callq 0x21f0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2190
jmp 0x671c
movq %rbx, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x5604
movq 0x28(%rsp), %rdx
leal 0x4(%rdx), %ecx
testb %al, %al
cmovel %edx, %ecx
movzbl %bpl, %ebp
movl $0x1, %eax
cmovel %eax, %ebp
movl %ecx, %eax
movq %rax, 0x28(%rsp)
jmp 0x63d8
movl $0xc, %edx
movq 0x49fa(%rip), %rdi      # 0xaff0
leaq 0x1cb8(%rip), %rsi      # 0x82b5
callq 0x21f0
movq 0x40(%rsp), %rax
leaq 0x18(%rsp), %rcx
movq %rcx, 0x8(%rsp)
movq 0x8(%rax), %rsi
movq 0x10(%rax), %rdx
addq %rsi, %rdx
leaq 0x8(%rsp), %rdi
callq 0x4c28
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq 0x49b9(%rip), %rdi      # 0xaff0
callq 0x21f0
movq %rax, %r14
movl $0x2e, %edx
movq %rax, %rdi
leaq 0x1c74(%rip), %rsi      # 0x82c2
callq 0x21f0
movl %r13d, %esi
movq %r14, %rdi
callq 0x2100
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x1a87(%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 0x63b9
movl $0x1e, %edx
movq 0x4943(%rip), %rdi      # 0xaff0
leaq 0x1c70(%rip), %rsi      # 0x8324
callq 0x21f0
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq 0x4926(%rip), %rdi      # 0xaff0
callq 0x21f0
movq %rax, %r14
movl $0x1c, %edx
movq %rax, %rdi
leaq 0x1c62(%rip), %rsi      # 0x8343
callq 0x21f0
movl %r13d, %esi
movq %r14, %rdi
callq 0x2100
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x19f4(%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 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x63d8
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x21b0
jmp 0x63d8
movq 0x30(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x6f02
movq 0x28(%rsp), %rcx
movl %ecx, (%rax)
jmp 0x6732
testb $0x1, %bpl
jne 0x696f
movq 0x38(%rbx), %r13
cmpq 0x40(%rbx), %r13
je 0x687f
leaq 0x8(%rsp), %r15
movq 0x485d(%rip), %r12      # 0xaff0
leaq 0x18(%rsp), %rax
movq %rax, 0x8(%rsp)
movq (%r13), %rsi
movq 0x8(%r13), %rdx
addq %rsi, %rdx
movq %r15, %rdi
callq 0x4c28
movl 0x20(%r13), %r14d
movq 0x30(%rsp), %rdi
movq %r15, %rsi
callq 0x73d0
cmpq 0x60(%rsp), %rax
jne 0x6855
movl $0x2b, %edx
movq %r12, %rdi
leaq 0x1b85(%rip), %rsi      # 0x8360
callq 0x21f0
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %r12, %rdi
callq 0x21f0
movq %rax, %rbp
movl $0xa, %edx
movq %rax, %rdi
leaq 0x1aa6(%rip), %rsi      # 0x82aa
callq 0x21f0
movq %rbp, %rdi
movq %r14, %rsi
callq 0x2100
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x18d1(%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 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x6871
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x21b0
addq $0x28, %r13
cmpq 0x40(%rbx), %r13
jne 0x6793
movq 0x28(%rsp), %rbx
cmpl $0x10000, %ebx          # imm = 0x10000
jbe 0x696f
movq 0x4759(%rip), %rdi      # 0xaff0
leaq 0x1aee(%rip), %rsi      # 0x838c
movl $0x17, %edx
callq 0x21f0
movl %ebx, %esi
movq 0x473f(%rip), %rdi      # 0xaff0
callq 0x2100
movq %rax, %rbx
leaq 0x1ae4(%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 0x1af9(%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
jmp 0x6959
movq 0x46e2(%rip), %rdi      # 0xaff0
leaq 0x1957(%rip), %rsi      # 0x826c
movl $0x26, %edx
callq 0x21f0
movl %r13d, %esi
movq 0x46c7(%rip), %rdi      # 0xaff0
callq 0x2100
movq %rax, %rbx
leaq 0x17bf(%rip), %rsi      # 0x80f7
movl $0x1, %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 0x6f7e
andb $0x1, %bpl
movl %ebp, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x69d5
jmp 0x69d5
jmp 0x69b4
jmp 0x69d5
jmp 0x69d5
jmp 0x69d5
jmp 0x69b4
jmp 0x69d5
jmp 0x69b4
jmp 0x69b4
jmp 0x69d5
jmp 0x69d5
jmp 0x69b4
jmp 0x69b4
jmp 0x69d5
jmp 0x69d5
jmp 0x69b4
movq %rax, %rbx
movq 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x69d8
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x21b0
jmp 0x69d8
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x6f7e
movq %rbx, %rdi
callq 0x2290