home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1986 Alan Kent
- *
- * Permission is granted to freely distribute part or
- * all of this code as long as it is not for profit
- * and this message is retained in the code.
- *
- * No resposibility is taken for any damage or incorect
- * results this program generates.
- *
- */
-
-
- #include <stdio.h>
- #include <math.h>
- #include "graph.h"
- #include "y.tab.h"
-
-
- extern double var_lookup ();
- extern double call_var_fun ();
-
-
- /* evaluate an expression tree */
-
- double
- eval ( table , row , expr )
- register table_st *table;
- register int row;
- register attr_st *expr;
- {
- register table_st *tp;
- register int i;
- int intval;
- double value;
- double val1 , val2;
-
-
- if ( expr == NULL )
- return ( 0.0 );
-
- switch ( expr->node_type ) {
-
- case PLUS :
- value = eval ( table , row , expr->left )
- + eval ( table , row , expr->right );
- break;
-
- case MINUS :
- value = ( eval ( table , row , expr->left )
- - eval ( table , row , expr->right ) );
- break;
-
- case MULTIPLY :
- value = ( eval ( table , row , expr->left )
- * eval ( table , row , expr->right ) );
- break;
-
- case DIVIDE :
- val1 = eval ( table , row , expr->left );
- val2 = eval ( table , row , expr->right );
- if ( val2 == 0.0 ) {
- value = HUGE;
- warn ( "division by zero error" );
- }
- else
- value = val1 / val2;
- break;
-
- case MODULUS :
- val1 = eval ( table , row , expr->left );
- val2 = eval ( table , row , expr->right );
- if ( val2 == 0.0 ) {
- value = 0.0;
- warn ( "modulus by zero error" );
- }
- else {
- while ( val1 > val2 ) /* % does not work with float's */
- val1 -= val2;
- while ( val1 < 0.0 )
- val1 += val2;
- value = val1;
- }
- break;
-
- case LE :
- value = ( eval ( table , row , expr->left )
- <= eval ( table , row , expr->right ) );
- break;
-
- case LT :
- value = ( eval ( table , row , expr->left )
- < eval ( table , row , expr->right ) );
- break;
-
- case GE :
- value = ( eval ( table , row , expr->left )
- >= eval ( table , row , expr->right ) );
- break;
-
- case GT :
- value = ( eval ( table , row , expr->left )
- > eval ( table , row , expr->right ) );
- break;
-
- case EQ :
- value = ( eval ( table , row , expr->left )
- == eval ( table , row , expr->right ) );
- break;
-
- case NE :
- value = ( eval ( table , row , expr->left )
- != eval ( table , row , expr->right ) );
- break;
-
- case QUEST :
- value = ( eval ( table , row , expr->left ) != 0.0 )
- ? eval ( table , row , expr->right->left )
- : eval ( table , row , expr->right->right );
- break;
-
- case AND :
- value = ( eval ( table , row , expr->left )
- && eval ( table , row , expr->right ) );
- break;
-
- case OR :
- value = ( eval ( table , row , expr->left )
- || eval ( table , row , expr->right ) );
- break;
-
- case NOT :
- value = ( eval ( table , row , expr->left ) == 0.0 );
- break;
-
- case NEG :
- value = ( - eval ( table , row , expr->left ) );
- break;
-
- case FVAR_IDENT :
- value = call_var_fun ( expr->ident , expr->parm_list , table , row );
- break;
-
- case VAR_IDENT :
- value = var_lookup ( expr->ident );
- break;
-
- case NUMBER :
- value = ( expr->value );
- break;
-
- case ATTR :
- intval = (int) eval ( table , row , expr->left );
- if ( intval == 0 )
- value = row + 1.0;
- else {
- for ( i = 1 , tp = table; tp != NULL && i < intval; i++ , tp = tp->next )
- ;
- if ( tp == NULL )
- abort ( "Illegal attribute number selected from table" );
- if ( row >= tp->size )
- abort ( "Internal error - accessing past end of array in eval()" );
- value = ( tp->data[row] );
- }
- break;
-
- default :
- value = 0.0;
- abort ( "Unknown operator in eval() = %d" , expr->node_type );
- }
- return ( value );
- }
-
-