home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / misc / eval / source / src.lha / etable.c < prev    next >
C/C++ Source or Header  |  1993-04-13  |  6KB  |  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.