DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T e

⟦d306b6f14⟧ TextFile

    Length: 3653 (0xe45)
    Types: TextFile
    Names: »eval.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/graph/eval.c« 

TextFile

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