|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T e
Length: 3653 (0xe45)
Types: TextFile
Names: »eval.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec1/graph/eval.c«
/*
* 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 );
}