home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / gnu / m4-1.1-src.lha / src / amiga / m4-1.1 / eval.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-02  |  12.7 KB  |  745 lines

  1. /* GNU m4 -- A simple macro processor
  2.    Copyright (C) 1989, 90, 91, 92, 93 Free Software Foundation, Inc.
  3.   
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.   
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.   
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18.  
  19. /* This file contains the functions to evaluate integer expressions for
  20.    the "eval" macro.  It is a little, fairly self-contained module, with
  21.    its own scanner, and a recursive descent parser.  The only entry point
  22.    is evaluate ().  */
  23.  
  24. #include "m4.h"
  25.  
  26. /* Evaluates token types.  */
  27.  
  28. typedef enum eval_token
  29.   {
  30.     ERROR,
  31.     PLUS, MINUS,
  32.     EXPONENT,
  33.     TIMES, DIVIDE, MODULO,
  34.     EQ, NOTEQ, GT, GTEQ, LS, LSEQ,
  35.     LSHIFT, RSHIFT,
  36.     LNOT, LAND, LOR,
  37.     NOT, AND, OR, XOR,
  38.     LEFTP, RIGHTP,
  39.     NUMBER, EOTEXT
  40.   }
  41. eval_token;
  42.  
  43. /* Error types.  */
  44.  
  45. typedef enum eval_error
  46.   {
  47.     NO_ERROR,
  48.     MISSING_RIGHT,
  49.     SYNTAX_ERROR,
  50.     UNKNOWN_INPUT,
  51.     DIVIDE_ZERO,
  52.     MODULO_ZERO
  53.   }
  54. eval_error;
  55.  
  56. static eval_error logical_or_term ();
  57. static eval_error logical_and_term ();
  58. static eval_error or_term ();
  59. static eval_error xor_term ();
  60. static eval_error and_term ();
  61. static eval_error not_term ();
  62. static eval_error logical_not_term ();
  63. static eval_error cmp_term ();
  64. static eval_error shift_term ();
  65. static eval_error add_term ();
  66. static eval_error mult_term ();
  67. static eval_error exp_term ();
  68. static eval_error unary_term ();
  69. static eval_error simple_term ();
  70.  
  71. /*--------------------.
  72. | Lexical functions.  |
  73. `--------------------*/
  74.  
  75. /* Pointer to next character of input text.  */
  76. static char *eval_text;
  77.  
  78. /* Value of eval_text, from before last call of eval_lex ().  This is so we
  79.    can back up, if we have read too much.  */
  80. static char *last_text;
  81.  
  82. static void
  83. eval_init_lex (char *text)
  84. {
  85.   eval_text = text;
  86.   last_text = NULL;
  87. }
  88.  
  89. static void
  90. eval_undo (void)
  91. {
  92.   eval_text = last_text;
  93. }
  94.  
  95. /* VAL is numerical value, if any.  */
  96.  
  97. static eval_token
  98. eval_lex (int *val)
  99. {
  100.   while (isspace (*eval_text))
  101.     eval_text++;
  102.  
  103.   last_text = eval_text;
  104.  
  105.   if (*eval_text == '\0')
  106.     return EOTEXT;
  107.  
  108.   if (isdigit (*eval_text))
  109.     {
  110.       int base, digit;
  111.  
  112.       if (*eval_text == '0')
  113.     {
  114.       eval_text++;
  115.       switch (*eval_text)
  116.         {
  117.         case 'x':
  118.         case 'X':
  119.           base = 16;
  120.           eval_text++;
  121.           break;
  122.  
  123.         case 'b':
  124.         case 'B':
  125.           base = 2;
  126.           eval_text++;
  127.           break;
  128.  
  129.         case 'r':
  130.         case 'R':
  131.           base = 0;
  132.           eval_text++;
  133.           while (isdigit (*eval_text) && base <= 36)
  134.         base = 10 * base + *eval_text++ - '0';
  135.           if (base == 0 || base > 36 || *eval_text != ':')
  136.         return ERROR;
  137.           eval_text++;
  138.           break;
  139.  
  140.         default:
  141.           base = 8;
  142.         }
  143.     }
  144.       else
  145.     base = 10;
  146.  
  147.       (*val) = 0;
  148.       for (; *eval_text; eval_text++)
  149.     {
  150.       if (isdigit (*eval_text))
  151.         digit = *eval_text - '0';
  152.       else if (islower (*eval_text))
  153.         digit = *eval_text - 'a' + 10;
  154.       else if (isupper (*eval_text))
  155.         digit = *eval_text - 'A' + 10;
  156.       else
  157.         break;
  158.  
  159.       if (digit >= base)
  160.         break;
  161.  
  162.       (*val) = (*val) * base + digit;
  163.     }
  164.       return NUMBER;
  165.     }
  166.  
  167.   switch (*eval_text++)
  168.     {
  169.     case '+':
  170.       return PLUS;
  171.     case '-':
  172.       return MINUS;
  173.     case '*':
  174.       if (*eval_text == '*')
  175.     {
  176.       eval_text++;
  177.       return EXPONENT;
  178.     }
  179.       else
  180.     return TIMES;
  181.     case '/':
  182.       return DIVIDE;
  183.     case '%':
  184.       return MODULO;
  185.     case '=':
  186.       if (*eval_text == '=')
  187.     eval_text++;
  188.       return EQ;
  189.     case '!':
  190.       if (*eval_text == '=')
  191.     {
  192.       eval_text++;
  193.       return NOTEQ;
  194.     }
  195.       else
  196.     return LNOT;
  197.     case '>':
  198.       if (*eval_text == '=')
  199.     {
  200.       eval_text++;
  201.       return GTEQ;
  202.     }
  203.       else if (*eval_text == '>')
  204.     {
  205.       eval_text++;
  206.       return RSHIFT;
  207.     }
  208.       else
  209.     return GT;
  210.     case '<':
  211.       if (*eval_text == '=')
  212.     {
  213.       eval_text++;
  214.       return LSEQ;
  215.     }
  216.       else if (*eval_text == '<')
  217.     {
  218.       eval_text++;
  219.       return LSHIFT;
  220.     }
  221.       else
  222.     return LS;
  223.     case '^':
  224.       return XOR;
  225.     case '~':
  226.       return NOT;
  227.     case '&':
  228.       if (*eval_text == '&')
  229.     {
  230.       eval_text++;
  231.       return LAND;
  232.     }
  233.       else
  234.     return AND;
  235.     case '|':
  236.       if (*eval_text == '|')
  237.     {
  238.       eval_text++;
  239.       return LOR;
  240.     }
  241.       else
  242.     return OR;
  243.     case '(':
  244.       return LEFTP;
  245.     case ')':
  246.       return RIGHTP;
  247.     default:
  248.       return ERROR;
  249.     }
  250. }
  251.  
  252. /*---------------------------------------.
  253. | Main entry point, called from "eval".     |
  254. `---------------------------------------*/
  255.  
  256. boolean
  257. evaluate (char *expr, int *val)
  258. {
  259.   eval_token et;
  260.   eval_error err;
  261.  
  262.   eval_init_lex (expr);
  263.   et = eval_lex (val);
  264.   err = logical_or_term (et, val);
  265.  
  266.   switch (err)
  267.     {
  268.     case NO_ERROR:
  269.       break;
  270.     case MISSING_RIGHT:
  271.       m4error ("bad expression in eval (missing right paren): %s", expr);
  272.       break;
  273.     case SYNTAX_ERROR:
  274.       m4error ("bad expression in eval: %s", expr);
  275.       break;
  276.     case UNKNOWN_INPUT:
  277.       m4error ("bad expression in eval (bad input): %s", expr);
  278.       break;
  279.     case DIVIDE_ZERO:
  280.       m4error ("divide by zero in eval: %s", expr);
  281.       break;
  282.     case MODULO_ZERO:
  283.       m4error ("modulo by zero in eval: %s", expr);
  284.       break;
  285.     default:
  286.       internal_error ("Bad error code in evaluate ()");
  287.       break;
  288.     }
  289.  
  290.   return (boolean) (err != NO_ERROR);
  291. }
  292.  
  293. /*---------------------------.
  294. | Recursive descent parser.  |
  295. `---------------------------*/
  296.  
  297. static eval_error
  298. logical_or_term (eval_token et, int *v1)
  299. {
  300.   int v2;
  301.   eval_error er;
  302.  
  303.   if ((er = logical_and_term (et, v1)) != NO_ERROR)
  304.     return er;
  305.  
  306.   while ((et = eval_lex (&v2)) == LOR)
  307.     {
  308.       et = eval_lex (&v2);
  309.       if (et == ERROR)
  310.     return UNKNOWN_INPUT;
  311.  
  312.       if ((er = logical_and_term (et, &v2)) != NO_ERROR)
  313.     return er;
  314.  
  315.       *v1 = *v1 || v2;
  316.     }
  317.   if (et == ERROR)
  318.     return UNKNOWN_INPUT;
  319.  
  320.   eval_undo ();
  321.   return NO_ERROR;
  322. }
  323.  
  324. static eval_error
  325. logical_and_term (eval_token et, int *v1)
  326. {
  327.   int v2;
  328.   eval_error er;
  329.  
  330.   if ((er = or_term (et, v1)) != NO_ERROR)
  331.     return er;
  332.  
  333.   while ((et = eval_lex (&v2)) == LAND)
  334.     {
  335.       et = eval_lex (&v2);
  336.       if (et == ERROR)
  337.     return UNKNOWN_INPUT;
  338.  
  339.       if ((er = or_term (et, &v2)) != NO_ERROR)
  340.     return er;
  341.  
  342.       *v1 = *v1 && v2;
  343.     }
  344.   if (et == ERROR)
  345.     return UNKNOWN_INPUT;
  346.  
  347.   eval_undo ();
  348.   return NO_ERROR;
  349. }
  350.  
  351. static eval_error
  352. or_term (eval_token et, int *v1)
  353. {
  354.   int v2;
  355.   eval_error er;
  356.  
  357.   if ((er = xor_term (et, v1)) != NO_ERROR)
  358.     return er;
  359.  
  360.   while ((et = eval_lex (&v2)) == OR)
  361.     {
  362.       et = eval_lex (&v2);
  363.       if (et == ERROR)
  364.     return UNKNOWN_INPUT;
  365.  
  366.       if ((er = xor_term (et, &v2)) != NO_ERROR)
  367.     return er;
  368.  
  369.       *v1 = *v1 | v2;
  370.     }
  371.   if (et == ERROR)
  372.     return UNKNOWN_INPUT;
  373.  
  374.   eval_undo ();
  375.   return NO_ERROR;
  376. }
  377.  
  378. static eval_error
  379. xor_term (eval_token et, int *v1)
  380. {
  381.   int v2;
  382.   eval_error er;
  383.  
  384.   if ((er = and_term (et, v1)) != NO_ERROR)
  385.     return er;
  386.  
  387.   while ((et = eval_lex (&v2)) == XOR)
  388.     {
  389.       et = eval_lex (&v2);
  390.       if (et == ERROR)
  391.     return UNKNOWN_INPUT;
  392.  
  393.       if ((er = and_term (et, &v2)) != NO_ERROR)
  394.     return er;
  395.  
  396.       *v1 = *v1 ^ v2;
  397.     }
  398.   if (et == ERROR)
  399.     return UNKNOWN_INPUT;
  400.  
  401.   eval_undo ();
  402.   return NO_ERROR;
  403. }
  404.  
  405. static eval_error
  406. and_term (eval_token et, int *v1)
  407. {
  408.   int v2;
  409.   eval_error er;
  410.  
  411.   if ((er = not_term (et, v1)) != NO_ERROR)
  412.     return er;
  413.  
  414.   while ((et = eval_lex (&v2)) == AND)
  415.     {
  416.       et = eval_lex (&v2);
  417.       if (et == ERROR)
  418.     return UNKNOWN_INPUT;
  419.  
  420.       if ((er = not_term (et, &v2)) != NO_ERROR)
  421.     return er;
  422.  
  423.       *v1 = *v1 & v2;
  424.     }
  425.   if (et == ERROR)
  426.     return UNKNOWN_INPUT;
  427.  
  428.   eval_undo ();
  429.   return NO_ERROR;
  430. }
  431.  
  432. static eval_error
  433. not_term (eval_token et, int *v1)
  434. {
  435.   eval_error er;
  436.  
  437.   if (et == NOT)
  438.     {
  439.       et = eval_lex (v1);
  440.       if (et == ERROR)
  441.     return UNKNOWN_INPUT;
  442.  
  443.       if ((er = not_term (et, v1)) != NO_ERROR)
  444.     return er;
  445.       *v1 = ~*v1;
  446.     }
  447.   else
  448.     if ((er = logical_not_term (et, v1)) != NO_ERROR)
  449.       return er;
  450.  
  451.   return NO_ERROR;
  452. }
  453.  
  454. static eval_error
  455. logical_not_term (eval_token et, int *v1)
  456. {
  457.   eval_error er;
  458.  
  459.   if (et == LNOT)
  460.     {
  461.       et = eval_lex (v1);
  462.       if (et == ERROR)
  463.     return UNKNOWN_INPUT;
  464.  
  465.       if ((er = logical_not_term (et, v1)) != NO_ERROR)
  466.     return er;
  467.       *v1 = !*v1;
  468.     }
  469.   else
  470.     if ((er = cmp_term (et, v1)) != NO_ERROR)
  471.       return er;
  472.  
  473.   return NO_ERROR;
  474. }
  475.  
  476. static eval_error
  477. cmp_term (eval_token et, int *v1)
  478. {
  479.   eval_token op;
  480.   int v2;
  481.   eval_error er;
  482.  
  483.   if ((er = shift_term (et, v1)) != NO_ERROR)
  484.     return er;
  485.  
  486.   while ((op = eval_lex (&v2)) == EQ || op == NOTEQ
  487.      || op == GT || op == GTEQ
  488.      || op == LS || op == LSEQ)
  489.     {
  490.  
  491.       et = eval_lex (&v2);
  492.       if (et == ERROR)
  493.     return UNKNOWN_INPUT;
  494.  
  495.       if ((er = shift_term (et, &v2)) != NO_ERROR)
  496.     return er;
  497.  
  498.       switch (op)
  499.     {
  500.     case EQ:
  501.       *v1 = *v1 == v2;
  502.       break;
  503.  
  504.     case NOTEQ:
  505.       *v1 = *v1 != v2;
  506.       break;
  507.  
  508.     case GT:
  509.       *v1 = *v1 > v2;
  510.       break;
  511.  
  512.     case GTEQ:
  513.       *v1 = *v1 >= v2;
  514.       break;
  515.  
  516.     case LS:
  517.       *v1 = *v1 < v2;
  518.       break;
  519.  
  520.     case LSEQ:
  521.       *v1 = *v1 <= v2;
  522.       break;
  523.  
  524.     default:
  525.       internal_error ("Bad comparison operator in cmp_term ()");
  526.       break;
  527.     }
  528.     }
  529.   if (op == ERROR)
  530.     return UNKNOWN_INPUT;
  531.  
  532.   eval_undo ();
  533.   return NO_ERROR;
  534. }
  535.  
  536. static eval_error
  537. shift_term (eval_token et, int *v1)
  538. {
  539.   eval_token op;
  540.   int v2;
  541.   eval_error er;
  542.  
  543.   if ((er = add_term (et, v1)) != NO_ERROR)
  544.     return er;
  545.  
  546.   while ((op = eval_lex (&v2)) == LSHIFT || op == RSHIFT)
  547.     {
  548.  
  549.       et = eval_lex (&v2);
  550.       if (et == ERROR)
  551.     return UNKNOWN_INPUT;
  552.  
  553.       if ((er = add_term (et, &v2)) != NO_ERROR)
  554.     return er;
  555.  
  556.       switch (op)
  557.     {
  558.     case LSHIFT:
  559.       *v1 = *v1 << v2;
  560.       break;
  561.  
  562.     case RSHIFT:
  563.       *v1 = *v1 >> v2;
  564.       break;
  565.  
  566.     default:
  567.       internal_error ("Bad shift operator in shift_term ()");
  568.       break;
  569.     }
  570.     }
  571.   if (op == ERROR)
  572.     return UNKNOWN_INPUT;
  573.  
  574.   eval_undo ();
  575.   return NO_ERROR;
  576. }
  577.  
  578. static eval_error
  579. add_term (eval_token et, int *v1)
  580. {
  581.   eval_token op;
  582.   int v2;
  583.   eval_error er;
  584.  
  585.   if ((er = mult_term (et, v1)) != NO_ERROR)
  586.     return er;
  587.  
  588.   while ((op = eval_lex (&v2)) == PLUS || op == MINUS)
  589.     {
  590.       et = eval_lex (&v2);
  591.       if (et == ERROR)
  592.     return UNKNOWN_INPUT;
  593.  
  594.       if ((er = mult_term (et, &v2)) != NO_ERROR)
  595.     return er;
  596.  
  597.       if (op == PLUS)
  598.     *v1 = *v1 + v2;
  599.       else
  600.     *v1 = *v1 - v2;
  601.     }
  602.   if (op == ERROR)
  603.     return UNKNOWN_INPUT;
  604.  
  605.   eval_undo ();
  606.   return NO_ERROR;
  607. }
  608.  
  609. static eval_error
  610. mult_term (eval_token et, int *v1)
  611. {
  612.   eval_token op;
  613.   int v2;
  614.   eval_error er;
  615.  
  616.   if ((er = exp_term (et, v1)) != NO_ERROR)
  617.     return er;
  618.  
  619.   while ((op = eval_lex (&v2)) == TIMES || op == DIVIDE || op == MODULO)
  620.     {
  621.       et = eval_lex (&v2);
  622.       if (et == ERROR)
  623.     return UNKNOWN_INPUT;
  624.  
  625.       if ((er = exp_term (et, &v2)) != NO_ERROR)
  626.     return er;
  627.  
  628.       switch (op)
  629.     {
  630.     case TIMES:
  631.       *v1 = *v1 * v2;
  632.       break;
  633.     case DIVIDE:
  634.       if (v2 == 0)
  635.         return DIVIDE_ZERO;
  636.       else
  637.         *v1 = *v1 / v2;
  638.       break;
  639.     case MODULO:
  640.       if (v2 == 0)
  641.         return MODULO_ZERO;
  642.       else
  643.         *v1 = *v1 % v2;
  644.       break;
  645.     default:
  646.       internal_error ("Bad operator in mult_term ()");
  647.       break;
  648.     }
  649.     }
  650.   if (op == ERROR)
  651.     return UNKNOWN_INPUT;
  652.  
  653.   eval_undo ();
  654.   return NO_ERROR;
  655. }
  656.  
  657. static eval_error
  658. exp_term (eval_token et, int *v1)
  659. {
  660.   register int result;
  661.   int v2;
  662.   eval_error er;
  663.  
  664.   if ((er = unary_term (et, v1)) != NO_ERROR)
  665.     return er;
  666.   result = *v1;
  667.  
  668.   while ((et = eval_lex (&v2)) == EXPONENT)
  669.     {
  670.       et = eval_lex (&v2);
  671.       if (et == ERROR)
  672.     return UNKNOWN_INPUT;
  673.  
  674.       if ((er = exp_term (et, &v2)) != NO_ERROR)
  675.     return er;
  676.  
  677.       result = 1;
  678.       while (v2-- > 0)
  679.     result *= *v1;
  680.       *v1 = result;
  681.     }
  682.   if (et == ERROR)
  683.     return UNKNOWN_INPUT;
  684.  
  685.   eval_undo ();
  686.   return NO_ERROR;
  687. }
  688.  
  689. static eval_error
  690. unary_term (eval_token et, int *v1)
  691. {
  692.   eval_token et2 = et;
  693.   eval_error er;
  694.  
  695.   if (et == PLUS || et == MINUS)
  696.     {
  697.       et2 = eval_lex (v1);
  698.       if (et2 == ERROR)
  699.     return UNKNOWN_INPUT;
  700.  
  701.       if ((er = simple_term (et2, v1)) != NO_ERROR)
  702.     return er;
  703.  
  704.       if (et == MINUS)
  705.     *v1 = -*v1;
  706.     }
  707.   else
  708.     if ((er = simple_term (et, v1)) != NO_ERROR)
  709.       return er;
  710.  
  711.   return NO_ERROR;
  712. }
  713.  
  714. static eval_error
  715. simple_term (eval_token et, int *v1)
  716. {
  717.   int v2;
  718.   eval_error er;
  719.  
  720.   switch (et)
  721.     {
  722.     case LEFTP:
  723.       et = eval_lex (v1);
  724.       if (et == ERROR)
  725.     return UNKNOWN_INPUT;
  726.  
  727.       if ((er = logical_or_term (et, v1)) != NO_ERROR)
  728.     return er;
  729.  
  730.       et = eval_lex (&v2);
  731.       if (et == ERROR)
  732.     return UNKNOWN_INPUT;
  733.  
  734.       if (et != RIGHTP)
  735.     return MISSING_RIGHT;
  736.  
  737.       break;
  738.     case NUMBER:
  739.       break;
  740.     default:
  741.       return SYNTAX_ERROR;
  742.     }
  743.   return NO_ERROR;
  744. }
  745.