// File: /workspace/github_c_makefile_star2_O1/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 $0x138, %rsp            # imm = 0x138
movq %rdi, %rbx
leaq 0x2344c(%rip), %rax     # 0x2c6dc
testb $0x20, (%rax)
jne 0x955e
movl $0x7, %r15d
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
xorl %r14d, %r14d
leaq 0x20831(%rip), %rsi     # 0x29ae0
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
movq %r14, 0x8(%rsp)
movl %r15d, %r14d
movsbq (%rbx), %r13
movl $0x6, %r15d
testq %r13, %r13
je 0x92e4
callq 0x5340
movq (%rax), %rsi
movzwl (%rsi,%r13,2), %ecx
xorl %edi, %edi
btl $0xd, %ecx
jb 0x92eb
xorl %edx, %edx
jmp 0x930e
xorl %edi, %edi
jmp 0x93e7
incq %rbx
movsbq (%rbx), %rcx
testq %rcx, %rcx
sete %dl
je 0x9382
movzwl (%rsi,%rcx,2), %ecx
incq %rbx
btl $0xd, %ecx
jb 0x92ee
decq %rbx
testb %dl, %dl
leaq 0x207c9(%rip), %rsi     # 0x29ae0
jne 0x93e7
btl $0xa, %ecx
jb 0x9386
movq 0x20816(%rip), %r15     # 0x29b40
leaq 0x2080f(%rip), %r13     # 0x29b40
testq %r15, %r15
je 0x9364
leaq 0x20803(%rip), %r13     # 0x29b40
movq %r15, %rdi
callq 0x5100
movq %rbx, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x5090
testl %eax, %eax
je 0x9364
movq 0x10(%r13), %r15
addq $0x10, %r13
testq %r15, %r15
jne 0x933d
movswl 0x8(%r13), %r15d
movswl 0xa(%r13), %eax
movl %eax, 0x4(%rsp)
movq (%r13), %rdi
testq %rdi, %rdi
je 0x93d4
callq 0x5100
jmp 0x93d9
xorl %edi, %edi
jmp 0x93cb
movb (%rbx), %dl
leaq 0x70(%rsp), %rcx
testb %dl, %dl
je 0x93b6
cmpb $0x5f, %dl
je 0x93a9
movq (%rax), %rsi
movsbq %dl, %rdi
movzwl (%rsi,%rdi,2), %esi
andl $0xc00, %esi            # imm = 0xC00
je 0x93b6
movb %dl, (%rcx)
incq %rcx
movb 0x1(%rbx), %dl
incq %rbx
jmp 0x938d
movb $0x0, (%rcx)
leaq 0x70(%rsp), %rdi
callq 0xc1a1
movl %eax, %edi
movl $0x1, %r15d
leaq 0x2070e(%rip), %rsi     # 0x29ae0
jmp 0x93e7
movl $0x1, %eax
addq %rax, %rbx
leaq 0x206fd(%rip), %rsi     # 0x29ae0
movl 0x4(%rsp), %edi
movslq %r15d, %rax
leaq 0x2072f(%rip), %rcx     # 0x29b20
movl (%rcx,%rax,4), %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
btl %r14d, %ecx
jae 0x954c
leal -0x1(%r15), %ecx
cmpl $0x5, %ecx
ja 0x954c
leaq 0x14f09(%rip), %rdx     # 0x1e320
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
xorl %eax, %eax
cmpl $-0x1, %edi
setne %al
movslq %ebp, %rcx
incl %ebp
movw %ax, 0x12(%rsp,%rcx,2)
jmp 0x9514
movq 0x8(%rsp), %r14
testl %r14d, %r14d
jle 0x954c
decl %r14d
jmp 0x9519
movq 0x8(%rsp), %r14
incl %r14d
jmp 0x9519
cmpl $0x7, %r14d
je 0x957e
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
cmpl $0x6, %r15d
je 0x9484
movslq %edi, %rax
shlq $0x4, %rax
movswl (%rax,%rsi), %eax
movq 0x8(%rsp), %rcx
leal (%rax,%rcx,8), %r14d
movl %edi, 0x4(%rsp)
testl %r12d, %r12d
js 0x94f3
movl %r12d, %eax
movswl 0x40(%rsp,%rax,2), %eax
movl %eax, %ecx
sarl $0x4, %ecx
cmpl %r14d, %ecx
jl 0x94f3
andl $0xf, %eax
shll $0x4, %eax
xorl %ecx, %ecx
cmpw $0x4, 0x2(%rax,%rsi)
setne %cl
movl %ebp, %r13d
subl %ecx, %r13d
jl 0x9547
addq %rsi, %rax
movl %ebp, %ecx
leaq (%rsp,%rcx,2), %rdi
addq $0x10, %rdi
callq *0x8(%rax)
leaq 0x2060d(%rip), %rsi     # 0x29ae0
movslq %r13d, %rcx
movw %ax, 0x10(%rsp,%rcx,2)
leal -0x1(%r12), %eax
movl %r13d, %ebp
testl %r12d, %r12d
movl %eax, %r12d
jg 0x948d
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
jmp 0x94f6
movl %ebp, %r13d
cmpl $0x6, %r15d
je 0x9511
shll $0x4, %r14d
orl 0x4(%rsp), %r14d
movslq %r12d, %rax
incl %r12d
movw %r14w, 0x42(%rsp,%rax,2)
movl %r13d, %ebp
movq 0x8(%rsp), %r14
cmpl $0x6, %r15d
jne 0x92b4
leaq 0x231b2(%rip), %rax     # 0x2c6dc
testb $0x20, (%rax)
jne 0x9582
orl %ebp, %r14d
notl %r12d
movswl 0x10(%rsp), %ecx
orl %r14d, %r12d
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmovel %ecx, %eax
jmp 0x954c
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x138, %rsp            # imm = 0x138
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x1ea8b(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
leaq 0x14dd3(%rip), %rsi     # 0x1e342
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5210
jmp 0x9299
xorl %eax, %eax
jmp 0x954c
leaq 0x10(%rsp), %rdi
callq 0x53cc
jmp 0x952f
nop