|
|
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 f
Length: 9436 (0x24dc)
Types: TextFile
Names: »fundeclr.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec1/graph/fundeclr.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 "graph.h"
#include "y.tab.h"
#include "math.h"
extern double eval ();
extern table_st *eval_tab ();
extern double min_fun ();
extern double max_fun ();
extern double sum_fun ();
extern double count_fun ();
extern double average_fun ();
#define MIN_FUN ((attr_st *)2)
#define MAX_FUN ((attr_st *)3)
#define SUM_FUN ((attr_st *)4)
#define COUNT_FUN ((attr_st *)5)
#define AVERAGE_FUN ((attr_st *)6)
#define LOG_FUN ((attr_st *)7)
#define LN_FUN ((attr_st *)8)
#define EXP_FUN ((attr_st *)9)
#define POWER_FUN ((attr_st *)10)
#define SQRT_FUN ((attr_st *)11)
#define FLOOR_FUN ((attr_st *)12)
#define CEIL_FUN ((attr_st *)13)
#define ABS_FUN ((attr_st *)14)
#define SIN_FUN ((attr_st *)15)
#define COS_FUN ((attr_st *)16)
#define ASIN_FUN ((attr_st *)17)
#define ACOS_FUN ((attr_st *)18)
#define ATAN_FUN ((attr_st *)19)
#define ATAN2_FUN ((attr_st *)20)
#define SINH_FUN ((attr_st *)21)
#define COSH_FUN ((attr_st *)22)
#define TANH_FUN ((attr_st *)23)
#define HYPOT_FUN ((attr_st *)24)
#define J0_FUN ((attr_st *)26)
#define J1_FUN ((attr_st *)27)
#define JN_FUN ((attr_st *)28)
#define Y0_FUN ((attr_st *)29)
#define Y1_FUN ((attr_st *)30)
#define YN_FUN ((attr_st *)31)
#define MAX_DEC 50
static struct declare_st {
char *name;
parm_st *parm_list;
attr_st *expr;
tnode_st *tab_expr;
} dec [ MAX_DEC ];
static int num_dec;
pdef_fun ()
{
static parm_st ptab;
static parm_st pexpr1 , pexpr2;
ptab.parm_type = TABLE;
ptab.ident = "";
ptab.next = NULL;
pexpr1.parm_type = VALUE;
pexpr1.ident = "";
pexpr1.next = NULL;
pexpr2.parm_type = VALUE;
pexpr2.ident = "";
pexpr2.next = &pexpr1;
fun_declare ( "min" , &ptab , MIN_FUN , NULL );
fun_declare ( "max" , &ptab , MAX_FUN , NULL );
fun_declare ( "sum" , &ptab , SUM_FUN , NULL );
fun_declare ( "count" , &ptab , COUNT_FUN , NULL );
fun_declare ( "average" , &ptab , AVERAGE_FUN , NULL );
fun_declare ( "sqrt" , &pexpr1 , SQRT_FUN , NULL );
fun_declare ( "log" , &pexpr1 , LOG_FUN , NULL );
fun_declare ( "ln" , &pexpr1 , LN_FUN , NULL );
fun_declare ( "exp" , &pexpr1 , EXP_FUN , NULL );
fun_declare ( "pow" , &pexpr2 , POWER_FUN , NULL );
fun_declare ( "floor" , &pexpr1 , FLOOR_FUN , NULL );
fun_declare ( "ceil" , &pexpr1 , CEIL_FUN , NULL );
fun_declare ( "abs" , &pexpr1 , ABS_FUN , NULL );
fun_declare ( "sin" , &pexpr1 , SIN_FUN , NULL );
fun_declare ( "cos" , &pexpr1 , COS_FUN , NULL );
fun_declare ( "asin" , &pexpr1 , ASIN_FUN , NULL );
fun_declare ( "acos" , &pexpr1 , ACOS_FUN , NULL );
fun_declare ( "atan" , &pexpr1 , ATAN_FUN , NULL );
fun_declare ( "atan2" , &pexpr2 , ATAN2_FUN , NULL );
fun_declare ( "sinh" , &pexpr1 , SINH_FUN , NULL );
fun_declare ( "cosh" , &pexpr1 , COSH_FUN , NULL );
fun_declare ( "tanh" , &pexpr1 , TANH_FUN , NULL );
fun_declare ( "hypot" , &pexpr2 , HYPOT_FUN , NULL );
fun_declare ( "j0" , &pexpr1 , J0_FUN , NULL );
fun_declare ( "j1" , &pexpr1 , J1_FUN , NULL );
fun_declare ( "jn" , &pexpr2 , JN_FUN , NULL );
fun_declare ( "y0" , &pexpr1 , Y0_FUN , NULL );
fun_declare ( "y1" , &pexpr1 , Y1_FUN , NULL );
fun_declare ( "yn" , &pexpr2 , YN_FUN , NULL );
}
fun_declare ( name , parm_list , expr , tab_expr )
char *name;
parm_st *parm_list;
attr_st *expr;
tnode_st *tab_expr;
{
int i;
for ( i = 0; i < num_dec; i++ ) {
if ( strcmp ( name , dec[i].name ) == 0 ) {
abort ( "cannot redeclare functions: '%s'" , name );
return;
}
}
if ( num_dec >= MAX_DEC )
abort ( "Internal array overflow - too many functions declared" );
dec[num_dec].name = name;
dec[num_dec].parm_list = parm_list;
dec[num_dec].expr = expr;
dec[num_dec].tab_expr = tab_expr;
num_dec++;
}
double
call_var_fun ( name , parm_list , table , row )
char *name;
parm_st *parm_list;
table_st *table;
int row;
{
int i;
double value;
parm_st *p1 , *p2;
#define MAX_TAB 3
#define MAX_VAR 3
table_st *tab_parm[ MAX_TAB ];
double var_parm[ MAX_VAR ];
int tab_num , var_num;
for ( i = 0; i < num_dec; i++ ) {
if ( strcmp ( dec[i].name , name ) == 0 ) {
if ( dec[i].expr == NULL )
abort ( "value function with no expression found" );
p1 = parm_list;
p2 = dec[i].parm_list;
var_num = 0;
tab_num = 0;
while ( p1 != NULL && p2 != NULL ) {
if ( p1->parm_type != p2->parm_type )
abort ( "type mismatch for parameter to function '%s'" , name );
if ( p1->parm_type == TABLE ) {
tab_parm[ tab_num ] = eval_tab ( p1->tab_expr );
tab_declare ( p2->ident , tab_parm[ tab_num ] );
if ( tab_num + 1 < MAX_TAB )
tab_num++;
}
else {
var_parm[ var_num ] = eval ( table , row , p1->expr );
var_declare ( p2->ident , var_parm[ var_num ] );
if ( var_num + 1 < MAX_VAR )
var_num++;
}
p1 = p1->next;
p2 = p2->next;
}
if ( p1 != NULL || p2 != NULL )
abort ( "illegal parameter list for function '%s'" , name );
switch ( dec[i].expr ) {
case MIN_FUN :
value = min_fun ( tab_parm[0] , 0 , tab_parm[0]->size );
break;
case MAX_FUN :
value = max_fun ( tab_parm[0] , 0 , tab_parm[0]->size );
break;
case SUM_FUN :
value = sum_fun ( tab_parm[0] , 0 , tab_parm[0]->size );
break;
case COUNT_FUN :
value = count_fun ( tab_parm[0] , 0 , tab_parm[0]->size );
break;
case AVERAGE_FUN :
value = average_fun ( tab_parm[0] , 0 , tab_parm[0]->size );
break;
case LOG_FUN :
value = log10 ( var_parm[0] );
break;
case LN_FUN :
value = log ( var_parm[0] );
break;
case EXP_FUN :
value = exp ( var_parm[0] );
break;
case POWER_FUN :
value = pow ( var_parm[0] , var_parm[1] );
break;
case SQRT_FUN :
value = sqrt ( var_parm[0] );
break;
case FLOOR_FUN :
value = floor ( var_parm[0] );
break;
case CEIL_FUN :
value = ceil ( var_parm[0] );
break;
case ABS_FUN :
value = fabs ( var_parm[0] );
break;
case SIN_FUN :
value = sin ( var_parm[0] );
break;
case COS_FUN :
value = cos ( var_parm[0] );
break;
case ASIN_FUN :
value = asin ( var_parm[0] );
break;
case ACOS_FUN :
value = acos ( var_parm[0] );
break;
case ATAN_FUN :
value = atan ( var_parm[0] );
break;
case ATAN2_FUN :
value = atan2 ( var_parm[0] , var_parm[1] );
break;
case SINH_FUN :
value = sinh ( var_parm[0] );
break;
case COSH_FUN :
value = cosh ( var_parm[0] );
break;
case TANH_FUN :
value = tanh ( var_parm[0] );
break;
case HYPOT_FUN :
value = hypot ( var_parm[0] , var_parm[1] );
break;
case J0_FUN :
value = sin ( var_parm[0] );
break;
case J1_FUN :
value = j1 ( var_parm[0] );
break;
case JN_FUN :
value = jn ( var_parm[0] );
break;
case Y0_FUN :
value = y0 ( var_parm[0] );
break;
case Y1_FUN :
value = y1 ( var_parm[0] );
break;
case YN_FUN :
value = yn ( var_parm[0] );
break;
default :
value = eval ( table , row , dec[i].expr );
break;
}
return ( value );
}
}
abort ( "Undefined function '%s' referenced" , name );
}
table_st *
call_tab_fun ( name , parm_list , table , row )
char *name;
parm_st *parm_list;
table_st *table;
int row;
{
int i;
table_st *newtab;
parm_st *p1 , *p2;
for ( i = 0; i < num_dec; i++ ) {
if ( strcmp ( dec[i].name , name ) == 0 ) {
if ( dec[i].tab_expr == NULL )
abort ( "table function with no expression found" );
p1 = parm_list;
p2 = dec[i].parm_list;
while ( p1 != NULL && p2 != NULL ) {
if ( p1->parm_type != p2->parm_type )
abort ( "type mismatch for parameter to function '%s'" , name );
if ( p1->parm_type == TABLE )
tab_declare ( p2->ident , eval_tab ( p1->tab_expr ) );
else
var_declare ( p2->ident , eval ( table , row , p1->expr ) );
p1 = p1->next;
p2 = p2->next;
}
if ( p1 != NULL || p2 != NULL )
abort ( "illegal parameter list for function '%s'" , name );
newtab = eval_tab ( dec[i].tab_expr );
return ( newtab );
}
}
abort ( "Undefined function '%s' referenced" , name );
}
is_fvar_ident ( name )
char *name;
{
int i;
for ( i = 0; i < num_dec; i++ ) {
if ( strcmp ( dec[i].name , name ) == 0 ) {
return ( dec[i].expr != NULL );
}
}
return ( 0 );
}
is_ftab_ident ( name )
char *name;
{
int i;
for ( i = 0; i < num_dec; i++ ) {
if ( strcmp ( dec[i].name , name ) == 0 ) {
return ( dec[i].expr == NULL );
}
}
return ( 0 );
}
check_group_fun ( name )
char *name;
{
int i;
for ( i = 0; i < num_dec; i++ ) {
if ( strcmp ( dec[i].name , name ) == 0 ) {
if ( dec[i].expr == NULL )
abort ( "function '%s' must return a value" , name );
if ( dec[i].parm_list == NULL
|| dec[i].parm_list->next != NULL
|| dec[i].parm_list->parm_type != TABLE )
abort ( "function '%s' expects a single table as parameters" );
return;
}
}
}