home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / calculat / meval113.zip / SRC / ETABLE.C < prev    next >
Text File  |  1993-04-11  |  5KB  |  197 lines

  1. /*
  2. **
  3. ** ETABLE.C    Manipulates a table of tokens.
  4. **
  5. ** Originally written 6/89 in ANSI C
  6. **
  7. ** Eval is a floating point expression evaluator.
  8. ** This file last updated in version 1.10
  9. ** For the version number, see eval.h
  10. ** Copyright (C) 1993  Will Menninger
  11. **
  12. ** This program is free software; you can redistribute it and/or modify it
  13. ** under the terms of the GNU General Public License as published by the
  14. ** Free Software Foundation; either version 2 of the License, or any
  15. ** later version.
  16. **
  17. ** This program is distributed in the hope that it will be useful, but
  18. ** WITHOUT ANY WARRANTY; without even the implied warranty of
  19. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  20. ** General Public License for more details.
  21. **
  22. ** You should have received a copy of the GNU General Public License along
  23. ** with this program; if not, write to the Free Software Foundation, Inc.,
  24. ** 675 Mass Ave, Cambridge, MA 02139, USA.
  25. **
  26. ** The author until 9/93 can be contacted at:
  27. ** e-mail:     willus@ilm.pfc.mit.edu
  28. ** U.S. mail:  Will Menninger, 45 River St., #2, Boston, MA 02108-1124
  29. **
  30. **
  31. */
  32.  
  33. #include   "eval.h"
  34.  
  35. static    TOKEN    ttable[MAXINPUT+1];
  36. static    int    ttp;
  37.  
  38. static BOOLEAN is_operator (int type);
  39. #ifdef DEBUG
  40. static void    print_table (void);
  41. #endif
  42.  
  43. void clear_table(void)
  44.  
  45.     {
  46.     ttp=0;
  47.     }
  48.  
  49.  
  50. BOOLEAN add_token(TOKENPTR t)
  51.  
  52.     {
  53.     if (ttp>MAXINPUT)
  54.     {
  55.     printf("Out of expression table space.\n");
  56.     return(0);
  57.     }
  58.     tokcpy(&ttable[ttp],t);
  59.     ttp++;
  60.     return(1);
  61.     }
  62.  
  63.  
  64. BOOLEAN table_value(double *ret_val)
  65.  
  66.     {
  67.     int     i,j,k,nargs,max;
  68.     double  args[MAXARGS];
  69.  
  70.     max=ttp;
  71.     while (ttp>1)
  72.     {
  73.     for (i=0;i<max && !is_operator((int)ttable[i].type);i++);
  74.     if (i==max)
  75.         return(eerror("Expression table lacking in operators."));
  76.     if (ttable[i].type==UNARY)
  77.         nargs=1;
  78.     else if (ttable[i].type==BINARY)
  79.         nargs=2;
  80.     else
  81.         nargs=func_nargs(ttable[i].code);
  82.     if (nargs>MAXARGS)
  83.         return(eerror("Maximum number of function arguments exceeded."));
  84.     for (j=i,k=nargs-1;k>=0;k--)
  85.         {
  86.         for (j--;j>=0 && ttable[j].type==VOID;j--);
  87.         if (j<0)
  88.         return(eerror("Expression table lacking in arguments."));
  89.         args[k]=ttable[j].value;
  90.         ttable[j].type=VOID;
  91.         ttp--;
  92.         }
  93.     if (!result((int)ttable[i].type,ttable[i].code,args,&ttable[i].value))
  94.         return(0);
  95.     ttable[i].type=NUMBER;
  96.     }
  97.     if (ttp!=1)
  98.     return(eerror("Expression table unexpectedly empty."));
  99.     for (i=0;i<max && ttable[i].type==VOID;i++);
  100.     if (i==max)
  101.     return(eerror("Internal inconsistency error."));
  102.     if (is_operator((int)ttable[i].type))
  103.     return(eerror("Final expression table result is not a number."));
  104.     (*ret_val)=ttable[i].value;
  105.     return(1);
  106.     }
  107.  
  108.  
  109. BOOLEAN result(int type,int code,double *args,double *ret_val)
  110.  
  111.     {
  112.     switch (type)
  113.     {
  114.     case BINARY:
  115.         switch (code)
  116.         {
  117.         case ADD:
  118.             (*ret_val)=args[0]+args[1];
  119.             return(1);
  120.         case SUBTRACT:
  121.             (*ret_val)=args[0]-args[1];
  122.             return(1);
  123.         case DIVIDE:
  124.         case MOD:
  125.             if (args[1]==0.)
  126.             return(eerror("Divide by zero in expression."));
  127.             if (code==DIVIDE)
  128.             (*ret_val)=args[0]/args[1];
  129.             else
  130.             (*ret_val)=args[1]*(args[0]/args[1]
  131.                         -(int)(args[0]/args[1]));
  132.             return(1);
  133.         case MULTIPLY:
  134.             (*ret_val)=args[0]*args[1];
  135.             return(1);
  136.         case POWER:
  137.             if (args[0]==0. && args[1]<0)
  138.             return(eerror("Cannot raise zero to a negative power."));
  139.             if (args[0]<0 && args[1]!=((int)args[1]))
  140.             return(eerror("Cannot raise a negative number to "
  141.                       "a non-integer power."));
  142.             (*ret_val)=pow(args[0],args[1]);
  143.             return(1);
  144.         case OR:
  145.             (*ret_val)=or(args[0],args[1]);
  146.             return(1);
  147.         case AND:
  148.             (*ret_val)=and(args[0],args[1]);
  149.             return(1);
  150.         case XOR:
  151.             (*ret_val)=xor(args[0],args[1]);
  152.             return(1);
  153.         case SHRIGHT:
  154.             (*ret_val)=args[0]*pow(2.,-args[1]);
  155.             return(1);
  156.         case SHLEFT:
  157.             (*ret_val)=args[0]*pow(2.,args[1]);
  158.             return(1);
  159.         }
  160.         break;
  161.     case UNARY:
  162.         (*ret_val)=(code==POSITIVE) ? args[0] :
  163.                (code==NEGATIVE ? -args[0] : not(args[0]));
  164.         return(1);
  165.     case FUNCTION:
  166.         return(func_eval(code,args,ret_val));
  167.     }
  168.     return(0);
  169.     }
  170.  
  171.  
  172. static BOOLEAN is_operator(int type)
  173.  
  174.     {
  175.     return(type==BINARY || type==UNARY || type==FUNCTION);
  176.     }
  177.  
  178.  
  179. #ifdef DEBUG
  180. static void print_table(void)
  181.  
  182.     {
  183.     int     i;
  184.  
  185.     for (i=0;i<ttp;i++)
  186.     {
  187.     printf("(%d,",ttable[i].type);
  188.     if (ttable[i].type==NUMBER || ttable[i].type==CONSTANT ||
  189.         ttable[i].type==VARIABLE || ttable[i].type==QUOTE)
  190.         printf("%g) ",ttable[i].value);
  191.     else
  192.         printf("%d) ",ttable[i].code);
  193.     }
  194.     printf("\n");
  195.     }
  196. #endif
  197.