home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Shells / zsh-3.0.5-MIHS / src / Src / math.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-25  |  14.4 KB  |  875 lines

  1. /*
  2.  * $Id: math.c,v 2.11 1996/10/15 20:16:35 hzoli Exp $
  3.  *
  4.  * math.c - mathematical expression evaluation
  5.  *
  6.  * This file is part of zsh, the Z shell.
  7.  *
  8.  * Copyright (c) 1992-1996 Paul Falstad
  9.  * All rights reserved.
  10.  *
  11.  * Permission is hereby granted, without written agreement and without
  12.  * license or royalty fees, to use, copy, modify, and distribute this
  13.  * software and to distribute modified versions of this software for any
  14.  * purpose, provided that the above copyright notice and the following
  15.  * two paragraphs appear in all copies of this software.
  16.  *
  17.  * In no event shall Paul Falstad or the Zsh Development Group be liable
  18.  * to any party for direct, indirect, special, incidental, or consequential
  19.  * damages arising out of the use of this software and its documentation,
  20.  * even if Paul Falstad and the Zsh Development Group have been advised of
  21.  * the possibility of such damage.
  22.  *
  23.  * Paul Falstad and the Zsh Development Group specifically disclaim any
  24.  * warranties, including, but not limited to, the implied warranties of
  25.  * merchantability and fitness for a particular purpose.  The software
  26.  * provided hereunder is on an "as is" basis, and Paul Falstad and the
  27.  * Zsh Development Group have no obligation to provide maintenance,
  28.  * support, updates, enhancements, or modifications.
  29.  *
  30.  */
  31.  
  32. #include "zsh.h"
  33.  
  34. static char *ptr;
  35.  
  36. static long yyval;
  37. static LV yylval;
  38.  
  39. static int mlevel = 0;
  40.  
  41. /* != 0 means recognize unary plus, minus, etc. */
  42.  
  43. static int unary = 1;
  44.  
  45. /* LR = left-to-right associativity *
  46.  * RL = right-to-left associativity *
  47.  * BOO = short-circuiting boolean   */
  48.  
  49. #define LR 0
  50. #define RL 1
  51. #define BOOL 2
  52.  
  53. #define M_INPAR 0
  54. #define M_OUTPAR 1
  55. #define NOT 2
  56. #define COMP 3
  57. #define POSTPLUS 4
  58. #define POSTMINUS 5
  59. #define UPLUS 6
  60. #define UMINUS 7
  61. #define AND 8
  62. #define XOR 9
  63. #define OR 10
  64. #define MUL 11
  65. #define DIV 12
  66. #define MOD 13
  67. #define PLUS 14
  68. #define MINUS 15
  69. #define SHLEFT 16
  70. #define SHRIGHT 17
  71. #define LES 18
  72. #define LEQ 19
  73. #define GRE 20
  74. #define GEQ 21
  75. #define DEQ 22
  76. #define NEQ 23
  77. #define DAND 24
  78. #define DOR 25
  79. #define DXOR 26
  80. #define QUEST 27
  81. #define COLON 28
  82. #define EQ 29
  83. #define PLUSEQ 30
  84. #define MINUSEQ 31
  85. #define MULEQ 32
  86. #define DIVEQ 33
  87. #define MODEQ 34
  88. #define ANDEQ 35
  89. #define XOREQ 36
  90. #define OREQ 37
  91. #define SHLEFTEQ 38
  92. #define SHRIGHTEQ 39
  93. #define DANDEQ 40
  94. #define DOREQ 41
  95. #define DXOREQ 42
  96. #define COMMA 43
  97. #define EOI 44
  98. #define PREPLUS 45
  99. #define PREMINUS 46
  100. #define NUM 47
  101. #define ID 48
  102. #define POWER 49
  103. #define CID 50
  104. #define POWEREQ 51
  105. #define TOKCOUNT 52
  106.  
  107. /* precedences */
  108.  
  109. static int prec[TOKCOUNT] =
  110. {
  111.      1, 137,  2,  2,   2,
  112.      2,   2,  2,  4,   5,
  113.      6,   8,  8,  8,   9,
  114.      9,   3,  3, 10,  10,
  115.     10,  10, 11, 11,  12,
  116.     13,  13, 14, 14,  15,
  117.     15,  15, 15, 15,  15,
  118.     15,  15, 15, 15,  15,
  119.     15,  15, 15, 16, 200,
  120.      2,   2,  0,  0,   7,
  121.      0,  15
  122. };
  123.  
  124. #define TOPPREC 16
  125. #define ARGPREC (TOPPREC-1)
  126.  
  127. static int type[TOKCOUNT] =
  128. {
  129.     LR, LR, RL, RL, RL,
  130.     RL, RL, RL, LR, LR,
  131.     LR, LR, LR, LR, LR,
  132.     LR, LR, LR, LR, LR,
  133.     LR, LR, LR, LR, BOOL,
  134.     BOOL, LR, RL, RL, RL,
  135.     RL, RL, RL, RL, RL,
  136.     RL, RL, RL, RL, RL,
  137.     BOOL, BOOL, RL, RL, RL,
  138.     RL, RL, LR, LR, RL,
  139.     LR, RL
  140. };
  141.  
  142. #define LVCOUNT 32
  143.  
  144. /* list of lvalues (variables) */
  145.  
  146. static int lvc;
  147. static char **lvals;
  148.  
  149.  
  150. /**/
  151. int
  152. zzlex(void)
  153. {
  154.     int cct = 0;
  155.  
  156.     for (;; cct = 0)
  157.     switch (*ptr++) {
  158.     case '+':
  159.         if (*ptr == '+' && (unary || !ialnum(*ptr))) {
  160.         ptr++;
  161.         return (unary) ? PREPLUS : POSTPLUS;
  162.         }
  163.         if (*ptr == '=') {
  164.         unary = 1;
  165.         ptr++;
  166.         return PLUSEQ;
  167.         }
  168.         return (unary) ? UPLUS : PLUS;
  169.     case '-':
  170.         if (*ptr == '-' && (unary || !ialnum(*ptr))) {
  171.         ptr++;
  172.         return (unary) ? PREMINUS : POSTMINUS;
  173.         }
  174.         if (*ptr == '=') {
  175.         unary = 1;
  176.         ptr++;
  177.         return MINUSEQ;
  178.         }
  179.         return (unary) ? UMINUS : MINUS;
  180.     case '(':
  181.         unary = 1;
  182.         return M_INPAR;
  183.     case ')':
  184.         return M_OUTPAR;
  185.     case '!':
  186.         if (*ptr == '=') {
  187.         unary = 1;
  188.         ptr++;
  189.         return NEQ;
  190.         }
  191.         return NOT;
  192.     case '~':
  193.         return COMP;
  194.     case '&':
  195.         unary = 1;
  196.         if (*ptr == '&') {
  197.         if (*++ptr == '=') {
  198.             ptr++;
  199.             return DANDEQ;
  200.         }
  201.         return DAND;
  202.         } else if (*ptr == '=') {
  203.         ptr++;
  204.         return ANDEQ;
  205.         }
  206.         return AND;
  207.     case '|':
  208.         unary = 1;
  209.         if (*ptr == '|') {
  210.         if (*++ptr == '=') {
  211.             ptr++;
  212.             return DOREQ;
  213.         }
  214.         return DOR;
  215.         } else if (*ptr == '=') {
  216.         ptr++;
  217.         return OREQ;
  218.         }
  219.         return OR;
  220.     case '^':
  221.         unary = 1;
  222.         if (*ptr == '^') {
  223.         if (*++ptr == '=') {
  224.             ptr++;
  225.             return DXOREQ;
  226.         }
  227.         return DXOR;
  228.         } else if (*ptr == '=') {
  229.         ptr++;
  230.         return XOREQ;
  231.         }
  232.         return XOR;
  233.     case '*':
  234.         unary = 1;
  235.         if (*ptr == '*') {
  236.         if (*++ptr == '=') {
  237.             ptr++;
  238.             return POWEREQ;
  239.         }
  240.         return POWER;
  241.         }
  242.         if (*ptr == '=') {
  243.         ptr++;
  244.         return MULEQ;
  245.         }
  246.         return MUL;
  247.     case '/':
  248.         unary = 1;
  249.         if (*ptr == '=') {
  250.         ptr++;
  251.         return DIVEQ;
  252.         }
  253.         return DIV;
  254.     case '%':
  255.         unary = 1;
  256.         if (*ptr == '=') {
  257.         ptr++;
  258.         return MODEQ;
  259.         }
  260.         return MOD;
  261.     case '<':
  262.         unary = 1;
  263.         if (*ptr == '<') {
  264.         if (*++ptr == '=') {
  265.             ptr++;
  266.             return SHLEFTEQ;
  267.         }
  268.         return SHLEFT;
  269.         } else if (*ptr == '=') {
  270.         ptr++;
  271.         return LEQ;
  272.         }
  273.         return LES;
  274.     case '>':
  275.         unary = 1;
  276.         if (*ptr == '>') {
  277.         if (*++ptr == '=') {
  278.             ptr++;
  279.             return SHRIGHTEQ;
  280.         }
  281.         return SHRIGHT;
  282.         } else if (*ptr == '=') {
  283.         ptr++;
  284.         return GEQ;
  285.         }
  286.         return GRE;
  287.     case '=':
  288.         unary = 1;
  289.         if (*ptr == '=') {
  290.         ptr++;
  291.         return DEQ;
  292.         }
  293.         return EQ;
  294.     case '$':
  295.         unary = 0;
  296.         yyval = mypid;
  297.         return NUM;
  298.     case '?':
  299.         if (unary) {
  300.         yyval = lastval;
  301.         unary = 0;
  302.         return NUM;
  303.         }
  304.         unary = 1;
  305.         return QUEST;
  306.     case ':':
  307.         unary = 1;
  308.         return COLON;
  309.     case ',':
  310.         unary = 1;
  311.         return COMMA;
  312.     case '\0':
  313.         unary = 1;
  314.         ptr--;
  315.         return EOI;
  316.     case '[':
  317.         unary = 0;
  318.         {
  319.         int base = zstrtol(ptr, &ptr, 10);
  320.  
  321.         if (*ptr == ']')
  322.             ptr++;
  323.         yyval = zstrtol(ptr, &ptr, lastbase = base);
  324.         return NUM;
  325.         }
  326.     case ' ':
  327.     case '\t':
  328.     case '\n':
  329.         break;
  330.     case '0':
  331.         if (*ptr == 'x' || *ptr == 'X') {
  332.         unary = 0;
  333.         /* Should we set lastbase here? */
  334.         yyval = zstrtol(++ptr, &ptr, lastbase = 16);
  335.         return NUM;
  336.         }
  337.     /* Fall through! */
  338.     default:
  339.         if (idigit(*--ptr)) {
  340.         unary = 0;
  341.         yyval = zstrtol(ptr, &ptr, 10);
  342.  
  343.         if (*ptr == '#') {
  344.             ptr++;
  345.             yyval = zstrtol(ptr, &ptr, lastbase = yyval);
  346.         }
  347.         return NUM;
  348.         }
  349.         if (*ptr == '#') {
  350.         if (*++ptr == '\\') {
  351.             ptr++;
  352.             yyval = *ptr == Meta ? *++ptr ^ 32 : *ptr;
  353.             ptr++;
  354.             unary = 0;
  355.             return NUM;
  356.         }
  357.         cct = 1;
  358.         }
  359.         if (iident(*ptr)) {
  360.         char *p, q;
  361.  
  362.         p = ptr;
  363.         if (lvc == LVCOUNT) {
  364.             zerr("too many identifiers (complain to author)", NULL, 0);
  365.             return EOI;
  366.         }
  367.         unary = 0;
  368.         while (iident(*++ptr));
  369.         if (*ptr == '[') {
  370.             int l;
  371.             for (ptr++, l = 1; *ptr && l; ptr++) {
  372.             if (*ptr == '[')
  373.                 l++;
  374.             if (*ptr == ']')
  375.                 l--;
  376.             if (*ptr == '\\' && ptr[1])
  377.                 ptr++;
  378.             }
  379.         }
  380.         q = *ptr;
  381.         *ptr = '\0';
  382.         lvals[yylval = lvc++] = ztrdup(p);
  383.         *ptr = q;
  384.         return cct ? CID : ID;
  385.         }
  386.         else if (cct) {
  387.         yyval = poundgetfn(NULL);
  388.         unary = 0;
  389.         return NUM;
  390.         }
  391.         return EOI;
  392.     }
  393. }
  394.  
  395. /* the value stack */
  396.  
  397. #define STACKSZ 100
  398. int mtok;            /* last token */
  399. int sp = -1;            /* stack pointer */
  400. struct mathvalue {
  401.     LV lval;
  402.     long val;
  403. };
  404.  
  405. static struct mathvalue *stack;
  406.  
  407. static void push _((long val, LV lval));
  408.  
  409. static void
  410. push(long val, LV lval)
  411. {
  412.     if (sp == STACKSZ - 1)
  413.     zerr("stack overflow", NULL, 0);
  414.     else
  415.     sp++;
  416.     stack[sp].val = val;
  417.     stack[sp].lval = lval;
  418. }
  419.  
  420.  
  421. /**/
  422. long
  423. getcvar(LV s)
  424. {
  425.     char *t;
  426.  
  427.     if (!(t = getsparam(lvals[s])))
  428.     return 0;
  429.     return STOUC(*t == Meta ? t[1] ^ 32 : *t);
  430. }
  431.  
  432.  
  433. /**/
  434. long
  435. setvar(LV s, long v)
  436. {
  437.     if (s == -1 || s >= lvc) {
  438.     zerr("lvalue required", NULL, 0);
  439.     return 0;
  440.     }
  441.     if (noeval)
  442.     return v;
  443.     setiparam(lvals[s], v);
  444.     return v;
  445. }
  446.  
  447.  
  448. /**/
  449. int
  450. notzero(long a)
  451. {
  452.     if (a == 0) {
  453.     zerr("division by zero", NULL, 0);
  454.     return 0;
  455.     }
  456.     return 1;
  457. }
  458.  
  459. /* macro to pop two values off the value stack */
  460. #define pop2() { \
  461.     if (sp < 1) { \
  462.          zerr("bad math expression: unbalanced stack", NULL, 0); \
  463.         return; \
  464.     } \
  465.     b = stack[sp--].val; \
  466.     a = stack[sp--].val; \
  467.     }
  468.  
  469. /* macro to pop three values off the value stack */
  470. #define pop3() { \
  471.     if (sp < 2) { \
  472.          zerr("bad math expression: unbalanced stack", NULL, 0); \
  473.         return; \
  474.     } \
  475.     c = stack[sp--].val; \
  476.     b = stack[sp--].val; \
  477.     a = stack[sp--].val; \
  478.     }
  479.  
  480. #define nolval() {stack[sp].lval= -1;}
  481. #define pushv(X) { push(X,-1); }
  482. #define pop2lv() { pop2() lv = stack[sp+1].lval; }
  483. #define set(X) { push(setvar(lv,X),lv); }
  484.  
  485.  
  486. /**/
  487. void
  488. op(int what)
  489. {
  490.     long a, b, c;
  491.     LV lv;
  492.  
  493.     if (sp < 0) {
  494.     zerr("bad math expression: stack empty", NULL, 0);
  495.     return;
  496.     }
  497.     switch (what) {
  498.     case NOT:
  499.     stack[sp].val = !stack[sp].val;
  500.     nolval();
  501.     break;
  502.     case COMP:
  503.     stack[sp].val = ~stack[sp].val;
  504.     nolval();
  505.     break;
  506.     case POSTPLUS:
  507.     (void)setvar(stack[sp].lval, stack[sp].val + 1);
  508.     break;
  509.     case POSTMINUS:
  510.     (void)setvar(stack[sp].lval, stack[sp].val - 1);
  511.     break;
  512.     case UPLUS:
  513.     nolval();
  514.     break;
  515.     case UMINUS:
  516.     stack[sp].val = -stack[sp].val;
  517.     nolval();
  518.     break;
  519.     case AND:
  520.     pop2();
  521.     pushv(a & b);
  522.     break;
  523.     case XOR:
  524.     pop2();
  525.     pushv(a ^ b);
  526.     break;
  527.     case OR:
  528.     pop2();
  529.     pushv(a | b);
  530.     break;
  531.     case MUL:
  532.     pop2();
  533.     pushv(a * b);
  534.     break;
  535.     case DIV:
  536.     pop2();
  537.     if (notzero(b))
  538.         pushv(a / b);
  539.     break;
  540.     case MOD:
  541.     pop2();
  542.     if (notzero(b))
  543.         pushv(a % b);
  544.     break;
  545.     case PLUS:
  546.     pop2();
  547.     pushv(a + b);
  548.     break;
  549.     case MINUS:
  550.     pop2();
  551.     pushv(a - b);
  552.     break;
  553.     case SHLEFT:
  554.     pop2();
  555.     pushv(a << b);
  556.     break;
  557.     case SHRIGHT:
  558.     pop2();
  559.     pushv(a >> b);
  560.     break;
  561.     case LES:
  562.     pop2();
  563.     pushv((long)(a < b));
  564.     break;
  565.     case LEQ:
  566.     pop2();
  567.     pushv((long)(a <= b));
  568.     break;
  569.     case GRE:
  570.     pop2();
  571.     pushv((long)(a > b));
  572.     break;
  573.     case GEQ:
  574.     pop2();
  575.     pushv((long)(a >= b));
  576.     break;
  577.     case DEQ:
  578.     pop2();
  579.     pushv((long)(a == b));
  580.     break;
  581.     case NEQ:
  582.     pop2();
  583.     pushv((long)(a != b));
  584.     break;
  585.     case DAND:
  586.     pop2();
  587.     pushv((long)(a && b));
  588.     break;
  589.     case DOR:
  590.     pop2();
  591.     pushv((long)(a || b));
  592.     break;
  593.     case DXOR:
  594.     pop2();
  595.     pushv((long)((a && !b) || (!a && b)));
  596.     break;
  597.     case QUEST:
  598.     pop3();
  599.     pushv((a) ? b : c);
  600.     break;
  601.     case COLON:
  602.     break;
  603.     case EQ:
  604.     pop2();
  605.     lv = stack[sp + 1].lval;
  606.     set(b);
  607.     break;
  608.     case PLUSEQ:
  609.     pop2lv();
  610.     set(a + b);
  611.     break;
  612.     case MINUSEQ:
  613.     pop2lv();
  614.     set(a - b);
  615.     break;
  616.     case MULEQ:
  617.     pop2lv();
  618.     set(a * b);
  619.     break;
  620.     case DIVEQ:
  621.     pop2lv();
  622.     if (notzero(b))
  623.         set(a / b);
  624.     break;
  625.     case MODEQ:
  626.     pop2lv();
  627.     if (notzero(b))
  628.         set(a % b);
  629.     break;
  630.     case ANDEQ:
  631.     pop2lv();
  632.     set(a & b);
  633.     break;
  634.     case XOREQ:
  635.     pop2lv();
  636.     set(a ^ b);
  637.     break;
  638.     case OREQ:
  639.     pop2lv();
  640.     set(a | b);
  641.     break;
  642.     case SHLEFTEQ:
  643.     pop2lv();
  644.     set(a << b);
  645.     break;
  646.     case SHRIGHTEQ:
  647.     pop2lv();
  648.     set(a >> b);
  649.     break;
  650.     case DANDEQ:
  651.     pop2lv();
  652.     set((long)(a && b));
  653.     break;
  654.     case DOREQ:
  655.     pop2lv();
  656.     set((long)(a || b));
  657.     break;
  658.     case DXOREQ:
  659.     pop2lv();
  660.     set((long)((a && !b) || (!a && b)));
  661.     break;
  662.     case COMMA:
  663.     pop2();
  664.     pushv(b);
  665.     break;
  666.     case PREPLUS:
  667.     stack[sp].val = setvar(stack[sp].lval,
  668.                    stack[sp].val + 1);
  669.     break;
  670.     case PREMINUS:
  671.     stack[sp].val = setvar(stack[sp].lval,
  672.                    stack[sp].val - 1);
  673.     break;
  674.     case POWER:
  675.     pop2();
  676.     if (b < 0) {
  677.         zerr("can't handle negative exponents", NULL, 0);
  678.         return;
  679.     }
  680.     for (c = 1; b--; c *= a);
  681.     pushv(c);
  682.     break;
  683.     case POWEREQ:
  684.     pop2lv();
  685.     if (b < 0) {
  686.         zerr("can't handle negative exponents", NULL, 0);
  687.         return;
  688.     }
  689.     for (c = 1; b--; c *= a);
  690.     set(c);
  691.     break;
  692.     default:
  693.     zerr("out of integers", NULL, 0);
  694.     return;
  695.     }
  696. }
  697.  
  698.  
  699. /**/
  700. void
  701. bop(int tk)
  702. {
  703.     switch (tk) {
  704.     case DAND:
  705.     case DANDEQ:
  706.     if (!stack[sp].val)
  707.         noeval++;
  708.     break;
  709.     case DOR:
  710.     case DOREQ:
  711.     if (stack[sp].val)
  712.         noeval++;
  713.     break;
  714.     };
  715. }
  716.  
  717.  
  718. /**/
  719. long
  720. mathevall(char *s, int prek, char **ep)
  721. {
  722.     int t0;
  723.     int xlastbase, xnoeval, xunary, xlvc;
  724.     char *xptr;
  725.     long xyyval;
  726.     LV xyylval;
  727.     char **xlvals = 0;
  728.     int xsp;
  729.     struct mathvalue *xstack = 0;
  730.     long ret;
  731.  
  732.     xlastbase = xnoeval = xunary = xlvc = xyyval = xyylval = xsp = 0;
  733.     xptr = NULL;
  734.     if (mlevel++) {
  735.     xlastbase = lastbase;
  736.     xnoeval = noeval;
  737.     xunary = unary;
  738.     xlvc = lvc;
  739.     xptr = ptr;
  740.     xyyval = yyval;
  741.     xyylval = yylval;
  742.     xlvals = lvals;
  743.  
  744.     xsp = sp;
  745.     xstack = stack;
  746.     }
  747.     stack = (struct mathvalue *)zalloc(STACKSZ*sizeof(struct mathvalue));
  748.     lastbase = -1;
  749.     lvals = (char **)zcalloc(LVCOUNT*sizeof(char *));
  750.     lvc = 0;
  751.     ptr = s;
  752.     sp = -1;
  753.     unary = 1;
  754.     mathparse(prek);
  755.     *ep = ptr;
  756.     if (sp)
  757.     zerr("bad math expression: unbalanced stack", NULL, 0);
  758.     for (t0 = 0; t0 != lvc; t0++)
  759.     zsfree(lvals[t0]);
  760.  
  761.     ret = stack[0].val;
  762.  
  763.     zfree(lvals, LVCOUNT*sizeof(char *));
  764.     zfree(stack, STACKSZ*sizeof(struct mathvalue));
  765.     if (--mlevel) {
  766.     lastbase = xlastbase;
  767.     noeval = xnoeval;
  768.     unary = xunary;
  769.     lvc = xlvc;
  770.     ptr = xptr;
  771.     yyval = xyyval;
  772.     yylval = xyylval;
  773.     lvals = xlvals;
  774.  
  775.     sp = xsp;
  776.     stack = xstack;
  777.     }
  778.     return ret;
  779. }
  780.  
  781.  
  782. /**/
  783. long
  784. matheval(char *s)
  785. {
  786.     char *junk;
  787.     long x;
  788.     int xmtok = mtok;
  789.  
  790.     if (!*s)
  791.     return 0;
  792.     x = mathevall(s, TOPPREC, &junk);
  793.     mtok = xmtok;
  794.     if (*junk)
  795.     zerr("bad math expression: illegal character: %c", NULL, *junk);
  796.     return x;
  797. }
  798.  
  799.  
  800. /**/
  801. long
  802. mathevalarg(char *s, char **ss)
  803. {
  804.     long x;
  805.     int xmtok = mtok;
  806.  
  807.     x = mathevall(s, ARGPREC, ss);
  808.     if (mtok == COMMA)
  809.     (*ss)--;
  810.     mtok = xmtok;
  811.     return x;
  812. }
  813.  
  814.  
  815. /* operator-precedence parse the string and execute */
  816.  
  817. /**/
  818. void
  819. mathparse(int pc)
  820. {
  821.     int q, otok, onoeval;
  822.  
  823.     if (errflag)
  824.     return;
  825.     mtok = zzlex();
  826.     while (prec[mtok] <= pc) {
  827.     if (errflag)
  828.         return;
  829.     switch (mtok) {
  830.     case NUM:
  831.         push(yyval, -1);
  832.         break;
  833.     case ID:
  834.         push(getiparam(lvals[yylval]), yylval);
  835.         break;
  836.     case CID:
  837.         push(getcvar(yylval), yylval);
  838.         break;
  839.     case M_INPAR:
  840.         mathparse(TOPPREC);
  841.         if (mtok != M_OUTPAR) {
  842.         if (!errflag)
  843.             zerr("')' expected", NULL, 0);
  844.         return;
  845.         }
  846.         break;
  847.     case QUEST:
  848.         q = stack[sp].val;
  849.  
  850.         if (!q)
  851.         noeval++;
  852.         mathparse(prec[QUEST] - 1);
  853.         if (!q)
  854.         noeval--;
  855.         else
  856.         noeval++;
  857.         mathparse(prec[QUEST]);
  858.         if (q)
  859.         noeval--;
  860.         op(QUEST);
  861.         continue;
  862.     default:
  863.         otok = mtok;
  864.         onoeval = noeval;
  865.         if (type[otok] == BOOL)
  866.         bop(otok);
  867.         mathparse(prec[otok] - (type[otok] != RL));
  868.         noeval = onoeval;
  869.         op(otok);
  870.         continue;
  871.     }
  872.     mtok = zzlex();
  873.     }
  874. }
  875.