// File: navrajsaini[P]PL_Compiler_design_project/interp.cpp
// Function: Interpreter::run_program()
void Interpreter::run_program()
{
  OperationCode  opcode;
  program_register = 0; 
  running = true;
  
  while (running)
  {
//
    opcode = (OperationCode) store[program_register];
//
 //   cout << "Opcode = " << opcode << endl;
    if ( stepping )
    {
      cout << endl << " press < enter > to execute "
                   << opcode_name[opcode] << " operation" << endl;
      cin.get();
    }
    switch (opcode)
    {
      case OP_ADD:
         add();
         break;
      case OP_AND:
         pland();
         break;
      case OP_ARROW:
         arrow(store[program_register + 1]);
         break;
      case OP_ASSIGN:
         assign( store[program_register + 1]);
         break;
      case OP_BAR:
         bar(store[program_register + 1]);
         break;
      case OP_CALL:
         call(store[program_register + 1], store[program_register + 2]);
         break;
      case OP_CONSTANT:
         constant(store[program_register + 1]);
         break;
      case OP_DIVIDE:
         divide();
         break;
      case OP_ENDPROC:
         endproc();
         break;
      case OP_ENDPROG:
         endprog();
         break;
      case OP_EQUAL:
         equal();
         break;
      case OP_FI:
         fi( store[program_register + 1]);
         break;
      case OP_GREATER:
         greater();
         break;
      case OP_INDEX:
         index( store[program_register + 1], store[program_register + 2]);
         break;
      case OP_LESS:
         less();
         break;
      case OP_MINUS:
         minus();
         break;
      case OP_MODULO:
         modulo();
         break;
      case OP_MULTIPLY:
         multiply();
         break;
      case OP_NOT:
         plnot();
         break;
      case OP_OR:
         plor();
         break;
      case OP_PROC:
         proc(store[program_register + 1], store[program_register + 2]);
         break;
      case OP_PROG:
         prog(store[program_register + 1], store[program_register + 2]);
         break;
      case OP_READ:
         read(store[program_register + 1]);
         break;
      case OP_SUBTRACT:
         subtract();
         break;
      case OP_VALUE:
         value();
         break;
      case OP_VARIABLE:
         variable(store[program_register + 1], store[program_register + 2]);
         break;
      case OP_WRITE:
         write(store[program_register + 1]);
         break;
      default:
         runtime_error(" FATAL! Damaged Program File!");
         break;
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x50(%rbp)
movl $0x0, 0xfb0(%rax)
movb $0x1, 0xfb4(%rax)
movq -0x50(%rbp), %rax
testb $0x1, 0xfb4(%rax)
je 0x1d8ed
movq -0x50(%rbp), %rax
movslq 0xfb0(%rax), %rcx
movl (%rax,%rcx,4), %ecx
movl %ecx, -0xc(%rbp)
testb $0x1, 0xfb5(%rax)
je 0x1d5e5
movq 0x9a41(%rip), %rdi      # 0x26fc8
movq 0x9a2a(%rip), %rsi      # 0x26fb8
callq 0x21d0
movq %rax, %rdi
leaq 0x2665(%rip), %rsi      # 0x1fc02
callq 0x21b0
movq %rax, %rdi
movl -0xc(%rbp), %eax
leaq 0xa6e1(%rip), %rsi      # 0x27c90
shlq $0x5, %rax
addq %rax, %rsi
callq 0x2190
movq %rax, %rdi
leaq 0x265a(%rip), %rsi      # 0x1fc1f
callq 0x21b0
movq %rax, %rdi
movq 0x99e4(%rip), %rsi      # 0x26fb8
callq 0x21d0
movq 0x99f8(%rip), %rdi      # 0x26fd8
callq 0x2220
movl -0xc(%rbp), %eax
movq %rax, -0x58(%rbp)
subq $0x1a, %rax
ja 0x1d86f
movq -0x58(%rbp), %rax
leaq 0x24df(%rip), %rcx      # 0x1fae0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x50(%rbp), %rdi
callq 0x1ddf0
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
callq 0x1dfb0
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
movl 0xfb0(%rdi), %eax
addl $0x1, %eax
cltq
movl (%rdi,%rax,4), %esi
callq 0x1e2e0
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
movl 0xfb0(%rdi), %eax
addl $0x1, %eax
cltq
movl (%rdi,%rax,4), %esi
callq 0x1e1b0
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
movl 0xfb0(%rdi), %eax
addl $0x1, %eax
cltq
movl (%rdi,%rax,4), %esi
callq 0x1e340
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
movl 0xfb0(%rdi), %eax
addl $0x1, %eax
cltq
movl (%rdi,%rax,4), %esi
movl 0xfb0(%rdi), %eax
addl $0x2, %eax
cltq
movl (%rdi,%rax,4), %edx
callq 0x1e230
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
movl 0xfb0(%rdi), %eax
addl $0x1, %eax
cltq
movl (%rdi,%rax,4), %esi
callq 0x1dbe0
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
callq 0x1dd00
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
callq 0x1e440
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
callq 0x1e4e0
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
callq 0x1def0
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
movl 0xfb0(%rdi), %eax
addl $0x1, %eax
cltq
movl (%rdi,%rax,4), %esi
callq 0x1e360
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
callq 0x1df50
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
movl 0xfb0(%rdi), %eax
addl $0x1, %eax
cltq
movl (%rdi,%rax,4), %esi
movl 0xfb0(%rdi), %eax
addl $0x2, %eax
cltq
movl (%rdi,%rax,4), %edx
callq 0x1dae0
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
callq 0x1de90
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
callq 0x1ddc0
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
callq 0x1dd60
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
callq 0x1dcb0
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
callq 0x1dc70
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
callq 0x1e010
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
movl 0xfb0(%rdi), %eax
addl $0x1, %eax
cltq
movl (%rdi,%rax,4), %esi
movl 0xfb0(%rdi), %eax
addl $0x2, %eax
cltq
movl (%rdi,%rax,4), %edx
callq 0x1e400
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
movl 0xfb0(%rdi), %eax
addl $0x1, %eax
cltq
movl (%rdi,%rax,4), %esi
movl 0xfb0(%rdi), %eax
addl $0x2, %eax
cltq
movl (%rdi,%rax,4), %edx
callq 0x1e490
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
movl 0xfb0(%rdi), %eax
addl $0x1, %eax
cltq
movl (%rdi,%rax,4), %esi
callq 0x1e070
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
callq 0x1de40
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
callq 0x1dc30
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
movl 0xfb0(%rdi), %eax
addl $0x1, %eax
cltq
movl (%rdi,%rax,4), %esi
movl 0xfb0(%rdi), %eax
addl $0x2, %eax
cltq
movl (%rdi,%rax,4), %edx
callq 0x1da60
jmp 0x1d8e8
movq -0x50(%rbp), %rdi
movl 0xfb0(%rdi), %eax
addl $0x1, %eax
cltq
movl (%rdi,%rax,4), %esi
callq 0x1e110
jmp 0x1d8e8
leaq -0x31(%rbp), %rdi
movq %rdi, -0x60(%rbp)
callq 0x2350
movq -0x60(%rbp), %rdx
leaq 0x23a3(%rip), %rsi      # 0x1fc2a
leaq -0x30(%rbp), %rdi
callq 0x2290
jmp 0x1d892
movq -0x50(%rbp), %rdi
leaq -0x30(%rbp), %rsi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x1d900
jmp 0x1d8a6
leaq -0x30(%rbp), %rdi
callq 0x2130
leaq -0x31(%rbp), %rdi
callq 0x21e0
jmp 0x1d8e8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x1d8dd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x2130
leaq -0x31(%rbp), %rdi
callq 0x21e0
jmp 0x1d8f3
jmp 0x1d555
addq $0x60, %rsp
popq %rbp
retq
movq -0x40(%rbp), %rdi
callq 0x2340
nopl (%rax)