home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / k / ksh48.zip / sh / expr.c < prev    next >
C/C++ Source or Header  |  1992-05-03  |  5KB  |  274 lines

  1. /*
  2.  * Korn expression evaluation
  3.  */
  4.  
  5. #ifndef lint
  6. static char *RCSid = "$Id: expr.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
  7. #endif
  8.  
  9. #include "stdh.h"
  10. #include <errno.h>
  11. #include <setjmp.h>
  12. #include "sh.h"
  13.  
  14. #define    ef    else if        /* fashion statement */
  15.  
  16. #define    VAR    0x01
  17. #define    LIT    0x02
  18. #define    LEQ    0x03
  19. #define    LNE    0x04
  20. #define    LLE    0x05
  21. #define    LGE    0x06
  22.  
  23. static char *expression;    /* expression being evaluated */
  24. static char *tokp;    /* lexical position */
  25. static int tok;            /* token from token() */
  26. static struct tbl *val;        /* value from token() */
  27.  
  28. static struct tbl *asn      ARGS((void));
  29. static struct tbl *e6       ARGS((void));
  30. static struct tbl *e5       ARGS((void));
  31. static struct tbl *e3       ARGS((void));
  32. static struct tbl *e2       ARGS((void));
  33. static struct tbl *e0       ARGS((void));
  34. static void     token       ARGS((void));
  35. static struct tbl *tempvar  ARGS((void));
  36. static struct tbl *intvar   ARGS((struct tbl *vp));
  37.  
  38. /*
  39.  * parse and evalute expression
  40.  */
  41. void
  42. evalerr(err)
  43.     char *err;
  44. {
  45.     errorf("%s: %s\n", expression, err);
  46. }
  47.  
  48. long
  49. evaluate(expr)
  50.     const char *expr;
  51. {
  52.     struct tbl *v;
  53.  
  54.     expression = tokp = (char *) expr;
  55.     token();
  56.     v = intvar(asn());
  57.     if (!(tok == 0))
  58.         evalerr("bad expression");
  59.     return v->val.i;
  60. }
  61.  
  62. static struct tbl *
  63. asn()
  64. {
  65.     register struct tbl *vl, *vr;
  66.  
  67.     vr = vl = e6();
  68.     if ((tok == '=')) {
  69.         Area * olastarea = lastarea;
  70.         token();
  71.         if ((vl->flag&RDONLY)) /* assign to rvalue */
  72.             evalerr("bad assignment");
  73.         vr = intvar(asn());
  74.         lastarea = olastarea;
  75.         setint(vl, vr->val.i);
  76.         if ((vl->flag&INTEGER) && vl->type == 0) /* default base? */
  77.             vl->type = vr->type;
  78.     }
  79.     return vr;
  80. }
  81.  
  82. static struct tbl *
  83. e6()
  84. {
  85.     register struct tbl *vl, *vr;
  86.  
  87.     vl = e5();
  88.     while ((tok == LEQ) || (tok == LNE)) {
  89.         int op = tok;
  90.         token();
  91.         vl = intvar(vl);
  92.         vr = intvar(e5());
  93.         vl->val.i = vl->val.i == vr->val.i;
  94.         if (op == LNE)
  95.             vl->val.i = ! vl->val.i;
  96.     }
  97.     return vl;
  98. }
  99.  
  100. static struct tbl *
  101. e5()
  102. {
  103.     register struct tbl *vl, *vr;
  104.  
  105.     vl = e3();
  106.     while ((tok == LLE) || (tok == '<') || (tok == '>') || (tok == LGE)) {
  107.         int op = tok;
  108.         token();
  109.         vl = intvar(vl);
  110.         vr = intvar(e3());
  111.         if (op == LLE)
  112.             vl->val.i = vl->val.i <= vr->val.i;
  113.         ef (op == '<')
  114.             vl->val.i = vl->val.i < vr->val.i;
  115.         ef (op == LGE)
  116.             vl->val.i = vl->val.i >= vr->val.i;
  117.         ef (op == '>')
  118.             vl->val.i = vl->val.i > vr->val.i;
  119.     }
  120.     return vl;
  121. }
  122.  
  123. static struct tbl *
  124. e3()
  125. {
  126.     register struct tbl *vl, *vr;
  127.  
  128.     vl = e2();
  129.     while ((tok == '+') || (tok == '-')) {
  130.         int op = tok;
  131.         token();
  132.         vl = intvar(vl);
  133.         vr = intvar(e2());
  134.         if (op == '+')
  135.             vl->val.i += vr->val.i;
  136.         ef (op == '-')
  137.             vl->val.i -= vr->val.i;
  138.     }
  139.     return vl;
  140. }
  141.  
  142. static struct tbl *
  143. e2()
  144. {
  145.     register struct tbl *vl, *vr;
  146.  
  147.     vl = e0();
  148.     while ((tok == '*') || (tok == '/') || (tok == '%')) {
  149.         int op = tok;
  150.         token();
  151.         vl = intvar(vl);
  152.         vr = intvar(e0());
  153.         if (op != '*' && vr->val.i == 0)
  154.             evalerr("zero divisor");
  155.         if (op == '*')
  156.             vl->val.i *= vr->val.i;
  157.         ef (op == '/')
  158.             vl->val.i /= vr->val.i;
  159.         ef (op == '%')
  160.             vl->val.i %= vr->val.i;
  161.     }
  162.     return vl;
  163. }
  164.  
  165. static struct tbl *
  166. e0()
  167. {
  168.     register struct tbl *v;
  169.  
  170.     if ((tok == '!') || (tok == '-')) {
  171.         int op = tok;
  172.         token();
  173.         v = intvar(e0());
  174.         if (op == '!')
  175.             v->val.i = !v->val.i;
  176.         ef (op == '-')
  177.             v->val.i = -v->val.i;
  178.     } else
  179.     if ((tok == '(')) {
  180.         token();
  181.         v = asn();
  182.         if (!(tok == ')'))
  183.             evalerr("missing )");
  184.         token();
  185.     } else
  186.     if ((tok == VAR) || (tok == LIT)) {
  187.         v = val;
  188.         token();
  189.     } else
  190.         evalerr("bad expression");
  191.     return v;
  192. }
  193.  
  194. static void
  195. token()
  196. {
  197.     register char *cp = (char *) tokp;
  198.     register int c, c2;
  199.  
  200.     /* skip white space */
  201.     do c = *cp++;    while (c != '\0' && (c == ' ' || c == '\t'));
  202.     tokp = cp-1;
  203.  
  204.     if (letter(c)) {
  205.         for (; letnum(c); c = *cp++)
  206.             ;
  207.         c = *--cp;
  208.         *cp = 0;
  209.         val = global(tokp);
  210.         *cp = c;
  211.         tok = VAR;
  212.     } else
  213.     if (digit(c)) {
  214.         for (; letnum(c) || c == '#'; c = *cp++)
  215.             ;
  216.         c = *--cp;
  217.         *cp = 0;
  218.         val = tempvar();
  219.         setstr(val, tokp);
  220.         val->flag |= RDONLY;
  221.         *cp = c;
  222.         tok = LIT;
  223.     } else {
  224.         c2 = *cp++;
  225.         if (c == '=' && c2 == '=')
  226.             c = LEQ;
  227.         ef (c == '!' && c2 == '=')
  228.             c = LNE;
  229.         ef (c == '<' && c2 == '=')
  230.                 c = LLE;
  231.         ef (c == '>' && c2 == '=')
  232.                 c = LGE;
  233.         else
  234.             cp--;
  235.         tok = c;
  236.     }
  237.     tokp = cp;
  238. }
  239.  
  240. static struct tbl *
  241. tempvar()
  242. {
  243.     register struct tbl *vp;
  244.  
  245.     vp = (struct tbl*) alloc(sizeof(struct tbl), ATEMP);
  246.     lastarea = ATEMP;
  247.     vp->flag = ISSET|INTEGER;
  248.     vp->type = 0;
  249.     vp->name[0] = '\0';
  250.     return vp;
  251. }
  252.  
  253. /* cast (string) variable to temporary integer variable */
  254. static struct tbl *
  255. intvar(vp)
  256.     register struct tbl *vp;
  257. {
  258.     register struct tbl *vq;
  259.  
  260.     vq = tempvar();
  261.     vq->type = 10;
  262.     if (strint(vq, vp) == NULL) {
  263.         if ((vp->flag&ISSET) && vp->val.s && *(vp->val.s)) {
  264.             evalerr("bad number");
  265.         } else {
  266.             vq->flag |= (ISSET|INTEGER);
  267.             vq->type = 10;
  268.             vq->val.i = 0;
  269.         }
  270.     }
  271.     return vq;
  272. }
  273.  
  274.