home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume8 / graph+ / part02 / eval.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-03-01  |  3.6 KB  |  174 lines

  1. /*
  2.  * Copyright (C) 1986   Alan Kent
  3.  *
  4.  * Permission is granted to freely distribute part or
  5.  * all of this code as long as it is not for profit
  6.  * and this message is retained in the code.
  7.  *
  8.  * No resposibility is taken for any damage or incorect
  9.  * results this program generates.
  10.  * 
  11.  */
  12.  
  13.  
  14. #include <stdio.h>
  15. #include <math.h>
  16. #include "graph.h"
  17. #include "y.tab.h"
  18.  
  19.  
  20. extern double var_lookup ();
  21. extern double call_var_fun ();
  22.  
  23.  
  24. /* evaluate an expression tree */
  25.  
  26. double
  27. eval ( table , row , expr )
  28. register table_st *table;
  29. register int row;
  30. register attr_st *expr;
  31. {
  32.     register table_st *tp;
  33.     register int i;
  34.     int intval;
  35.     double value;
  36.     double val1 , val2;
  37.  
  38.  
  39.     if ( expr == NULL )
  40.     return ( 0.0 );
  41.  
  42.     switch ( expr->node_type ) {
  43.  
  44.     case PLUS :
  45.     value = eval ( table , row , expr->left )
  46.     + eval ( table , row , expr->right );
  47.     break;
  48.  
  49.     case MINUS :
  50.     value = ( eval ( table , row , expr->left )
  51.     - eval ( table , row , expr->right ) );
  52.     break;
  53.  
  54.     case MULTIPLY :
  55.     value = ( eval ( table , row , expr->left )
  56.     * eval ( table , row , expr->right ) );
  57.     break;
  58.  
  59.     case DIVIDE :
  60.     val1 = eval ( table , row , expr->left );
  61.     val2 =  eval ( table , row , expr->right );
  62.     if ( val2 == 0.0 ) {
  63.         value = HUGE;
  64.         warn ( "division by zero error" );
  65.     }
  66.     else
  67.         value = val1 / val2;
  68.     break;
  69.  
  70.     case MODULUS :
  71.     val1 = eval ( table , row , expr->left );
  72.     val2 = eval ( table , row , expr->right );
  73.     if ( val2 == 0.0 ) {
  74.         value = 0.0;
  75.         warn ( "modulus by zero error" );
  76.     }
  77.     else {
  78.         while ( val1 > val2 )    /* % does not work with float's */
  79.         val1 -= val2;
  80.         while ( val1 < 0.0 )
  81.         val1 += val2;
  82.         value = val1;
  83.     }
  84.     break;
  85.  
  86.     case LE :
  87.     value = ( eval ( table , row , expr->left )
  88.     <= eval ( table , row , expr->right ) );
  89.     break;
  90.  
  91.     case LT :
  92.     value = ( eval ( table , row , expr->left )
  93.     < eval ( table , row , expr->right ) );
  94.     break;
  95.  
  96.     case GE :
  97.     value = ( eval ( table , row , expr->left )
  98.     >= eval ( table , row , expr->right ) );
  99.     break;
  100.  
  101.     case GT :
  102.     value = ( eval ( table , row , expr->left )
  103.     > eval ( table , row , expr->right ) );
  104.     break;
  105.  
  106.     case EQ :
  107.     value = ( eval ( table , row , expr->left )
  108.     == eval ( table , row , expr->right ) );
  109.     break;
  110.  
  111.     case NE :
  112.     value = ( eval ( table , row , expr->left )
  113.     != eval ( table , row , expr->right ) );
  114.     break;
  115.  
  116.     case QUEST :
  117.     value = ( eval ( table , row , expr->left ) != 0.0 )
  118.         ? eval ( table , row , expr->right->left )
  119.         : eval ( table , row , expr->right->right );
  120.     break;
  121.  
  122.     case AND :
  123.     value = ( eval ( table , row , expr->left )
  124.     && eval ( table , row , expr->right ) );
  125.     break;
  126.  
  127.     case OR :
  128.     value = ( eval ( table , row , expr->left )
  129.     || eval ( table , row , expr->right ) );
  130.     break;
  131.  
  132.     case NOT :
  133.     value = ( eval ( table , row , expr->left ) == 0.0 );
  134.     break;
  135.  
  136.     case NEG :
  137.     value = ( - eval ( table , row , expr->left ) );
  138.     break;
  139.  
  140.     case FVAR_IDENT :
  141.     value = call_var_fun ( expr->ident , expr->parm_list , table , row );
  142.     break;
  143.  
  144.     case VAR_IDENT :
  145.     value = var_lookup ( expr->ident );
  146.     break;
  147.  
  148.     case NUMBER :
  149.     value = ( expr->value );
  150.     break;
  151.  
  152.     case ATTR :
  153.     intval = (int) eval ( table , row , expr->left );
  154.     if ( intval == 0 )
  155.         value = row + 1.0;
  156.     else {
  157.         for ( i = 1 , tp = table; tp != NULL  &&  i < intval; i++ , tp = tp->next )
  158.         ;
  159.         if ( tp == NULL )
  160.         abort ( "Illegal attribute number selected from table" );
  161.         if ( row >= tp->size )
  162.         abort ( "Internal error - accessing past end of array in eval()" );
  163.         value = ( tp->data[row] );
  164.     }
  165.     break;
  166.  
  167.     default :
  168.     value = 0.0;
  169.     abort ( "Unknown operator in eval() = %d" , expr->node_type );
  170.     }
  171.     return ( value );
  172. }
  173.  
  174.