// File: /workspace/github_c_makefile_star2_O2/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, %r14
leaq 0x23ab0(%rip), %rax     # 0x2c6cc
testb $0x20, (%rax)
jne 0x8e84
pushq $0x7
popq %rdx
pushq $-0x1
popq %r15
movq $0x0, 0x10(%rsp)
leaq 0x20e94(%rip), %rbp     # 0x29ad0
movl %r15d, %ebx
movl %r15d, 0x4(%rsp)
movl %edx, %r13d
movsbq (%r14), %r12
testq %r12, %r12
je 0x8c68
callq 0x5330
movq (%rax), %rax
movzwl (%rax,%r12,2), %ecx
btl $0xd, %ecx
jae 0x8c74
incq %r14
jmp 0x8c47
xorl %esi, %esi
pushq $0x6
popq %rax
movl %eax, %edx
jmp 0x8d1f
movl %r13d, 0x8(%rsp)
btl $0xa, %ecx
jb 0x8cb2
leaq 0x20eb4(%rip), %rbp     # 0x29b3a
movq -0xa(%rbp), %r13
testq %r13, %r13
je 0x8d04
movq %r13, %rdi
callq 0x5100
movq %rax, %r12
movq %r14, %rdi
movq %r13, %rsi
movq %rax, %rdx
callq 0x5090
testl %eax, %eax
je 0x8d08
addq $0x10, %rbp
jmp 0x8c86
xorl %r13d, %r13d
testb %r12b, %r12b
je 0x8ce2
cmpb $0x5f, %r12b
je 0x8cd0
movsbq %r12b, %rcx
movzwl (%rax,%rcx,2), %ecx
andl $0xc00, %ecx            # imm = 0xC00
je 0x8ce2
movb %r12b, 0x80(%rsp,%r13)
movb 0x1(%r14,%r13), %r12b
incq %r13
jmp 0x8cb5
movb $0x0, 0x80(%rsp,%r13)
leaq 0x80(%rsp), %rdi
callq 0xb7a5
movl %eax, %esi
addq %r13, %r14
pushq $0x1
popq %rax
movl %eax, %edx
jmp 0x8d1a
pushq $0x1
popq %r12
movswl -0x2(%rbp), %edx
movswl (%rbp), %esi
addq %r12, %r14
leaq 0x20db6(%rip), %rbp     # 0x29ad0
movl 0x8(%rsp), %r13d
movslq %edx, %rax
leaq 0x20de7(%rip), %rcx     # 0x29b10
movl (%rcx,%rax,4), %eax
btl %r13d, %eax
jae 0x8e6e
leal -0x1(%rdx), %eax
cmpl $0x5, %eax
ja 0x8e6e
leaq 0x145d7(%rip), %rcx     # 0x1d320
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rdx, 0x8(%rsp)
movl %esi, 0x18(%rsp)
movslq %esi, %rax
shlq $0x4, %rax
movswl (%rax,%rbp), %eax
movq 0x10(%rsp), %rcx
leal (%rax,%rcx,8), %r12d
xorl %eax, %eax
jmp 0x8dc6
movq 0x10(%rsp), %rax
testl %eax, %eax
jle 0x8e6e
decl %eax
jmp 0x8da3
xorl %eax, %eax
cmpl $-0x1, %esi
setne %al
movslq %r15d, %rcx
incl %r15d
movw %ax, 0x22(%rsp,%rcx,2)
jmp 0x8e3d
movq 0x10(%rsp), %rax
incl %eax
movq %rax, 0x10(%rsp)
jmp 0x8e3d
movl %esi, 0x18(%rsp)
movq %rdx, 0x8(%rsp)
movb $0x1, %al
pushq $-0x1
popq %r12
cmpl $0x7, %r13d
je 0x8ea4
movl %eax, 0x1c(%rsp)
testl %ebx, %ebx
js 0x8e1d
movl %ebx, %eax
movswl 0x50(%rsp,%rax,2), %eax
movl %eax, %ecx
sarl $0x4, %ecx
cmpl %r12d, %ecx
jl 0x8e1d
andl $0xf, %eax
shll $0x4, %eax
xorl %ecx, %ecx
cmpw $0x4, 0x2(%rax,%rbp)
setne %cl
movq %rbp, %r13
movl %r15d, %ebp
subl %ecx, %ebp
jl 0x8e6e
addq %r13, %rax
movl %r15d, %ecx
leaq (%rsp,%rcx,2), %rdi
addq $0x20, %rdi
callq *0x8(%rax)
movslq %ebp, %rcx
movw %ax, 0x20(%rsp,%rcx,2)
decl %ebx
movl %ebp, %r15d
movq %r13, %rbp
jmp 0x8dca
cmpb $0x0, 0x1c(%rsp)
jne 0x8e38
shll $0x4, %r12d
orl 0x18(%rsp), %r12d
incl %ebx
movslq %ebx, %rax
movw %r12w, 0x50(%rsp,%rax,2)
movq 0x8(%rsp), %rdx
cmpl $0x6, %edx
jne 0x8c44
leaq 0x2387f(%rip), %rax     # 0x2c6cc
testb $0x20, (%rax)
movzwl 0x20(%rsp), %eax
jne 0x8eae
movq 0x10(%rsp), %rcx
orl %r15d, %ecx
notl %ebx
cwtl
orl %ecx, %ebx
pushq $-0x1
popq %rcx
cmovel %eax, %ecx
movl %ecx, 0x4(%rsp)
movl 0x4(%rsp), %eax
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x1f16d(%rip), %rax     # 0x27ff8
movq (%rax), %rdi
leaq 0x144ad(%rip), %rsi     # 0x1d342
movq %r14, %rdx
xorl %eax, %eax
callq 0x5200
jmp 0x8c25
movl $0x0, 0x4(%rsp)
jmp 0x8e6e
movq 0x1f143(%rip), %rcx     # 0x27ff8
movq (%rcx), %rdi
testw %ax, %ax
leaq 0x144b2(%rip), %rax     # 0x1d374
leaq 0x144a6(%rip), %rdx     # 0x1d36f
cmoveq %rax, %rdx
leaq 0x1448a(%rip), %rsi     # 0x1d35e
xorl %eax, %eax
callq 0x5200
movzwl 0x20(%rsp), %eax
jmp 0x8e57
nopl (%rax)