// File: /workspace/github_cpp_makefile_star2_O2/rfotino[P]consolite-compiler/src/syntax.cpp
// Function: ExprToken::output(Parser*, VarLocation const&)
void ExprToken::output(Parser *parser, const VarLocation& varLoc) {
  // Evaluate the postfix expression using the stack, pushing nullptr
  // as an operand where a temporary value would go (one that is
  // not already represented by a Token).
  std::stack<Operand> operands;
  for (auto token : _postfix) {
    auto op = std::dynamic_pointer_cast<OperatorToken>(token);
    auto global = std::dynamic_pointer_cast<GlobalVarToken>(token);
    auto var = std::dynamic_pointer_cast<Variable>(token);
    auto literal = std::dynamic_pointer_cast<LiteralToken>(token);
    auto fnCall = std::dynamic_pointer_cast<FunctionCallToken>(token);
    if (nullptr != op) {
      // Pop one or two operands off the stack, depending on if the
      // operator is unary or binary. Then output the operation in
      // assembly.
      Operand rhs = operands.top();
      operands.pop();
      Operand lhs;
      if (op->isBinary()) {
        lhs = operands.top();
        operands.pop();
      }
      Operand result = op->output(parser, lhs, rhs);
      operands.push(result);
    } else if (nullptr != global) {
      // Push the address onto the stack.
      parser->writeInst("MOVI L " + global->name());
      parser->writeInst("PUSH L");
      operands.push(Operand(OperandType::ADDRESS));
    } else if (nullptr != var) {
      // Push nothing onto the stack for a register, or the address onto the
      // stack for a variable on the stack.
      if (var->isReg()) {
        operands.push(Operand(OperandType::REGISTER, var->getReg()));
      } else {
        // Get the variable's location into register M
        parser->writeInst("MOV M FP");
        int offset = var->getOffset();
        if (0 != offset) {
          parser->writeInst("MOVI L " + toHexStr(0 < offset ? offset : -offset));
          if (0 < offset) {
            parser->writeInst("ADD M L");
          } else {
            parser->writeInst("SUB M L");
          }
        }
        // Push the address onto the stack.
        parser->writeInst("PUSH M");
        operands.push(Operand(OperandType::ADDRESS));
      }
    } else if (nullptr != literal) {
      // Don't do anything with the stack, we can save this literal for
      // later use.
      operands.push(Operand(OperandType::LITERAL, literal->val()));
    } else if (nullptr != fnCall) {
      // Get the result of the function call and push it onto the stack.
      fnCall->output(parser);
      parser->writeInst("PUSH L");
      // The result of a function call is a value token.
      operands.push(Operand(OperandType::VALUE));
    }
  }
  // Move the evaluated expression output to the given variable location.
  if (varLoc.isReg()) {
    operandValueToReg(parser, operands.top(), varLoc.getReg());
  } else {
    // Get the variable's address in a register so that we can store to
    // that address.
    int offset = varLoc.getOffset();
    parser->writeInst("MOV M FP");
    if (0 != offset) {
      if (offset < 0) {
        parser->writeInst("MOVI L " + toHexStr(-offset));
        parser->writeInst("SUB M L");
      } else {
        parser->writeInst("MOVI L " + toHexStr(offset));
        parser->writeInst("ADD M L");
      }
    }
    // Pop the result from the expression and store it in the calculated
    // address.
    operandValueToReg(parser, operands.top(), "L");
    parser->writeInst("STOR L M");
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x158, %rsp            # imm = 0x158
movq %rdx, 0xe8(%rsp)
movq %rsi, (%rsp)
movq %rdi, %r12
leaq 0x98(%rsp), %rdi
callq 0x18670
movq 0x10(%r12), %r15
movq 0x18(%r12), %rax
movq %rax, 0xf0(%rsp)
leaq 0x40(%rsp), %r14
leaq 0x38(%rsp), %r12
leaq 0x8(%rsp), %rbp
leaq 0x128(%rsp), %r13
cmpq 0xf0(%rsp), %r15
je 0x111dd
movq %r12, %rdi
movq %r15, %rsi
callq 0x18b56
leaq 0x78(%rsp), %rdi
movq %r12, %rsi
callq 0x183d8
leaq 0x118(%rsp), %rdi
movq %r12, %rsi
callq 0x18504
leaq 0x88(%rsp), %rdi
movq %r12, %rsi
callq 0x18619
leaq 0x108(%rsp), %rdi
movq %r12, %rsi
callq 0x1845a
leaq 0xf8(%rsp), %rdi
movq %r12, %rsi
callq 0x184af
cmpq $0x0, 0x78(%rsp)
je 0x10e5b
movq 0xc8(%rsp), %rsi
cmpq 0xd0(%rsp), %rsi
jne 0x10d94
movq 0xe0(%rsp), %rax
movq -0x8(%rax), %rsi
movl $0x1e0, %eax            # imm = 0x1E0
addq %rax, %rsi
addq $-0x30, %rsi
movq %rbp, %rdi
callq 0x1868c
leaq 0x98(%rsp), %rdi
callq 0x258ec
leaq 0x60(%rsp), %rax
movq %rax, 0x50(%rsp)
andq $0x0, 0x58(%rsp)
movb $0x0, 0x60(%rsp)
movq 0x78(%rsp), %rsi
cmpb $0x1, 0x30(%rsi)
jne 0x10e13
movq 0xc8(%rsp), %rsi
cmpq 0xd0(%rsp), %rsi
jne 0x10df3
movq 0xe0(%rsp), %rax
movq -0x8(%rax), %rsi
movl $0x1e0, %eax            # imm = 0x1E0
addq %rax, %rsi
addq $-0x30, %rsi
leaq 0x48(%rsp), %rdi
callq 0x186b8
leaq 0x98(%rsp), %rdi
callq 0x258ec
movq 0x78(%rsp), %rsi
movq %r13, %rbx
movq %r13, %rdi
movq (%rsp), %rdx
leaq 0x48(%rsp), %rcx
movq %rbp, %r8
callq 0xc820
leaq 0x98(%rsp), %rdi
movq %rbx, %rsi
callq 0x2595c
leaq 0x130(%rsp), %rdi
callq 0x75c8
leaq 0x50(%rsp), %rdi
callq 0x75c8
leaq 0x10(%rsp), %rdi
jmp 0x10f1e
movq 0x118(%rsp), %rsi
testq %rsi, %rsi
je 0x10f75
addq $0x70, %rsi
leaq 0x48(%rsp), %rbx
movq %rbx, %rdi
callq 0x73e0
movq %rbp, %rdi
leaq 0x18994(%rip), %rsi     # 0x2981b
movq %rbx, %rdx
callq 0x1832f
movq (%rsp), %rdi
movq %rbp, %rsi
callq 0x914a
movq %rbp, %rdi
callq 0x75c8
leaq 0x48(%rsp), %rbx
movq %rbx, %rdi
callq 0x75c8
movq %rbp, %rdi
leaq 0x188f1(%rip), %rsi     # 0x297ab
movq %rbx, %rdx
callq 0x9502
movq (%rsp), %rdi
movq %rbp, %rsi
callq 0x914a
movq %rbp, %rdi
callq 0x75c8
leaq 0x48(%rsp), %rbx
movq %rbx, %rdi
leaq 0x191ea(%rip), %rsi     # 0x2a0cf
movq %r13, %rdx
callq 0x9502
andl $0x0, 0x8(%rsp)
leaq 0x10(%rsp), %rdi
movq %rbx, %rsi
callq 0x73e0
leaq 0x98(%rsp), %rdi
movq %rbp, %rsi
callq 0x25bda
leaq 0x10(%rsp), %rdi
callq 0x75c8
leaq 0x48(%rsp), %rdi
callq 0x75c8
leaq 0x100(%rsp), %rdi
callq 0x7a34
leaq 0x110(%rsp), %rdi
callq 0x7a34
leaq 0x90(%rsp), %rdi
callq 0x7a34
leaq 0x120(%rsp), %rdi
callq 0x7a34
leaq 0x80(%rsp), %rdi
callq 0x7a34
movq %r14, %rdi
callq 0x7a34
addq $0x10, %r15
jmp 0x10cfc
movq 0x88(%rsp), %rsi
testq %rsi, %rsi
je 0x10fc4
cmpq $0x0, 0x8(%rsi)
je 0x11011
leaq 0x48(%rsp), %rbx
movq %rbx, %rdi
callq 0x73e0
movl $0x1, 0x8(%rsp)
leaq 0x10(%rsp), %rdi
movq %rbx, %rsi
callq 0x73e0
leaq 0x98(%rsp), %rdi
movq %rbp, %rsi
callq 0x25bda
jmp 0x10f0f
movq 0x108(%rsp), %rdi
testq %rdi, %rdi
je 0x110c9
movq (%rdi), %rax
callq *(%rax)
movl $0x3, 0x8(%rsp)
leaq 0x20(%rsp), %rcx
movq %rcx, 0x10(%rsp)
andq $0x0, 0x18(%rsp)
movb $0x0, 0x20(%rsp)
movw %ax, 0x30(%rsp)
leaq 0x98(%rsp), %rdi
movq %rbp, %rsi
callq 0x25bda
jmp 0x10e51
movq %rbp, %rdi
leaq 0x18996(%rip), %rsi     # 0x299b1
leaq 0x48(%rsp), %rdx
callq 0x9502
movq (%rsp), %rdi
movq %rbp, %rsi
callq 0x914a
movq %rbp, %rdi
callq 0x75c8
movq 0x88(%rsp), %rax
movl 0x20(%rax), %r14d
testl %r14d, %r14d
je 0x11172
movl %r14d, %eax
negl %eax
cmovsl %r14d, %eax
movzwl %ax, %esi
leaq 0x48(%rsp), %rbx
movq %rbx, %rdi
pushq $0x4
popq %rdx
callq 0x27ea7
movq %rbp, %rdi
leaq 0x187a7(%rip), %rsi     # 0x2981b
movq %rbx, %rdx
callq 0x1832f
movq (%rsp), %rdi
movq %rbp, %rsi
callq 0x914a
movq %rbp, %rdi
callq 0x75c8
leaq 0x48(%rsp), %rbx
movq %rbx, %rdi
callq 0x75c8
testl %r14d, %r14d
jle 0x1114c
movq %rbp, %rdi
leaq 0x1890a(%rip), %rsi     # 0x299ba
movq %rbx, %rdx
callq 0x9502
movq (%rsp), %rdi
movq %rbp, %rsi
callq 0x914a
jmp 0x1116a
movq 0xf8(%rsp), %rdi
testq %rdi, %rdi
je 0x10f23
movq (%rsp), %rsi
callq 0x1156e
movq %rbp, %rdi
leaq 0x186be(%rip), %rsi     # 0x297ab
leaq 0x48(%rsp), %rdx
callq 0x9502
movq (%rsp), %rdi
movq %rbp, %rsi
callq 0x914a
movq %rbp, %rdi
callq 0x75c8
leaq 0x48(%rsp), %rbx
movq %rbx, %rdi
leaq 0x18fb5(%rip), %rsi     # 0x2a0cf
movq %r13, %rdx
callq 0x9502
movl $0x2, 0x8(%rsp)
leaq 0x10(%rsp), %rdi
movq %rbx, %rsi
callq 0x73e0
leaq 0x98(%rsp), %rdi
movq %rbp, %rsi
callq 0x25bda
jmp 0x10f0f
movq %rbp, %rdi
leaq 0x1886c(%rip), %rsi     # 0x299c2
movq %rbx, %rdx
callq 0x9502
movq (%rsp), %rdi
movq %rbp, %rsi
callq 0x914a
movq %rbp, %rdi
callq 0x75c8
movq %rbp, %rdi
leaq 0x1859f(%rip), %rsi     # 0x2971b
leaq 0x48(%rsp), %rdx
leaq 0x40(%rsp), %r14
callq 0x9502
movq (%rsp), %rdi
movq %rbp, %rsi
callq 0x914a
movq %rbp, %rdi
callq 0x75c8
leaq 0x48(%rsp), %rbx
movq %rbx, %rdi
leaq 0x18f21(%rip), %rsi     # 0x2a0cf
movq %r13, %rdx
callq 0x9502
andl $0x0, 0x8(%rsp)
leaq 0x10(%rsp), %rdi
movq %rbx, %rsi
callq 0x73e0
leaq 0x98(%rsp), %rdi
movq %rbp, %rsi
callq 0x25bda
jmp 0x10f0f
movq 0xe8(%rsp), %rsi
cmpq $0x0, 0x8(%rsi)
je 0x11234
movq 0xc8(%rsp), %r14
cmpq 0xd0(%rsp), %r14
jne 0x11210
movq 0xe0(%rsp), %rax
movl $0x1e0, %r14d           # imm = 0x1E0
addq -0x8(%rax), %r14
leaq 0x8(%rsp), %rdi
callq 0x73e0
addq $-0x30, %r14
leaq 0x8(%rsp), %rdx
movq (%rsp), %rdi
movq %r14, %rsi
callq 0x27c70
jmp 0x113d2
movl 0x20(%rsi), %ebx
leaq 0x18773(%rip), %rsi     # 0x299b1
leaq 0x8(%rsp), %rdi
leaq 0x48(%rsp), %rdx
callq 0x9502
leaq 0x8(%rsp), %rsi
movq (%rsp), %rdi
callq 0x914a
leaq 0x8(%rsp), %rdi
callq 0x75c8
testl %ebx, %ebx
je 0x11355
js 0x112dd
movzwl %bx, %esi
leaq 0x48(%rsp), %rdi
pushq $0x4
popq %rdx
callq 0x27ea7
leaq 0x18595(%rip), %rsi     # 0x2981b
leaq 0x8(%rsp), %rdi
leaq 0x48(%rsp), %rdx
callq 0x1832f
leaq 0x8(%rsp), %rsi
movq (%rsp), %rdi
callq 0x914a
leaq 0x8(%rsp), %rdi
callq 0x75c8
leaq 0x48(%rsp), %rdi
callq 0x75c8
leaq 0x186fc(%rip), %rsi     # 0x299ba
leaq 0x8(%rsp), %rdi
leaq 0x48(%rsp), %rdx
callq 0x9502
leaq 0x8(%rsp), %rsi
movq (%rsp), %rdi
callq 0x914a
jmp 0x1134b
negl %ebx
movzwl %bx, %esi
leaq 0x48(%rsp), %rdi
pushq $0x4
popq %rdx
callq 0x27ea7
leaq 0x18525(%rip), %rsi     # 0x2981b
leaq 0x8(%rsp), %rdi
leaq 0x48(%rsp), %rdx
callq 0x1832f
leaq 0x8(%rsp), %rsi
movq (%rsp), %rdi
callq 0x914a
leaq 0x8(%rsp), %rdi
callq 0x75c8
leaq 0x48(%rsp), %rdi
callq 0x75c8
leaq 0x18694(%rip), %rsi     # 0x299c2
leaq 0x8(%rsp), %rdi
leaq 0x48(%rsp), %rdx
callq 0x9502
leaq 0x8(%rsp), %rsi
movq (%rsp), %rdi
callq 0x914a
leaq 0x8(%rsp), %rdi
callq 0x75c8
movq 0xc8(%rsp), %r14
cmpq 0xd0(%rsp), %r14
jne 0x11379
movq 0xe0(%rsp), %rax
movl $0x1e0, %r14d           # imm = 0x1E0
addq -0x8(%rax), %r14
leaq 0x18758(%rip), %rsi     # 0x29ad8
leaq 0x8(%rsp), %rdi
leaq 0x48(%rsp), %rdx
callq 0x9502
addq $-0x30, %r14
leaq 0x8(%rsp), %rdx
movq (%rsp), %rdi
movq %r14, %rsi
callq 0x27c70
leaq 0x8(%rsp), %rdi
callq 0x75c8
leaq 0x18615(%rip), %rsi     # 0x299ca
leaq 0x8(%rsp), %rdi
leaq 0x48(%rsp), %rdx
callq 0x9502
leaq 0x8(%rsp), %rsi
movq (%rsp), %rdi
callq 0x914a
leaq 0x8(%rsp), %rdi
callq 0x75c8
leaq 0x98(%rsp), %rdi
callq 0x18c10
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x11453
jmp 0x11465
jmp 0x11409
jmp 0x11418
jmp 0x11465
jmp 0x11453
jmp 0x11465
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x75c8
jmp 0x1141b
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
jmp 0x1145b
jmp 0x11465
jmp 0x1148f
jmp 0x11471
jmp 0x11453
jmp 0x11465
jmp 0x11453
jmp 0x11465
jmp 0x11453
jmp 0x11465
jmp 0x114c2
jmp 0x114d1
jmp 0x114dd
jmp 0x114a3
jmp 0x114dd
jmp 0x114dd
jmp 0x1148f
jmp 0x11471
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x75c8
jmp 0x11559
movq %rax, %rbx
jmp 0x11559
jmp 0x114b4
jmp 0x114d1
movq %rax, %rbx
jmp 0x1150b
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
jmp 0x114ab
jmp 0x114dd
jmp 0x114c2
jmp 0x114d1
jmp 0x114dd
jmp 0x114a3
jmp 0x114dd
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
jmp 0x11506
jmp 0x114dd
jmp 0x114c2
jmp 0x114d1
jmp 0x114dd
jmp 0x114dd
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x75c8
jmp 0x11510
jmp 0x114dd
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
jmp 0x114ca
jmp 0x114d1
jmp 0x114dd
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x75c8
jmp 0x114d4
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
jmp 0x11506
jmp 0x114f4
movq %rax, %rbx
jmp 0x11510
movq %rax, %rbx
leaq 0x130(%rsp), %rdi
callq 0x75c8
jmp 0x114f7
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x75c8
leaq 0x10(%rsp), %rdi
callq 0x75c8
leaq 0x40(%rsp), %r14
leaq 0x100(%rsp), %rdi
callq 0x7a34
leaq 0x110(%rsp), %rdi
callq 0x7a34
leaq 0x90(%rsp), %rdi
callq 0x7a34
leaq 0x120(%rsp), %rdi
callq 0x7a34
leaq 0x80(%rsp), %rdi
callq 0x7a34
movq %r14, %rdi
callq 0x7a34
leaq 0x98(%rsp), %rdi
callq 0x18c10
movq %rbx, %rdi
callq 0x7510