// File: /workspace/github_c_makefile_star2_O3/mmayer[P]pcal/src/exprpars.c
// Function: parse_expr
int parse_expr (char *pbuf)
{
   OPERAND opd_stack[MAX_OP];   /* operand stack - TRUE/FALSE values */
   OPERATOR opr_stack[MAX_OP];   /* operator stack - precedence | op */
   int value, token, plevel, prec, result, npop, opr, opd, prev_token, op;
   
   plevel = 0;   /* paren nesting level */
   opd = opr = -1;   /* indices of stack tops */
   prev_token = TK_STARTINPUT;   /* to detect null expressions */
   
   if (DEBUG(DEBUG_PP)) fprintf(stderr, "evaluating expression '%s'\n", pbuf);
   do {
      pbuf = next_token(pbuf, &token, &value);
      
      /* check that the current token may follow the previous one */
      if (! IS_LEGAL(token, prev_token)) return EXPR_ERR;

      switch(token) {
         
      case TK_IDENT:   /* identifier => 1 if def, 0 if not */
         opd_stack[++opd] = value != PP_SYM_UNDEF;
         break;
         
      case TK_LPAREN:   /* left paren - bump nesting level */
         ++plevel;
         break;
         
      case TK_RPAREN:   /* right paren - decrement nesting */
         if (--plevel < 0) return EXPR_ERR;
         break;
         
      case TK_ENDINPUT:   /* end-of-input - treat as operator */
         if (prev_token == TK_STARTINPUT) return FALSE;   /* null expr => FALSE */
         /* fall through */

      case TK_UNARYOP:
      case TK_BINARYOP:

         /* get precedence of operator, adjusting for paren
          * nesting (TK_ENDINPUT has the lowest precedence
          * of all, to unwind operand/operator stacks at end)
          */
         prec = token == TK_ENDINPUT ? ENDINPUT_PREC : (plevel * PAREN_PREC) + opr_tbl[value].prec;
         
         /* pop (and perform) any equal- or higher-precedence
          * operators on operator stack: extract operator,
          * check for operand stack underflow, execute
          * operator, adjust operand stack height and place
          * result of operator on top
          */
         
         for ( ;
               opr >= 0 && PREC(opr_stack[opr]) >= prec;
               opr--) {
            op = OPCODE(opr_stack[opr]);
            npop = opr_tbl[op].type == TK_UNARYOP ? 0 : 1;
            if (opd < npop) return EXPR_ERR;
            result = (*opr_tbl[op].pfcn)(opd_stack + opd);
            opd_stack[opd -= npop] = result;
         }

         /* push operator (if any) onto stack */
         
         if (token != TK_ENDINPUT) opr_stack[++opr] = MAKE_OPR(prec, value);

         break;
         
      default:   /* should never get here */
         return EXPR_ERR;
         break;
      }
      
      prev_token = token;
      
   } while (token != TK_ENDINPUT);
   
   /* done - check for dangling parens, and leftover operand/operators */
   
   if (DEBUG(DEBUG_PP)) {
      fprintf(stderr, "evaluated to %s\n", opd_stack[0] ? "TRUE" : "FALSE");
   }

   return plevel != 0 || opd != 0 || opr != -1 ? 
      EXPR_ERR :   /* leftover junk - return error */
      opd_stack[0];   /* all OK - return final value */
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x148, %rsp            # imm = 0x148
movq %rdi, %rbx
leaq 0x23eb4(%rip), %rax     # 0x2d6dc
testb $0x20, (%rax)
jne 0x9b0c
movl $0x7, %ecx
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
xorl %r12d, %r12d
leaq 0x212da(%rip), %r13     # 0x2ab20
leaq 0x21293(%rip), %rdx     # 0x2aae0
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
movl %ecx, %esi
movb (%rbx), %r15b
movl $0x6, %ecx
testb %r15b, %r15b
je 0x98a0
movl %esi, 0x8(%rsp)
callq 0x5340
movq (%rax), %rax
movsbq %r15b, %rcx
movzwl (%rax,%rcx,2), %ecx
btl $0xd, %ecx
jae 0x98ad
movb 0x1(%rbx), %r15b
incq %rbx
testb %r15b, %r15b
jne 0x986d
movl $0x0, 0x4(%rsp)
leaq 0x2124a(%rip), %rdx     # 0x2aae0
movl $0x6, %ecx
jmp 0x9985
movl $0x0, 0x4(%rsp)
jmp 0x9989
btl $0xa, %ecx
jb 0x990a
movq 0x21286(%rip), %r15     # 0x2ab40
movl $0x1, %edx
testq %r15, %r15
je 0x9955
movq %r12, 0x10(%rsp)
leaq 0x2126c(%rip), %r13     # 0x2ab40
movq %r15, %rdi
callq 0x5100
movq %rax, %r12
movq %rbx, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x5090
testl %eax, %eax
je 0x995e
movq 0x10(%r13), %r15
addq $0x10, %r13
testq %r15, %r15
jne 0x98d4
movq 0x10(%rsp), %r12
movl $0x1, %edx
jmp 0x9966
leaq 0x80(%rsp), %rcx
cmpb $0x5f, %r15b
je 0x9928
movsbq %r15b, %rdx
movzwl (%rax,%rdx,2), %edx
andl $0xc00, %edx            # imm = 0xC00
je 0x993a
movb %r15b, (%rcx)
incq %rcx
movb 0x1(%rbx), %r15b
incq %rbx
testb %r15b, %r15b
jne 0x9912
movb $0x0, (%rcx)
leaq 0x80(%rsp), %rdi
callq 0xc685
movl %eax, 0x4(%rsp)
movl $0x1, %ecx
jmp 0x997e
leaq 0x211e4(%rip), %r13     # 0x2ab40
jmp 0x9966
movq %r12, %rdx
movq 0x10(%rsp), %r12
movswl 0x8(%r13), %ecx
movswl 0xa(%r13), %eax
movl %eax, 0x4(%rsp)
addq %rdx, %rbx
leaq 0x211a2(%rip), %r13     # 0x2ab20
leaq 0x2115b(%rip), %rdx     # 0x2aae0
movl 0x8(%rsp), %esi
movslq %ecx, %rax
movl (%r13,%rax,4), %eax
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
btl %esi, %eax
jae 0x9af7
leal -0x1(%rcx), %eax
cmpl $0x5, %eax
ja 0x9af7
movq %rcx, 0x8(%rsp)
leaq 0x159c0(%rip), %rcx     # 0x1f378
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movslq 0x4(%rsp), %rax
shlq $0x4, %rax
movswl (%rax,%rdx), %eax
movq %r12, 0x10(%rsp)
leal (%rax,%r12,8), %r12d
xorl %eax, %eax
jmp 0x9a22
testl %r12d, %r12d
jle 0x9af7
decl %r12d
jmp 0x9a02
xorl %eax, %eax
cmpl $-0x1, 0x4(%rsp)
setne %al
movslq %ebp, %rcx
incl %ebp
movw %ax, 0x22(%rsp,%rcx,2)
jmp 0x9a02
incl %r12d
movq 0x8(%rsp), %rcx
jmp 0x9ac9
cmpl $0x7, %esi
je 0x9b2c
movq %r12, 0x10(%rsp)
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
movb $0x1, %al
testl %r14d, %r14d
js 0x9a90
movl %eax, 0x1c(%rsp)
movl %r14d, %eax
movswl 0x50(%rsp,%rax,2), %eax
movl %eax, %ecx
sarl $0x4, %ecx
cmpl %r12d, %ecx
jl 0x9a95
andl $0xf, %eax
shll $0x4, %eax
xorl %ecx, %ecx
cmpw $0x4, 0x2(%rax,%rdx)
setne %cl
movl %ebp, %r13d
subl %ecx, %r13d
jl 0x9af7
addq %rdx, %rax
movl %ebp, %ecx
leaq (%rsp,%rcx,2), %rdi
addq $0x20, %rdi
callq *0x8(%rax)
leaq 0x2106f(%rip), %rdx     # 0x2aae0
movslq %r13d, %rcx
movw %ax, 0x20(%rsp,%rcx,2)
leal -0x1(%r14), %eax
movl %r13d, %ebp
testl %r14d, %r14d
movl %eax, %r14d
jg 0x9a2b
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
jmp 0x9a98
movl %ebp, %r13d
jmp 0x9a9c
movl %ebp, %r13d
movl 0x1c(%rsp), %eax
testb %al, %al
movq 0x8(%rsp), %rcx
jne 0x9aba
shll $0x4, %r12d
orl 0x4(%rsp), %r12d
movslq %r14d, %rax
incl %r14d
movw %r12w, 0x52(%rsp,%rax,2)
movl %r13d, %ebp
movq 0x10(%rsp), %r12
leaq 0x21057(%rip), %r13     # 0x2ab20
cmpl $0x6, %ecx
jne 0x9852
leaq 0x23c03(%rip), %rax     # 0x2d6dc
testb $0x20, (%rax)
movzwl 0x20(%rsp), %eax
jne 0x9b31
orl %ebp, %r12d
notl %r14d
cwtl
orl %r12d, %r14d
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
cmovel %eax, %r15d
movl %r15d, %eax
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x1f4dd(%rip), %rax     # 0x28ff0
movq (%rax), %rdi
leaq 0x1587d(%rip), %rsi     # 0x1f39a
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5210
jmp 0x9831
xorl %r15d, %r15d
jmp 0x9af7
movq 0x1f4b8(%rip), %rcx     # 0x28ff0
movq (%rcx), %rdi
testw %ax, %ax
leaq 0x15887(%rip), %rax     # 0x1f3cc
leaq 0x1587b(%rip), %rdx     # 0x1f3c7
cmoveq %rax, %rdx
leaq 0x1585f(%rip), %rsi     # 0x1f3b6
xorl %eax, %eax
callq 0x5210
movzwl 0x20(%rsp), %eax
jmp 0x9ae3