// File: rfotino[P]consolite-compiler/src/syntax.cpp
// Function: ExprToken::_evaluate()
void ExprToken::_evaluate() {
  // Evaluate the postfix expression
  std::stack<std::shared_ptr<Token>> operands;
  for (auto token : _postfix) {
    auto op = std::dynamic_pointer_cast<OperatorToken>(token);
    if (std::dynamic_pointer_cast<LiteralToken>(token) ||
        std::dynamic_pointer_cast<GlobalVarToken>(token)) {
      operands.push(token);
    } else if (std::dynamic_pointer_cast<ParamToken>(token) ||
               std::dynamic_pointer_cast<LocalVarToken>(token) ||
               std::dynamic_pointer_cast<FunctionCallToken>(token)) {
      // We don't know parameter or local variable values at
      // compile time, nor do we know the output of functions,
      // so this expression can't be constant.
      _const = false;
      return;
    } else if (nullptr != op) {
      std::shared_ptr<Token> rhs = operands.top();
      operands.pop();
      std::shared_ptr<Token> lhs;
      if (op->isBinary()) {
        lhs = operands.top();
        operands.pop();
      } else {
        lhs = nullptr;
      }
      uint16_t result;
      // If using assignment, dereferencing, or address-of, this
      // expression is not considered constant.
      if (("=" == op->str() && op->isBinary()) ||
          (("&" == op->str() || "*" == op->str()) && op->isUnary())) {
        _const = false;
        return;
      } else if ("[" == op->str() && op->isBinary()) {
        auto global = std::dynamic_pointer_cast<GlobalVarToken>(lhs);
        if (nullptr == global) {
          _const = false;
          return;
        }
        if (!global->isArray()) {
          _const = false;
          return;
        } else if (global->arraySize() <= rhs->val()) {
          _warn("Array index out of bounds in expression.", _lineNum);
          _const = false;
          return;
        }
        result = global->arrayVal(rhs->val());
      } else {
        result = op->operate(lhs ? lhs->val() : 0, rhs->val());
      }
      operands.push(std::shared_ptr<Token>(new LiteralToken(result)));
    } else {
      _const = false;
      return;
    }
  }
  _value = operands.top()->val();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2b0, %rsp            # imm = 0x2B0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x220(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x32870
movq -0x220(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rdi
callq 0x32fd0
movq %rax, -0x68(%rbp)
movq -0x60(%rbp), %rdi
callq 0x33000
movq %rax, -0x70(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x33030
testb $0x1, %al
jne 0x21502
jmp 0x21f8e
leaq -0x68(%rbp), %rdi
callq 0x33070
movq %rax, %rsi
leaq -0x80(%rbp), %rdi
callq 0x33090
leaq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x32a80
leaq -0xa0(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x330c0
leaq -0xa0(%rbp), %rdi
callq 0x33150
movb %al, %cl
movb $0x0, -0xb1(%rbp)
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x221(%rbp)
jne 0x21582
leaq -0xb0(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x33220
movb $0x1, -0xb1(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x332b0
movb %al, -0x221(%rbp)
movb -0x221(%rbp), %al
movb %al, -0x222(%rbp)
testb $0x1, -0xb1(%rbp)
jne 0x21599
jmp 0x215a5
leaq -0xb0(%rbp), %rdi
callq 0x9880
leaq -0xa0(%rbp), %rdi
callq 0x32f90
movb -0x222(%rbp), %al
testb $0x1, %al
jne 0x215bd
jmp 0x215e8
leaq -0x58(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x334e0
jmp 0x215cc
jmp 0x21f26
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
jmp 0x21f77
leaq -0xd8(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x332d0
leaq -0xd8(%rbp), %rdi
callq 0x33360
movb %al, %cl
movb $0x0, -0xe9(%rbp)
movb $0x0, -0x101(%rbp)
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x223(%rbp)
jne 0x2167c
leaq -0xe8(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x33380
movb $0x1, -0xe9(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x33410
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x223(%rbp)
jne 0x2167c
leaq -0x100(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x33170
movb $0x1, -0x101(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x33200
movb %al, -0x223(%rbp)
movb -0x223(%rbp), %al
movb %al, -0x224(%rbp)
testb $0x1, -0x101(%rbp)
jne 0x21693
jmp 0x2169f
leaq -0x100(%rbp), %rdi
callq 0x32f70
testb $0x1, -0xe9(%rbp)
jne 0x216aa
jmp 0x216b6
leaq -0xe8(%rbp), %rdi
callq 0x10dc0
leaq -0xd8(%rbp), %rdi
callq 0xd400
movb -0x224(%rbp), %al
testb $0x1, %al
jne 0x216ce
jmp 0x216e8
movq -0x220(%rbp), %rax
movb $0x0, 0xc(%rax)
movl $0x1, -0x108(%rbp)
jmp 0x21f30
xorl %eax, %eax
movl %eax, %edi
leaq -0x90(%rbp), %rsi
callq 0x33430
testb $0x1, %al
jne 0x21701
jmp 0x21f0b
leaq -0x58(%rbp), %rdi
callq 0x32b10
movq %rax, -0x230(%rbp)
jmp 0x21713
movq -0x230(%rbp), %rsi
leaq -0x118(%rbp), %rdi
callq 0x33090
leaq -0x58(%rbp), %rdi
callq 0x32be0
jmp 0x21731
leaq -0x128(%rbp), %rdi
callq 0x33510
leaq -0x90(%rbp), %rdi
callq 0x32c70
movq %rax, %rdi
callq 0x32590
movb %al, -0x231(%rbp)
jmp 0x21759
movb -0x231(%rbp), %al
testb $0x1, %al
jne 0x21765
jmp 0x217c5
leaq -0x58(%rbp), %rdi
callq 0x32b10
movq %rax, -0x240(%rbp)
jmp 0x21777
movq -0x240(%rbp), %rsi
leaq -0x128(%rbp), %rdi
callq 0x33530
leaq -0x58(%rbp), %rdi
callq 0x32be0
jmp 0x21795
jmp 0x217f4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
jmp 0x21efd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
jmp 0x21ef1
leaq -0x138(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x33560
leaq -0x128(%rbp), %rdi
leaq -0x138(%rbp), %rsi
callq 0x33580
leaq -0x138(%rbp), %rdi
callq 0x327f0
leaq -0x90(%rbp), %rdi
callq 0x32c70
movq %rax, %rsi
movb $0x0, -0x181(%rbp)
movb $0x0, -0x1a9(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x33460
jmp 0x2181f
leaq 0x4de5c(%rip), %rdi     # 0x6f682
leaq -0x160(%rbp), %rsi
callq 0xd590
movb %al, -0x241(%rbp)
jmp 0x2183a
movb -0x241(%rbp), %al
testb $0x1, %al
jne 0x21846
jmp 0x2187b
leaq -0x90(%rbp), %rdi
callq 0x32c70
movq %rax, %rdi
callq 0x32590
movb %al, -0x242(%rbp)
jmp 0x21862
movb -0x242(%rbp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x243(%rbp)
jne 0x21950
jmp 0x2187b
leaq -0x90(%rbp), %rdi
callq 0x32c70
movq %rax, %rsi
leaq -0x180(%rbp), %rdi
callq 0x33460
jmp 0x21898
movb $0x1, -0x181(%rbp)
leaq 0x4ddd0(%rip), %rdi     # 0x6f676
leaq -0x180(%rbp), %rsi
callq 0xd590
movb %al, -0x244(%rbp)
jmp 0x218ba
movb -0x244(%rbp), %al
testb $0x1, %al
jne 0x2191a
jmp 0x218c6
leaq -0x90(%rbp), %rdi
callq 0x32c70
movq %rax, %rsi
leaq -0x1a8(%rbp), %rdi
callq 0x33460
jmp 0x218e3
movb $0x1, -0x1a9(%rbp)
leaq 0x4dd75(%rip), %rdi     # 0x6f666
leaq -0x1a8(%rbp), %rsi
callq 0xd590
movb %al, -0x245(%rbp)
jmp 0x21905
movb -0x245(%rbp), %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x246(%rbp)
jne 0x2191a
jmp 0x21944
leaq -0x90(%rbp), %rdi
callq 0x32c70
movq %rax, %rdi
callq 0x32570
movb %al, -0x247(%rbp)
jmp 0x21936
movb -0x247(%rbp), %al
movb %al, -0x246(%rbp)
jmp 0x21944
movb -0x246(%rbp), %al
movb %al, -0x243(%rbp)
movb -0x243(%rbp), %al
movb %al, -0x248(%rbp)
testb $0x1, -0x1a9(%rbp)
jne 0x21967
jmp 0x21973
leaq -0x1a8(%rbp), %rdi
callq 0x8848
testb $0x1, -0x181(%rbp)
jne 0x2197e
jmp 0x2198a
leaq -0x180(%rbp), %rdi
callq 0x8848
leaq -0x160(%rbp), %rdi
callq 0x8848
movb -0x248(%rbp), %al
testb $0x1, %al
jne 0x219a5
jmp 0x21a3c
movq -0x220(%rbp), %rax
movb $0x0, 0xc(%rax)
movl $0x1, -0x108(%rbp)
jmp 0x21e84
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
jmp 0x21a2b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
jmp 0x21a12
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
testb $0x1, -0x1a9(%rbp)
jne 0x21a04
jmp 0x21a10
leaq -0x1a8(%rbp), %rdi
callq 0x8848
jmp 0x21a12
testb $0x1, -0x181(%rbp)
jne 0x21a1d
jmp 0x21a29
leaq -0x180(%rbp), %rdi
callq 0x8848
jmp 0x21a2b
leaq -0x160(%rbp), %rdi
callq 0x8848
jmp 0x21ef1
leaq -0x90(%rbp), %rdi
callq 0x32c70
movq %rax, %rsi
leaq -0x1d0(%rbp), %rdi
callq 0x33460
jmp 0x21a59
leaq 0x4dc24(%rip), %rdi     # 0x6f684
leaq -0x1d0(%rbp), %rsi
callq 0xd590
movb %al, -0x249(%rbp)
jmp 0x21a74
movb -0x249(%rbp), %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x24a(%rbp)
jne 0x21a89
jmp 0x21ab3
leaq -0x90(%rbp), %rdi
callq 0x32c70
movq %rax, %rdi
callq 0x32590
movb %al, -0x24b(%rbp)
jmp 0x21aa5
movb -0x24b(%rbp), %al
movb %al, -0x24a(%rbp)
jmp 0x21ab3
movb -0x24a(%rbp), %al
movb %al, -0x24c(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0x8848
movb -0x24c(%rbp), %al
testb $0x1, %al
jne 0x21ada
jmp 0x21d58
leaq -0x1e0(%rbp), %rdi
leaq -0x128(%rbp), %rsi
callq 0x33220
xorl %eax, %eax
movl %eax, %edi
leaq -0x1e0(%rbp), %rsi
callq 0x335b0
testb $0x1, %al
jne 0x21b03
jmp 0x21b40
movq -0x220(%rbp), %rax
movb $0x0, 0xc(%rax)
movl $0x1, -0x108(%rbp)
jmp 0x21d26
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0x8848
jmp 0x21ef1
leaq -0x1e0(%rbp), %rdi
callq 0xd830
movq %rax, %rdi
callq 0x335e0
movb %al, -0x24d(%rbp)
jmp 0x21b5c
movb -0x24d(%rbp), %al
testb $0x1, %al
jne 0x21b99
jmp 0x21b68
movq -0x220(%rbp), %rax
movb $0x0, 0xc(%rax)
movl $0x1, -0x108(%rbp)
jmp 0x21d26
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
jmp 0x21d47
leaq -0x1e0(%rbp), %rdi
callq 0xd830
movq %rax, %rdi
callq 0x33610
movw %ax, -0x250(%rbp)
jmp 0x21bb6
movw -0x250(%rbp), %ax
movzwl %ax, %eax
movl %eax, -0x258(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x33640
movq %rax, %rdi
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
movw %ax, -0x252(%rbp)
jmp 0x21be6
movl -0x258(%rbp), %eax
movw -0x252(%rbp), %cx
movzwl %cx, %ecx
cmpl %ecx, %eax
jg 0x21cba
leaq -0x201(%rbp), %rdi
movq %rdi, -0x260(%rbp)
callq 0x8760
movq -0x260(%rbp), %rdx
leaq 0x4ddf9(%rip), %rsi     # 0x6fa18
leaq -0x200(%rbp), %rdi
callq 0xced0
jmp 0x21c2d
movq -0x220(%rbp), %rax
movl 0x8(%rax), %esi
leaq -0x200(%rbp), %rdi
callq 0x6d9e0
jmp 0x21c45
leaq -0x200(%rbp), %rdi
callq 0x8848
leaq -0x201(%rbp), %rdi
callq 0x8460
movq -0x220(%rbp), %rax
movb $0x0, 0xc(%rax)
movl $0x1, -0x108(%rbp)
jmp 0x21d26
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
jmp 0x21ca9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
leaq -0x200(%rbp), %rdi
callq 0x8848
leaq -0x201(%rbp), %rdi
callq 0x8460
jmp 0x21d47
jmp 0x21cbc
leaq -0x1e0(%rbp), %rdi
callq 0xd830
movq %rax, -0x270(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x33640
movq %rax, %rdi
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
movw %ax, -0x262(%rbp)
jmp 0x21cef
movq -0x270(%rbp), %rdi
movw -0x262(%rbp), %ax
movzwl %ax, %esi
callq 0x33660
movw %ax, -0x272(%rbp)
jmp 0x21d0e
movw -0x272(%rbp), %ax
movw %ax, -0x13a(%rbp)
movl $0x0, -0x108(%rbp)
leaq -0x1e0(%rbp), %rdi
callq 0x9880
movl -0x108(%rbp), %eax
testl %eax, %eax
jne 0x21e84
jmp 0x21d42
jmp 0x21e1d
leaq -0x1e0(%rbp), %rdi
callq 0x9880
jmp 0x21ef1
leaq -0x90(%rbp), %rdi
callq 0x32c70
movq %rax, -0x280(%rbp)
leaq -0x128(%rbp), %rdi
callq 0x33690
testb $0x1, %al
jne 0x21d7d
jmp 0x21daf
leaq -0x128(%rbp), %rdi
callq 0x33640
movq %rax, %rdi
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
movw %ax, -0x282(%rbp)
jmp 0x21d9d
movw -0x282(%rbp), %ax
movzwl %ax, %eax
movl %eax, -0x288(%rbp)
jmp 0x21db9
xorl %eax, %eax
movl %eax, -0x288(%rbp)
jmp 0x21db9
movl -0x288(%rbp), %eax
movw %ax, -0x28c(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x33640
movq %rax, %rdi
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
movw %ax, -0x28a(%rbp)
jmp 0x21de6
movq -0x280(%rbp), %rdi
movw -0x28a(%rbp), %ax
movw -0x28c(%rbp), %cx
movzwl %cx, %esi
movzwl %ax, %edx
callq 0x188d0
movw %ax, -0x28e(%rbp)
jmp 0x21e0f
movw -0x28e(%rbp), %ax
movw %ax, -0x13a(%rbp)
jmp 0x21e1f
movl $0x10, %edi
callq 0x83e0
movq %rax, -0x298(%rbp)
jmp 0x21e32
movq -0x298(%rbp), %rdi
movzwl -0x13a(%rbp), %esi
callq 0x32780
jmp 0x21e47
movq -0x298(%rbp), %rsi
leaq -0x218(%rbp), %rdi
callq 0x327c0
jmp 0x21e5c
leaq -0x58(%rbp), %rdi
leaq -0x218(%rbp), %rsi
callq 0x32970
jmp 0x21e6e
leaq -0x218(%rbp), %rdi
callq 0x327f0
movl $0x0, -0x108(%rbp)
leaq -0x128(%rbp), %rdi
callq 0x327f0
leaq -0x118(%rbp), %rdi
callq 0x327f0
movl -0x108(%rbp), %eax
testl %eax, %eax
jne 0x21f30
jmp 0x21eac
jmp 0x21f22
movq -0x298(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
movl $0x10, %esi
callq 0x83f0
jmp 0x21ef1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
leaq -0x218(%rbp), %rdi
callq 0x327f0
leaq -0x128(%rbp), %rdi
callq 0x327f0
leaq -0x118(%rbp), %rdi
callq 0x327f0
jmp 0x21f77
movq -0x220(%rbp), %rax
movb $0x0, 0xc(%rax)
movl $0x1, -0x108(%rbp)
jmp 0x21f30
jmp 0x21f24
jmp 0x21f26
movl $0x0, -0x108(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x32b50
movl -0x108(%rbp), %eax
testl %eax, %eax
jne 0x21f52
jmp 0x21f48
movl $0x0, -0x108(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x327f0
movl -0x108(%rbp), %eax
testl %eax, %eax
jne 0x21fdc
jmp 0x21f67
jmp 0x21f69
leaq -0x68(%rbp), %rdi
callq 0x334c0
jmp 0x214ec
leaq -0x90(%rbp), %rdi
callq 0x32b50
leaq -0x80(%rbp), %rdi
callq 0x327f0
jmp 0x22000
leaq -0x58(%rbp), %rdi
callq 0x32b10
movq %rax, -0x2a0(%rbp)
jmp 0x21fa0
movq -0x2a0(%rbp), %rdi
callq 0x33640
movq %rax, %rdi
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
movw %ax, -0x2a2(%rbp)
jmp 0x21fc0
movq -0x220(%rbp), %rax
movw -0x2a2(%rbp), %cx
movw %cx, 0xe(%rax)
movl $0x0, -0x108(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x32fb0
addq $0x2b0, %rsp            # imm = 0x2B0
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x32fb0
movq -0xc0(%rbp), %rdi
callq 0x8750
nopw %cs:(%rax,%rax)