// File: rfotino[P]consolite-compiler/src/parser.cpp
// Function: Parser::output(char*)
bool Parser::output(char *filename) {
  // Start by opening the output file.
  _outfile.open(filename, std::ofstream::out | std::ofstream::trunc);
  if (!_outfile.good()) {
    _error("Unable to open output file.");
    return false;
  }
  // Next assign labels for all globals and functions.
  for (auto global : _globals) {
    this->addLabel(global->name());
  }
  for (auto function : _functions) {
    this->addLabel(function->name());
  }
  // Output the "bootloader". This sets the stack pointer, calls main,
  // then goes into an infinite loop to prevent attempting to execute
  // code that wasn't meant to be executed.
  std::string stackLabel = this->getUnusedLabel("stack");
  this->writeInst("MOVI SP " + stackLabel);
  this->writeInst("CALL main");
  std::string finishedLabel = this->getUnusedLabel("program_finished");
  this->writeln(finishedLabel + ":");
  this->writeInst("JMPI " + finishedLabel);
  // Output global variables.
  for (auto global : _globals) {
    global->output(this);
  }
  // Output functions.
  for (auto function: _functions) {
    function->output(this);
  }
  // Output the stack position.
  this->writeln(stackLabel + ":");
  return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2c0, %rsp            # imm = 0x2C0
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x270(%rbp)
addq $0x38, %rax
movq %rax, -0x280(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x278(%rbp)
movl $0x10, %edi
movl $0x20, %esi
callq 0xd990
movq -0x280(%rbp), %rdi
movq -0x278(%rbp), %rsi
movl %eax, %edx
callq 0x8080
movq -0x270(%rbp), %rax
movq %rax, %rdi
addq $0x38, %rdi
movq 0x38(%rax), %rax
addq -0x18(%rax), %rdi
callq 0x86c0
testb $0x1, %al
jne 0xbc40
leaq -0x39(%rbp), %rdi
movq %rdi, -0x288(%rbp)
callq 0x8760
movq -0x288(%rbp), %rdx
leaq 0x634fa(%rip), %rsi     # 0x6f0d3
leaq -0x38(%rbp), %rdi
callq 0xced0
jmp 0xbbe4
leaq -0x38(%rbp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x6d960
jmp 0xbbf4
leaq -0x38(%rbp), %rdi
callq 0x8848
leaq -0x39(%rbp), %rdi
callq 0x8460
movb $0x0, -0x1(%rbp)
jmp 0xc342
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xbc32
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x8848
leaq -0x39(%rbp), %rdi
callq 0x8460
jmp 0xc350
movq -0x270(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rdi
callq 0xd9b0
movq %rax, -0x60(%rbp)
movq -0x58(%rbp), %rdi
callq 0xd9e0
movq %rax, -0x68(%rbp)
leaq -0x60(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0xda10
testb $0x1, %al
jne 0xbc7f
jmp 0xbd28
leaq -0x60(%rbp), %rdi
callq 0xda50
movq %rax, %rsi
leaq -0x78(%rbp), %rdi
movq %rdi, -0x290(%rbp)
callq 0xda70
movq -0x290(%rbp), %rdi
callq 0xd830
movq %rax, %rsi
addq $0x10, %rsi
leaq -0x98(%rbp), %rdi
callq 0xdaa0
jmp 0xbcbc
movq -0x270(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0xc360
jmp 0xbcd1
leaq -0x98(%rbp), %rdi
callq 0x8848
leaq -0x78(%rbp), %rdi
callq 0x9880
leaq -0x60(%rbp), %rdi
callq 0xdad0
jmp 0xbc69
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xbd1a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x8848
leaq -0x78(%rbp), %rdi
callq 0x9880
jmp 0xc350
movq -0x270(%rbp), %rax
addq $0x20, %rax
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rdi
callq 0xdaf0
movq %rax, -0xa8(%rbp)
movq -0xa0(%rbp), %rdi
callq 0xdb20
movq %rax, -0xb0(%rbp)
leaq -0xa8(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0xdb50
testb $0x1, %al
jne 0xbd7c
jmp 0xbe30
leaq -0xa8(%rbp), %rdi
callq 0xdb90
movq %rax, %rsi
leaq -0xc0(%rbp), %rdi
movq %rdi, -0x298(%rbp)
callq 0xdbb0
movq -0x298(%rbp), %rdi
callq 0xd780
movq %rax, %rsi
leaq -0xe0(%rbp), %rdi
callq 0xdbe0
jmp 0xbdbb
movq -0x270(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0xc360
jmp 0xbdd0
leaq -0xe0(%rbp), %rdi
callq 0x8848
leaq -0xc0(%rbp), %rdi
callq 0x94c0
leaq -0xa8(%rbp), %rdi
callq 0xdc10
jmp 0xbd60
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xbe1f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x8848
leaq -0xc0(%rbp), %rdi
callq 0x94c0
jmp 0xc350
leaq -0x121(%rbp), %rdi
movq %rdi, -0x2a0(%rbp)
callq 0x8760
movq -0x2a0(%rbp), %rdx
leaq 0x6329e(%rip), %rsi     # 0x6f0ef
leaq -0x120(%rbp), %rdi
callq 0xced0
jmp 0xbe5f
movq -0x270(%rbp), %rsi
leaq -0x100(%rbp), %rdi
leaq -0x120(%rbp), %rdx
callq 0xc3c0
jmp 0xbe7b
leaq -0x120(%rbp), %rdi
callq 0x8848
leaq -0x121(%rbp), %rdi
callq 0x8460
leaq 0x6325b(%rip), %rsi     # 0x6f0f5
leaq -0x148(%rbp), %rdi
leaq -0x100(%rbp), %rdx
callq 0xdc30
jmp 0xbeaf
movq -0x270(%rbp), %rdi
leaq -0x148(%rbp), %rsi
callq 0xc600
jmp 0xbec4
leaq -0x148(%rbp), %rdi
callq 0x8848
leaq -0x169(%rbp), %rdi
movq %rdi, -0x2a8(%rbp)
callq 0x8760
movq -0x2a8(%rbp), %rdx
leaq 0x6320d(%rip), %rsi     # 0x6f0fe
leaq -0x168(%rbp), %rdi
callq 0xced0
jmp 0xbeff
movq -0x270(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0xc600
jmp 0xbf14
leaq -0x168(%rbp), %rdi
callq 0x8848
leaq -0x169(%rbp), %rdi
callq 0x8460
leaq -0x1b1(%rbp), %rdi
movq %rdi, -0x2b0(%rbp)
callq 0x8760
movq -0x2b0(%rbp), %rdx
leaq 0x631bb(%rip), %rsi     # 0x6f108
leaq -0x1b0(%rbp), %rdi
callq 0xced0
jmp 0xbf5b
movq -0x270(%rbp), %rsi
leaq -0x190(%rbp), %rdi
leaq -0x1b0(%rbp), %rdx
callq 0xc3c0
jmp 0xbf77
leaq -0x1b0(%rbp), %rdi
callq 0x8848
leaq -0x1b1(%rbp), %rdi
callq 0x8460
leaq 0x656b2(%rip), %rdx     # 0x71648
leaq -0x1d8(%rbp), %rdi
leaq -0x190(%rbp), %rsi
callq 0xdd40
jmp 0xbfab
movq -0x270(%rbp), %rdi
leaq -0x1d8(%rbp), %rsi
callq 0xcc30
jmp 0xbfc0
leaq -0x1d8(%rbp), %rdi
callq 0x8848
leaq 0x63146(%rip), %rsi     # 0x6f119
leaq -0x1f8(%rbp), %rdi
leaq -0x190(%rbp), %rdx
callq 0xdc30
jmp 0xbfe8
movq -0x270(%rbp), %rdi
leaq -0x1f8(%rbp), %rsi
callq 0xc600
jmp 0xbffd
leaq -0x1f8(%rbp), %rdi
callq 0x8848
movq -0x270(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x200(%rbp)
movq -0x200(%rbp), %rdi
callq 0xd9b0
movq %rax, -0x208(%rbp)
movq -0x200(%rbp), %rdi
callq 0xd9e0
movq %rax, -0x210(%rbp)
leaq -0x208(%rbp), %rdi
leaq -0x210(%rbp), %rsi
callq 0xda10
testb $0x1, %al
jne 0xc05d
jmp 0xc1f1
leaq -0x208(%rbp), %rdi
callq 0xda50
movq %rax, %rsi
leaq -0x220(%rbp), %rdi
movq %rdi, -0x2b8(%rbp)
callq 0xda70
movq -0x2b8(%rbp), %rdi
callq 0xd830
movq -0x270(%rbp), %rsi
movq %rax, %rdi
callq 0x25c20
jmp 0xc09c
leaq -0x220(%rbp), %rdi
callq 0x9880
leaq -0x208(%rbp), %rdi
callq 0xdad0
jmp 0xc041
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xc0dc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x120(%rbp), %rdi
callq 0x8848
leaq -0x121(%rbp), %rdi
callq 0x8460
jmp 0xc350
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xc334
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x148(%rbp), %rdi
callq 0x8848
jmp 0xc334
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xc141
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x8848
leaq -0x169(%rbp), %rdi
callq 0x8460
jmp 0xc334
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xc178
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0x8848
leaq -0x1b1(%rbp), %rdi
callq 0x8460
jmp 0xc334
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xc328
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x1d8(%rbp), %rdi
callq 0x8848
jmp 0xc328
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x8848
jmp 0xc328
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x220(%rbp), %rdi
callq 0x9880
jmp 0xc328
movq -0x270(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x228(%rbp)
movq -0x228(%rbp), %rdi
callq 0xdaf0
movq %rax, -0x230(%rbp)
movq -0x228(%rbp), %rdi
callq 0xdb20
movq %rax, -0x238(%rbp)
leaq -0x230(%rbp), %rdi
leaq -0x238(%rbp), %rsi
callq 0xdb50
testb $0x1, %al
jne 0xc242
jmp 0xc2b5
leaq -0x230(%rbp), %rdi
callq 0xdb90
movq %rax, %rsi
leaq -0x248(%rbp), %rdi
movq %rdi, -0x2c0(%rbp)
callq 0xdbb0
movq -0x2c0(%rbp), %rdi
callq 0xd780
movq -0x270(%rbp), %rsi
movq %rax, %rdi
callq 0x295c0
jmp 0xc281
leaq -0x248(%rbp), %rdi
callq 0x94c0
leaq -0x230(%rbp), %rdi
callq 0xdc10
jmp 0xc229
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x248(%rbp), %rdi
callq 0x94c0
jmp 0xc328
leaq 0x6538c(%rip), %rdx     # 0x71648
leaq -0x268(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0xdd40
jmp 0xc2d1
movq -0x270(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0xcc30
jmp 0xc2e6
leaq -0x268(%rbp), %rdi
callq 0x8848
movb $0x1, -0x1(%rbp)
leaq -0x190(%rbp), %rdi
callq 0x8848
leaq -0x100(%rbp), %rdi
callq 0x8848
jmp 0xc342
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x268(%rbp), %rdi
callq 0x8848
leaq -0x190(%rbp), %rdi
callq 0x8848
leaq -0x100(%rbp), %rdi
callq 0x8848
jmp 0xc350
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x2c0, %rsp            # imm = 0x2C0
popq %rbp
retq
movq -0x48(%rbp), %rdi
callq 0x8750
nopl (%rax)