// File: melop[P]admixem/./parser/parser.cpp
// Function: Parser::Primary(bool)
const double Parser::Primary (const bool get)   // primary (base) tokens
  {
  
  if (get)
    GetToken ();    // one-token lookahead  
  
  switch (type_)
    {
    case NUMBER:  
      {
      double v = value_; 
      GetToken (true);  // get next one (one-token lookahead)
      return v;
      }
    
    case NAME:
      {
      std::string word = word_;
      GetToken (true); 
      if (type_ == LHPAREN)
        {
        // might be single-argument function (eg. abs (x) )
        std::map<std::string, OneArgFunction>::const_iterator si;
        si = OneArgumentFunctions.find (word);
        if (si != OneArgumentFunctions.end ())
          {
          double v = Expression (true);   // get argument
          CheckToken (RHPAREN);
          GetToken (true);        // get next one (one-token lookahead)
          return si->second (v);  // evaluate function
          }
        
        // might be double-argument function (eg. roll (6, 2) )
        std::map<std::string, TwoArgFunction>::const_iterator di;
        di = TwoArgumentFunctions.find (word);
        if (di != TwoArgumentFunctions.end ())
          {
          double v1 = Expression (true);   // get argument 1 (not commalist)
          CheckToken (COMMA);
          double v2 = Expression (true);   // get argument 2 (not commalist)
          CheckToken (RHPAREN);
          GetToken (true);            // get next one (one-token lookahead)
          return di->second (v1, v2); // evaluate function
          }
  
       // might be double-argument function (eg. roll (6, 2) )
        std::map<std::string, ThreeArgFunction>::const_iterator ti;
        ti = ThreeArgumentFunctions.find (word);
        if (ti != ThreeArgumentFunctions.end ())
          {
          double v1 = Expression (true);   // get argument 1 (not commalist)
          CheckToken (COMMA);
          double v2 = Expression (true);   // get argument 2 (not commalist)
          CheckToken (COMMA);
          double v3 = Expression (true);   // get argument 3 (not commalist)
          CheckToken (RHPAREN);
          GetToken (true);  // get next one (one-token lookahead)
          return ti->second (v1, v2, v3); // evaluate function
          }
        
        throw std::runtime_error ("Function '" + word + "' not implemented.");
        }
		
		

      
      // not a function? must be a symbol in the symbol table
      double & v = symbols_ [word];  // get REFERENCE to symbol table entry
      // change table entry with expression? (eg. a = 22, or a = 22)
	  
	  
      switch (type_)
        {
        // maybe check for NaN or Inf here (see: isinf, isnan functions)
        case ASSIGN:     v  = Expression (true); break;   
        case ASSIGN_ADD: v += Expression (true); break;   
        case ASSIGN_SUB: v -= Expression (true); break;   
        case ASSIGN_MUL: v *= Expression (true); break;   
        case ASSIGN_DIV: 
            {
            double d = Expression (true); 
            if (d == 0.0)
              throw std::runtime_error ("Divide by zero");
            v /= d;
            break;   // change table entry with expression
            } // end of ASSIGN_DIV
        default: break;   // do nothing for others
        } // end of switch on type_              
      return v;               // and return new value
      }
    
    case MINUS:               // unary minus
      return - Primary (true);
    
    case NOT:   // unary not
      return (Primary (true) == 0.0) ? 1.0 : 0.0;;
    
    case LHPAREN:
      {
      double v = CommaList (true);    // inside parens, you could have commas
      CheckToken (RHPAREN);
      GetToken (true);                // eat the )
      return v;
      }
    
    default:   
      throw std::runtime_error ("Unexpected token: " + word_);
    
    } // end of switch on type
  
  }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x250, %rsp            # imm = 0x250
movb %sil, %al
movq %rdi, -0x10(%rbp)
andb $0x1, %al
movb %al, -0x11(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x190(%rbp)
testb $0x1, -0x11(%rbp)
je 0xb2d6
movq -0x190(%rbp), %rdi
xorl %esi, %esi
callq 0x9390
movq -0x190(%rbp), %rax
movl 0x30(%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x198(%rbp)
subl $0x2c, %eax
ja 0xbb66
movq -0x198(%rbp), %rax
leaq 0x6aefe(%rip), %rcx     # 0x76200
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x190(%rbp), %rdi
movsd 0x58(%rdi), %xmm0
movsd %xmm0, -0x20(%rbp)
movl $0x1, %esi
callq 0x9390
movsd -0x20(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0xbc15
movq -0x190(%rbp), %rsi
addq $0x38, %rsi
leaq -0x40(%rbp), %rdi
callq 0x81f0
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0x9390
jmp 0xb35c
movq -0x190(%rbp), %rax
cmpl $0x28, 0x30(%rax)
jne 0xb87f
leaq -0x58(%rbp), %rdi
callq 0xc5c0
leaq 0x9f193(%rip), %rdi     # 0xaa510
leaq -0x40(%rbp), %rsi
callq 0xc5e0
movq %rax, -0x1a0(%rbp)
jmp 0xb38f
movq -0x1a0(%rbp), %rax
movq %rax, -0x68(%rbp)
leaq -0x60(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0xc610
movq -0x60(%rbp), %rax
movq %rax, -0x58(%rbp)
leaq 0x9f15a(%rip), %rdi     # 0xaa510
callq 0xc660
movq %rax, -0x78(%rbp)
leaq -0x70(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0xc610
leaq -0x58(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0xc630
testb $0x1, %al
jne 0xb3e2
jmp 0xb47b
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0xbc30
movsd %xmm0, -0x1a8(%rbp)
jmp 0xb3fd
movq -0x190(%rbp), %rdi
movsd -0x1a8(%rbp), %xmm0
movsd %xmm0, -0x80(%rbp)
movl $0x29, %esi
callq 0xc690
jmp 0xb41d
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0x9390
jmp 0xb430
leaq -0x58(%rbp), %rdi
callq 0xc800
movq 0x20(%rax), %rax
movsd -0x80(%rbp), %xmm0
callq *%rax
movsd %xmm0, -0x1b0(%rbp)
jmp 0xb44e
movsd -0x1b0(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
movl $0x1, -0x84(%rbp)
jmp 0xba91
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xba9f
leaq -0x90(%rbp), %rdi
callq 0xc820
leaq 0x9f0b2(%rip), %rdi     # 0xaa540
leaq -0x40(%rbp), %rsi
callq 0xc840
movq %rax, -0x1b8(%rbp)
jmp 0xb4a0
movq -0x1b8(%rbp), %rax
movq %rax, -0xa0(%rbp)
leaq -0x98(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0xc870
movq -0x98(%rbp), %rax
movq %rax, -0x90(%rbp)
leaq 0x9f06a(%rip), %rdi     # 0xaa540
callq 0xc8c0
movq %rax, -0xb0(%rbp)
leaq -0xa8(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0xc870
leaq -0x90(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0xc890
testb $0x1, %al
jne 0xb511
jmp 0xb5e8
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0xbc30
movsd %xmm0, -0x1c0(%rbp)
jmp 0xb52c
movq -0x190(%rbp), %rdi
movsd -0x1c0(%rbp), %xmm0
movsd %xmm0, -0xb8(%rbp)
movl $0x2c, %esi
callq 0xc690
jmp 0xb54f
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0xbc30
movsd %xmm0, -0x1c8(%rbp)
jmp 0xb56a
movq -0x190(%rbp), %rdi
movsd -0x1c8(%rbp), %xmm0
movsd %xmm0, -0xc0(%rbp)
movl $0x29, %esi
callq 0xc690
jmp 0xb58d
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0x9390
jmp 0xb5a0
leaq -0x90(%rbp), %rdi
callq 0xc8f0
movq 0x20(%rax), %rax
movsd -0xb8(%rbp), %xmm0
movsd -0xc0(%rbp), %xmm1
callq *%rax
movsd %xmm0, -0x1d0(%rbp)
jmp 0xb5cc
movsd -0x1d0(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
movl $0x1, -0x84(%rbp)
jmp 0xba91
leaq -0xc8(%rbp), %rdi
callq 0xc910
leaq 0x9ef75(%rip), %rdi     # 0xaa570
leaq -0x40(%rbp), %rsi
callq 0xc930
movq %rax, -0x1d8(%rbp)
jmp 0xb60d
movq -0x1d8(%rbp), %rax
movq %rax, -0xd8(%rbp)
leaq -0xd0(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0xc960
movq -0xd0(%rbp), %rax
movq %rax, -0xc8(%rbp)
leaq 0x9ef2d(%rip), %rdi     # 0xaa570
callq 0xc9b0
movq %rax, -0xe8(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0xc960
leaq -0xc8(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0xc980
testb $0x1, %al
jne 0xb67e
jmp 0xb79b
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0xbc30
movsd %xmm0, -0x1e0(%rbp)
jmp 0xb699
movq -0x190(%rbp), %rdi
movsd -0x1e0(%rbp), %xmm0
movsd %xmm0, -0xf0(%rbp)
movl $0x2c, %esi
callq 0xc690
jmp 0xb6bc
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0xbc30
movsd %xmm0, -0x1e8(%rbp)
jmp 0xb6d7
movq -0x190(%rbp), %rdi
movsd -0x1e8(%rbp), %xmm0
movsd %xmm0, -0xf8(%rbp)
movl $0x2c, %esi
callq 0xc690
jmp 0xb6fa
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0xbc30
movsd %xmm0, -0x1f0(%rbp)
jmp 0xb715
movq -0x190(%rbp), %rdi
movsd -0x1f0(%rbp), %xmm0
movsd %xmm0, -0x100(%rbp)
movl $0x29, %esi
callq 0xc690
jmp 0xb738
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0x9390
jmp 0xb74b
leaq -0xc8(%rbp), %rdi
callq 0xc9e0
movq 0x20(%rax), %rax
movsd -0xf0(%rbp), %xmm0
movsd -0xf8(%rbp), %xmm1
movsd -0x100(%rbp), %xmm2
callq *%rax
movsd %xmm0, -0x1f8(%rbp)
jmp 0xb77f
movsd -0x1f8(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
movl $0x1, -0x84(%rbp)
jmp 0xba91
movb $0x1, -0x141(%rbp)
movl $0x10, %edi
callq 0x8230
movq %rax, -0x200(%rbp)
leaq 0x6abda(%rip), %rsi     # 0x76394
leaq -0x140(%rbp), %rdi
leaq -0x40(%rbp), %rdx
callq 0xc3f0
jmp 0xb7cc
leaq 0x6abcc(%rip), %rdx     # 0x7639f
leaq -0x120(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0xca00
jmp 0xb7e8
movq -0x200(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x87a0
jmp 0xb7fd
movq -0x200(%rbp), %rdi
movb $0x0, -0x141(%rbp)
movq 0x9e7de(%rip), %rsi     # 0xa9ff0
movq 0x9e767(%rip), %rdx     # 0xa9f80
callq 0x8820
jmp 0xbc2c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xb863
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xb857
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x120(%rbp), %rdi
callq 0x82e0
leaq -0x140(%rbp), %rdi
callq 0x82e0
testb $0x1, -0x141(%rbp)
jne 0xb86e
jmp 0xb87a
movq -0x200(%rbp), %rdi
callq 0x8370
jmp 0xba9f
movq -0x190(%rbp), %rdi
addq $0x68, %rdi
leaq -0x40(%rbp), %rsi
callq 0xca50
movq %rax, -0x208(%rbp)
jmp 0xb89c
movq -0x190(%rbp), %rax
movq -0x208(%rbp), %rcx
movq %rcx, -0x150(%rbp)
movl 0x30(%rax), %eax
addl $-0x3d, %eax
movl %eax, %ecx
movq %rcx, -0x210(%rbp)
subl $0xb, %eax
ja 0xba75
movq -0x210(%rbp), %rax
leaq 0x6a9dd(%rip), %rcx     # 0x762b4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0xbc30
movsd %xmm0, -0x218(%rbp)
jmp 0xb8fb
movsd -0x218(%rbp), %xmm0
movq -0x150(%rbp), %rax
movsd %xmm0, (%rax)
jmp 0xba77
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0xbc30
movsd %xmm0, -0x220(%rbp)
jmp 0xb92e
movsd -0x220(%rbp), %xmm0
movq -0x150(%rbp), %rax
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
jmp 0xba77
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0xbc30
movsd %xmm0, -0x228(%rbp)
jmp 0xb965
movsd -0x228(%rbp), %xmm1
movq -0x150(%rbp), %rax
movsd (%rax), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, (%rax)
jmp 0xba77
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0xbc30
movsd %xmm0, -0x230(%rbp)
jmp 0xb9a0
movsd -0x230(%rbp), %xmm0
movq -0x150(%rbp), %rax
mulsd (%rax), %xmm0
movsd %xmm0, (%rax)
jmp 0xba77
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0xbc30
movsd %xmm0, -0x238(%rbp)
jmp 0xb9d7
movsd -0x238(%rbp), %xmm0
movsd %xmm0, -0x158(%rbp)
movsd -0x158(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0xba58
jp 0xba58
movl $0x10, %edi
callq 0x8230
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x240(%rbp)
leaq 0x6a99a(%rip), %rsi     # 0x763b2
callq 0x81b0
jmp 0xba1f
movq -0x240(%rbp), %rdi
movq 0x9e5c3(%rip), %rsi     # 0xa9ff0
movq 0x9e54c(%rip), %rdx     # 0xa9f80
callq 0x8820
jmp 0xbc2c
movq -0x240(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
callq 0x8370
jmp 0xba9f
movsd -0x158(%rbp), %xmm1
movq -0x150(%rbp), %rax
movsd (%rax), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, (%rax)
jmp 0xba77
jmp 0xba77
movq -0x150(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x8(%rbp)
movl $0x1, -0x84(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x82e0
jmp 0xbc15
leaq -0x40(%rbp), %rdi
callq 0x82e0
jmp 0xbc23
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0xb2a0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0xbc15
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0xb2a0
movsd 0x6a518(%rip), %xmm3    # 0x76010
xorps %xmm2, %xmm2
cmpeqsd %xmm2, %xmm0
movaps %xmm0, %xmm1
andpd %xmm3, %xmm1
andnpd %xmm2, %xmm0
orpd %xmm1, %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0xbc15
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0xbd40
movq -0x190(%rbp), %rdi
movsd %xmm0, -0x160(%rbp)
movl $0x29, %esi
callq 0xc690
movq -0x190(%rbp), %rdi
movl $0x1, %esi
callq 0x9390
movsd -0x160(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0xbc15
movb $0x1, -0x181(%rbp)
movl $0x10, %edi
callq 0x8230
movq -0x190(%rbp), %rdx
movq %rax, -0x248(%rbp)
addq $0x38, %rdx
leaq 0x6a831(%rip), %rsi     # 0x763c1
leaq -0x180(%rbp), %rdi
callq 0xc3f0
jmp 0xbb9e
movq -0x248(%rbp), %rdi
leaq -0x180(%rbp), %rsi
callq 0x87a0
jmp 0xbbb3
movq -0x248(%rbp), %rdi
movb $0x0, -0x181(%rbp)
movq 0x9e428(%rip), %rsi     # 0xa9ff0
movq 0x9e3b1(%rip), %rdx     # 0xa9f80
callq 0x8820
jmp 0xbc2c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xbbfc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x180(%rbp), %rdi
callq 0x82e0
testb $0x1, -0x181(%rbp)
jne 0xbc07
jmp 0xbc13
movq -0x248(%rbp), %rdi
callq 0x8370
jmp 0xbc23
movsd -0x8(%rbp), %xmm0
addq $0x250, %rsp            # imm = 0x250
popq %rbp
retq
movq -0x48(%rbp), %rdi
callq 0x8860
nopl (%rax)