home *** CD-ROM | disk | FTP | other *** search
- /*********************************************************
- *
- * Copyright (c) 1993 Ke Jin
- *
- * Permission to use, copy, modify, and distribute
- * this software and its documentation without fee
- * is granted, provided that the author's name and
- * this copyright notice are retained.
- *
- * -----------------------------------------------------
- *
- * defunc.c -- defunc high level module
- *
- * public function : dfopen();
- * dfclose();
- * dfcloseall();
- *
- * private function : getfreehdl();
- * tdfopen();
- * getexprbody();
- * getexprname();
- * getexprset();
- * isfnctexpr();
- *
- * brkbalance();
- *
- * hdl00() to hdl31();
- *
- * private variable : tr_arr[];
- * : hdl_arr[];
- *
- *********************************************************/
-
- #include <stdio.h>
- #include <malloc.h>
- #include <ctype.h>
- #include <string.h>
-
- #include "dfctree.h"
- #include "dfcsymtable.h"
- #include "defunc.h"
-
- #ifdef __cplusplus /* for c++ */
- extern "C" {
- #endif
-
- #define MAXHANDLE 32
-
- typedef Node* Tree;
- typedef double (*FP)();
-
- #if NeedFunctionPrototypes
- static Tree tr_arr[MAXHANDLE]; /* predeclare static member */
- static FP hdl_arr[MAXHANDLE]; /* predeclare static member */
- static char* getexprbody(char* inputstr);
- static char* getexprname(char* inputstr);
- static char* getarguset(char* inputstr, int argidx);
- static int isfnctexpr(char* inputstr);
- static int brkbalance(char* inputstr);
- #else
- extern Tree tr_arr[MAXHANDLE]; /* predeclare static member */
- extern FP hdl_arr[MAXHANDLE]; /* predeclare static member */
- extern char* getexprbody();
- extern char* getexprname();
- extern char* getarguset();
- extern int isfnctexpr();
- extern int brkbalance();
- #endif /* predeclare private function */
-
- #if NeedFunctionPrototypes
- static int getfreehdl(void)
- #else
- static int getfreehdl()
- #endif
- /* return the index of free handle on success. return -1 on fail */
- {
- int i;
-
- for(i=0;i<MAXHANDLE;i++)
- {
- if(tr_arr[i]==(Node*)0) return i;
- }
-
- return -1; /* if no free handle */
- };
-
- #if NeedFunctionPrototypes
- static double (*tdfopen(char* exprbody))(double x, double y)
- #else
- static double (*tdfopen(exprbody))()
- char* exprbody;
- #endif
- /* Only accept expression body. Return handle function or NULL */
- {
- int i, size;
-
- if(brkbalance(exprbody)!=0)
- {
- exparserror = "unbalanced ( ) in expression";
- return 0;
- }
-
- if((i=getfreehdl())==-1) return 0; /* no free handle */
-
- size = exparse(exprbody);
- if(size<=0) return 0;
-
- tr_arr[i] = (Node*)malloc(sizeof(Node)*size);
- if(tr_arr[i]==0)
- {
- exparserror = "fail to alloc memory for new parse tree";
- return 0;
- }
-
- getparsetree(tr_arr[i]);
- reduce(tr_arr[i], 0);
-
- return hdl_arr[i];
- };
-
- #if NeedFunctionPrototypes
- double (*dfopen(char* expr))(double x, double y)
- #else
- double (*dfopen(expr))()
- char* expr;
- #endif
- /* Accept full expression as well as expression
- * body. Return handle function or NULL */
- {
- double (*fnctptr)();
-
- char* exprbody;
- char* exprname;
- char *arg1, *arg2;
-
- exparserror = 0;
- if(brkbalance(expr)!=0)
- {
- exparserror = "unbalanced ( ) in expression";
- return 0;
- }
-
- exprbody = getexprbody(expr);
- exprname = getexprname(expr);
- arg1 = getarguset(expr, 1);
- arg2 = getarguset(expr, 2);
-
- if(nameargu(arg1, arg2)==-1)
- {
- exparserror = "error on reset argument";
- return 0;
- }
-
- fnctptr = tdfopen(exprbody);
-
- if(exprname!=0)
- {
- if(arg1!=0||isfnctexpr(expr))
- {
- namefnct(exprname, fnctptr);
- }
- else if(fnctptr!=0)
- {
- namecnst(exprname, fnctptr());
- }
- }
-
- return fnctptr;
- };
-
- #if NeedFunctionPrototypes
- int dfclose(double (*fnctptr)())
- #else
- int dfclose(fnctptr)
- double (*fnctptr)();
- #endif
- /* close a dynamic function(getten from dfopen) if it not on
- * the global name-function association table. On success,
- * return 0. On fail return -1
- */
- {
- int i;
- if(getsym(getfnctname(fnctptr))!=0) return -1;
- /* function still on symbol table can't be closed */
-
- for(i=0;i<MAXHANDLE;i++)
- {
- if(fnctptr==hdl_arr[i])
- {
- if(tr_arr[i]!=0) free(tr_arr[i]);
- tr_arr[i]=0;
- return 0; /* success */
- }
- }
-
- return -1; /* fail to close */
- };
-
- #if NeedFunctionPrototypes
- int dfcloseall(void)
- #else
- int dfcloseall()
- #endif
- /* close all (not on the association table) dynamic functions
- * Return the total number of handler freed by this calling.
- */
- {
- int i, j;
-
- for(i=0, j=0; i<MAXHANDLE; i++)
- {
- if(tr_arr[i]!=0) /* unfreed handle */
- {
- if(dfclose(hdl_arr[i])==0) /* success */
- {
- tr_arr[i]=0;
- j++;
- }
- }
- }
-
- return j;
- };
-
- #if NeedFunctionPrototypes
- static char* getexprbody(char* str)
- #else
- static char* getexprbody(str)
- char* str;
- #endif
- /* extract the expression body from an input string */
- {
- int i;
-
- for(i=0;i<strlen(str);i++)
- {
- if(str[i]=='=') return str+i+1;
- /* found '=' in str, substring after '=' be returned */
-
- }
-
- return str; /* no '=' be found, then return str itself */
- };
-
- #if NeedFunctionPrototypes
- static char* getexprname(char* str)
- #else
- static char* getexprname(str)
- char* str;
- #endif
- /* extract the expression title from an input string */
- {
- int i, j=0, len;
- static char* name;
-
- for(i=0; i<strlen(str);i++)
- {
- if(str[i]=='=') break;
- /* if no '=' be found, then it's a anonymous expression */
- }
- if(i==strlen(str)) return 0;
-
- len = i;
-
- name = (char*)malloc(len*sizeof(char));
- if(name == 0)
- {
- perror("malloc in getarguset()");
- exit(1);
- }
-
- for(i=0; i<len; i++)
- {
- if(isalnum(str[i]))
- {
- name[j] = str[i];
- j++;
- }
- else break;
- }
-
- name[j]= '\0';
- if(strlen(name)==0) return 0;
- return name;
- };
-
- #if NeedFunctionPrototypes
- static char* getarguset(char* str, int argidx)
- #else
- static char* getarguset(str, argidx)
- char* str;
- int argidx;
- #endif
- /* extract an argument name from input string */
- {
- int i, j=0, len;
- char c;
- static char *name1;
- static char *name2;
-
- for(i=0; i<strlen(str); i++)
- {
- if(str[i]=='=') break;
- /* if no '=' be found, then it's a anonymous expression */
- }
- if(i==strlen(str)) return 0;
- len=i;
- /* len is the length of substring (those part in front of '=') */
-
- for(i=0; i<len; i++)
- {
- if(argidx==1)
- {
- name1 = (char*)malloc(len*sizeof(char));
- if(name1 == 0)
- {
- perror("malloc in getarguset()");
- exit(1);
- }
-
- if(str[i] == '(') /* skim over the expr name */
- {
- for(i=i+1;i<len;i++)
- {
- c = str[i];
- if(j==0&&(c==' '||c=='\t')) continue;
- if(c!=','&&c!=')'&&c!='='&&c!=' '&&c!='\t')
- {
- name1[j]=c;
- j++;
- }
- else break;
- }
- name1[j]='\0';
- if(strlen(name1)==0) return 0;
- return name1;
- }
- }
-
- if(argidx==2)
- {
- name2 = (char*)malloc(len*sizeof(char));
- if(name2 == 0)
- {
- perror("malloc in getarguset()");
- exit(1);
- }
-
- if(str[i] == ',')
- /* skim over the expr and 1st argu names */
- {
- for(i=i+1;i<len;i++)
- {
- c=str[i];
- if(j==0&&(c==' '||c=='\t')) continue;
- if(c!=','&&c!=')'&&c!='='&&c!=' '&&c!='\t')
- {
- name2[j]=str[i];
- j++;
- }
- else break;
- }
- name2[j]='\0';
- if(strlen(name2)==0) return 0;
- return name2;
- }
- }
- }
-
- return 0;
- };
-
- #if NeedFunctionPrototypes
- static int isfnctexpr(char* expression)
- #else
- static int isfnctexpr(expression)
- char* expression;
- #endif
- /* to see the title is in "name(...)=" form or in "name=" form */
- {
- int i, tag=0;
- char c;
-
- if(expression==0) return 0;
-
- for(i=0; i<strlen(expression); i++)
- {
- c=expression[i];
- if(c=='(') tag=1;
- if(c=='=') return tag;
- }
-
- return tag;
- };
-
- #if NeedFunctionPrototypes
- static int brkbalance(char* expression)
- #else
- static int brkbalance(expression)
- char* expression;
- #endif
- /* check the balance of '(' and ')'. Return 0 on balance */
- {
- int i,j;
- char c;
-
- for(i=0, j=0;i<strlen(expression);i++)
- {
- c = expression[i];
- if(c=='(') j++;
- if(c==')') j--;
- }
-
- return j;
- };
-
- /* ------------------------- private members ------------------------ */
- static Tree tr_arr[MAXHANDLE];
-
- #if NeedFunctionPrototypes
- static double hdl00(double x,double y){return evaluate(tr_arr[ 0],0,x,y);};
- static double hdl01(double x,double y){return evaluate(tr_arr[ 1],0,x,y);};
- static double hdl02(double x,double y){return evaluate(tr_arr[ 2],0,x,y);};
- static double hdl03(double x,double y){return evaluate(tr_arr[ 3],0,x,y);};
- static double hdl04(double x,double y){return evaluate(tr_arr[ 4],0,x,y);};
- static double hdl05(double x,double y){return evaluate(tr_arr[ 5],0,x,y);};
- static double hdl06(double x,double y){return evaluate(tr_arr[ 6],0,x,y);};
- static double hdl07(double x,double y){return evaluate(tr_arr[ 7],0,x,y);};
- static double hdl08(double x,double y){return evaluate(tr_arr[ 8],0,x,y);};
- static double hdl09(double x,double y){return evaluate(tr_arr[ 9],0,x,y);};
- static double hdl10(double x,double y){return evaluate(tr_arr[10],0,x,y);};
- static double hdl11(double x,double y){return evaluate(tr_arr[11],0,x,y);};
- static double hdl12(double x,double y){return evaluate(tr_arr[12],0,x,y);};
- static double hdl13(double x,double y){return evaluate(tr_arr[13],0,x,y);};
- static double hdl14(double x,double y){return evaluate(tr_arr[14],0,x,y);};
- static double hdl15(double x,double y){return evaluate(tr_arr[15],0,x,y);};
- static double hdl16(double x,double y){return evaluate(tr_arr[16],0,x,y);};
- static double hdl17(double x,double y){return evaluate(tr_arr[17],0,x,y);};
- static double hdl18(double x,double y){return evaluate(tr_arr[18],0,x,y);};
- static double hdl19(double x,double y){return evaluate(tr_arr[19],0,x,y);};
- static double hdl20(double x,double y){return evaluate(tr_arr[20],0,x,y);};
- static double hdl21(double x,double y){return evaluate(tr_arr[21],0,x,y);};
- static double hdl22(double x,double y){return evaluate(tr_arr[22],0,x,y);};
- static double hdl23(double x,double y){return evaluate(tr_arr[23],0,x,y);};
- static double hdl24(double x,double y){return evaluate(tr_arr[24],0,x,y);};
- static double hdl25(double x,double y){return evaluate(tr_arr[25],0,x,y);};
- static double hdl26(double x,double y){return evaluate(tr_arr[26],0,x,y);};
- static double hdl27(double x,double y){return evaluate(tr_arr[27],0,x,y);};
- static double hdl28(double x,double y){return evaluate(tr_arr[28],0,x,y);};
- static double hdl29(double x,double y){return evaluate(tr_arr[29],0,x,y);};
- static double hdl30(double x,double y){return evaluate(tr_arr[30],0,x,y);};
- static double hdl31(double x,double y){return evaluate(tr_arr[31],0,x,y);};
- #else
- static double hdl00(x,y) double x,y; {return evaluate(tr_arr[ 0],0,x,y);};
- static double hdl01(x,y) double x,y; {return evaluate(tr_arr[ 1],0,x,y);};
- static double hdl02(x,y) double x,y; {return evaluate(tr_arr[ 2],0,x,y);};
- static double hdl03(x,y) double x,y; {return evaluate(tr_arr[ 3],0,x,y);};
- static double hdl04(x,y) double x,y; {return evaluate(tr_arr[ 4],0,x,y);};
- static double hdl05(x,y) double x,y; {return evaluate(tr_arr[ 5],0,x,y);};
- static double hdl06(x,y) double x,y; {return evaluate(tr_arr[ 6],0,x,y);};
- static double hdl07(x,y) double x,y; {return evaluate(tr_arr[ 7],0,x,y);};
- static double hdl08(x,y) double x,y; {return evaluate(tr_arr[ 8],0,x,y);};
- static double hdl09(x,y) double x,y; {return evaluate(tr_arr[ 9],0,x,y);};
- static double hdl10(x,y) double x,y; {return evaluate(tr_arr[10],0,x,y);};
- static double hdl11(x,y) double x,y; {return evaluate(tr_arr[11],0,x,y);};
- static double hdl12(x,y) double x,y; {return evaluate(tr_arr[12],0,x,y);};
- static double hdl13(x,y) double x,y; {return evaluate(tr_arr[13],0,x,y);};
- static double hdl14(x,y) double x,y; {return evaluate(tr_arr[14],0,x,y);};
- static double hdl15(x,y) double x,y; {return evaluate(tr_arr[15],0,x,y);};
- static double hdl16(x,y) double x,y; {return evaluate(tr_arr[16],0,x,y);};
- static double hdl17(x,y) double x,y; {return evaluate(tr_arr[17],0,x,y);};
- static double hdl18(x,y) double x,y; {return evaluate(tr_arr[18],0,x,y);};
- static double hdl19(x,y) double x,y; {return evaluate(tr_arr[19],0,x,y);};
- static double hdl20(x,y) double x,y; {return evaluate(tr_arr[20],0,x,y);};
- static double hdl21(x,y) double x,y; {return evaluate(tr_arr[21],0,x,y);};
- static double hdl22(x,y) double x,y; {return evaluate(tr_arr[22],0,x,y);};
- static double hdl23(x,y) double x,y; {return evaluate(tr_arr[23],0,x,y);};
- static double hdl24(x,y) double x,y; {return evaluate(tr_arr[24],0,x,y);};
- static double hdl25(x,y) double x,y; {return evaluate(tr_arr[25],0,x,y);};
- static double hdl26(x,y) double x,y; {return evaluate(tr_arr[26],0,x,y);};
- static double hdl27(x,y) double x,y; {return evaluate(tr_arr[27],0,x,y);};
- static double hdl28(x,y) double x,y; {return evaluate(tr_arr[28],0,x,y);};
- static double hdl29(x,y) double x,y; {return evaluate(tr_arr[29],0,x,y);};
- static double hdl30(x,y) double x,y; {return evaluate(tr_arr[30],0,x,y);};
- static double hdl31(x,y) double x,y; {return evaluate(tr_arr[31],0,x,y);};
- #endif
-
- static FP hdl_arr[MAXHANDLE] ={
- hdl00, hdl01, hdl02, hdl03, hdl04, hdl05, hdl06, hdl07,
- hdl08, hdl09, hdl10, hdl11, hdl12, hdl13, hdl14, hdl15,
- hdl16, hdl17, hdl18, hdl19, hdl20, hdl21, hdl22, hdl23,
- hdl24, hdl25, hdl26, hdl27, hdl28, hdl29, hdl30, hdl31 };
-
- #ifdef __cplusplus
- } /* end for c++ */
- #endif
-