|
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 ); }