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.
- *
- * -----------------------------------------------------
- *
- * dfcsymtable.c -- symbol table of defunc
- *
- * public function : getsym();
- * getfnctname();
- * getarguname();
- *
- * nameargu();
- * initargu();
- * namefnct();
- * namecnst();
- * clrfnct();
- * clrfnctall();
- * clrcnst();
- * clrcnstall();
- *
- * matha2z();
- *
- * private variable : sym_table;
- * tablen;
- *
- * private function : top();
- * isname();
- * clrname();
- * clrall();
- *
- *********************************************************/
-
- #include <stdio.h>
- #include <malloc.h>
- #include <string.h>
- #include <math.h>
- #include <ctype.h>
- #include "dfcsymtable.h"
-
- #ifdef __cplusplus
- extern "C" { /* for c++ */
- #endif
-
- static Symbol_record* sym_table = 0;
- /* The defunc system global name-object association table */
-
- #if NeedFunctionPrototypes
- Symbol_record* getsym(char *name)
- #else
- Symbol_record* getsym(name)
- char *name;
- #endif
- /* search for record with the given name from sym_table */
- {
- Symbol_record* ptr;
-
- if(name==0) return 0;
-
- for(ptr=sym_table; ptr!=0; ptr=(Symbol_record*)ptr->next)
- {
- if(strcmp(ptr->name, name)==0) break;
- }
-
- return ptr;
- /* if symbol with name not in sym_table, return will be NULL */
- };
-
- #if NeedFunctionPrototypes
- char* getfnctname(double (*fnct)())
- #else
- char* getfnctname(fnct)
- double (*fnct)();
- #endif
- {
- Symbol_record* ptr;
-
- for(ptr=sym_table;ptr!=0;ptr=ptr->next)
- {
- if(ptr->type==fnct_symbol)
- {
- if(fnct==ptr->content.fnctptr) return ptr->name;
- }
- }
-
- return 0;
- };
-
- #if NeedFunctionPrototypes
- char* getarguname(int argidx)
- #else
- char* getarguname(argidx)
- int argidx;
- #endif
- /* return the name of the argument with specific index */
- {
- Symbol_record* ptr;
-
- for(ptr=sym_table; ptr!=0; ptr=ptr->next)
- {
- if(ptr->type==arg_symbol)
- {
- if(argidx==ptr->content.argidx) return ptr->name;
- }
- }
-
- return 0;
- };
-
- #if NeedFunctionPrototypes
- static Symbol_record* top(void)
- #else
- static Symbol_record* top()
- #endif
- /* return the top symbol record in the sym_table heap */
- {
- Symbol_record* ptr;
-
- for(ptr=sym_table; ptr->next!=0; ptr=(Symbol_record*)ptr->next)
- {
- /* skim over the table, do nothing on it */
- };
-
- return ptr;
- };
-
- #if NeedFunctionPrototypes
- static int isname(char* str)
- #else
- static int isname(str)
- char *str;
- #endif
- /* Is the string str a legal name? (start with alphabetic character
- * followed by alphabetics or numberical characters) */
- {
- int i;
-
- if(str==0||strlen(str)==0) return 0;
-
- if(!isalpha(str[0])) return 0; /* fail */
-
- for(i=1;i<strlen(str);i++)
- {
- if(!isalnum(str[i])) return 0; /* fail */
- }
-
- return 1; /* true */
- };
-
- #if NeedFunctionPrototypes
- static int clrname(char* name, Symbol_type type)
- #else
- static int clrname(name, type)
- char* name;
- Symbol_type type;
- #endif
- /* delete a specific name with given type from symbol table */
- {
- Symbol_record *ptr=sym_table, *newnext;
-
- if(sym_table==0) return 0; /* empty table, no delete action */
-
- if(strcmp(sym_table->name, name)==0&&ptr->type==type)
- /* name and type matched with the 1st record */
- {
- ptr = sym_table;
- sym_table = sym_table->next; /* cut out the 1st record */
- free(ptr->name);
- free(ptr);
- return 1;
- }
-
- for(ptr=sym_table; ptr->next!=0; ptr=(Symbol_record*)ptr->next)
- /* skim through the table */
- {
- if(strcmp(ptr->next->name, name)==0&&ptr->next->type==type)
- /* name and type matched with the next record */
- {
- newnext=ptr->next->next; /* cut out the next record */
- free(ptr->next->name);
- free(ptr->next);
- ptr->next=newnext;
- return 1;
- }
- }
-
- return 0; /* no matching */
- };
-
- #if NeedFunctionPrototypes
- int clrfnct(char* name)
- { return clrname(name, fnct_symbol);};
- int clrcnst(char* name)
- { return clrname(name, const_symbol);};
- #else
- int clrfnct(name) char* name;
- { return clrname(name, fnct_symbol);};
- int clrcnst(name) char* name;
- { return clrname(name, const_symbol);};
- #endif
-
- #if NeedFunctionPrototypes
- static int clrall(Symbol_type type)
- #else
- static int clrall(type)
- Symbol_type type;
- #endif
- /* delete all symbols with specific type from symbol table */
- {
- Symbol_record* ptr, *newnext;
- int i=0;
-
- if(sym_table==0) return 0; /* empty, no delete action */
-
- for(ptr=sym_table;sym_table!=0;ptr=sym_table)
- /* always point to 1st record */
- {
- if(sym_table->type==type) /* type matched with the 1st record */
- {
- sym_table=sym_table->next; /* cut out the 1st record */
- free(ptr->name);
- free(ptr);
- i++;
- }
- else break; /* if new 1st record not match, jump out */
- }
-
- if(sym_table == 0) return i; /* still have record ? */
-
- for(ptr=sym_table; ptr->next!=0; ptr=(Symbol_record*)ptr->next)
- /* skim through the table */
- {
- if(ptr->next->type==type) /* type matched with next record */
- {
- newnext = ptr->next->next; /* cut out the next record */
- free(ptr->next->name);
- free(ptr->next);
- ptr->next = newnext;
- i++;
- }
- }
-
- return i;
- };
-
- #if NeedFunctionPrototypes
- int clrfnctall(void)
- { return clrall(fnct_symbol);};
- int clrcnstall(void)
- { return clrall(const_symbol);};
- #else
- int clrfnctall()
- { return clrall(fnct_symbol);};
- int clrcnstall()
- { return clrall(const_symbol);};
- #endif
-
- #if NeedFunctionPrototypes
- int namefnct(char* str, double (*fnctptr)())
- #else
- int namefnct(str, fnctptr)
- char *str;
- double (*fnctptr)();
- #endif
- /* add a function symbol to the end of sym_table */
- {
- Symbol_record* ptr=0;
-
- if(!isname(str)||fnctptr==0) return 0;
-
- if(sym_table==0) /* table is empty */
- {
- if(nameargu("x", "y")<=0) return -1;
- }
-
- ptr = getsym(str);
-
- if(ptr==0) /* symbol not exist in sym_table */
- {
- ptr = top()->next
- = (Symbol_record*)malloc(sizeof(Symbol_record));
- if(ptr==0)
- {
- perror("malloc for new function token item");
- exit(1);
- }
- }
- else if(ptr->type==arg_symbol)
- {
- return -1; /* forbiding override argument symbols */
- }
-
- ptr->name = (char*)malloc((strlen(str)+1)*sizeof(char));
- if(ptr->name==0)
- {
- perror("malloc for new function token name");
- exit(1);
- }
-
- strncpy(ptr->name, str, strlen(str)+1);
- ptr->type = fnct_symbol;
- ptr->content.fnctptr = fnctptr;
-
- return 1;
- };
-
- #if NeedFunctionPrototypes
- int namecnst(char* str, double number)
- #else
- int namecnst(str, number)
- char *str;
- double number;
- #endif
- /* add a constnat symbol to the end of sym_table */
- {
- Symbol_record* ptr=0;
-
- if(!isname(str)) return 0;
-
- if(sym_table==0) /* table is empty */
- {
- if(nameargu("x", "y")<=0) return -1;
- }
-
- ptr = getsym(str);
-
- if(ptr==0) /* symbol not exist in sym_table */
- {
- ptr = top()->next
- = (Symbol_record*)malloc(sizeof(Symbol_record));
- if(ptr==0)
- {
- perror("malloc for constant token item");
- exit(1);
- }
- }
- else if(ptr->type==arg_symbol)
- {
- return -1; /* forbiding override argument symbols */
- }
-
- ptr->name = (char*)malloc((strlen(str)+1)*sizeof(char));
- if(ptr->name==0)
- {
- perror("malloc for constant token name");
- exit(1);
- }
-
- strncpy(ptr->name, str, strlen(str)+1);
- ptr->type = const_symbol;
- ptr->content.value = number;
-
- return 1;
- };
-
- #if NeedFunctionPrototypes
- int nameargu(char* arg1, char* arg2)
- #else
- int nameargu(arg1, arg2)
- char *arg1, *arg2;
- #endif
- /* on error return -1, on success return 1, if no change return 0 */
- {
- if(!isname(arg1)) return 0;
-
- if(!isname(arg2)) arg2 = "_";
-
- if(strcmp(arg1, arg2)==0) return -1; /* stupid */
-
- clrname(arg1, fnct_symbol);
- clrname(arg1, const_symbol);
- clrname(arg2, fnct_symbol);
- clrname(arg2, const_symbol);
-
- if(sym_table==0)
- {
- sym_table = (Symbol_record*)malloc(sizeof(Symbol_record));
- if(sym_table==0)
- {
- perror("malloc for the 1st argument token item");
- exit(1);
- }
- }
-
- sym_table->name = (char*)malloc((strlen(arg1)+1)*sizeof(char));
- if(sym_table->name==0)
- {
- perror("malloc for the 1st argument token name");
- exit(1);
- }
-
- strncpy(sym_table->name, arg1, strlen(arg1)+1);
- sym_table->type = arg_symbol;
- sym_table->content.argidx = 1;
-
- if(sym_table->next==0)
- {
- sym_table->next = (Symbol_record*)malloc(sizeof(Symbol_record));
- if(sym_table->next==0)
- {
- perror("malloc for the 2nd token token item");
- exit(1);
- }
- }
-
- sym_table->next->name = (char*)malloc((strlen(arg2)+1)*sizeof(char));
- if(sym_table->next->name==0)
- {
- perror("alloc memory for 2nd arguement name");
- exit(1);
- }
-
- strncpy(sym_table->next->name, arg2, strlen(arg2)+1);
-
- sym_table->next->type = arg_symbol;
- sym_table->next->content.argidx = 2;
-
- return 1;
- };
-
- #if NeedFunctionPrototypes
- int initargu(void)
- #else
- int initargu()
- #endif
- /* if no argument names then use default */
- {
- if(sym_table==0) return nameargu("x", "y");
- return 0;
- };
-
- static struct {
- char* name;
- double (*fnctptr)();
- } initfnct[] = {
- "sin" , sin ,
- "cos" , cos ,
- "tan" , tan ,
- "tg" , tan ,
- "asin" , asin ,
- "acos" , acos ,
- "atan" , atan ,
- "atan2", atan2,
- "exp" , exp ,
- "sinh" , sinh ,
- "sh" , sinh ,
- "cosh" , cosh ,
- "ch" , cosh ,
- "tanh" , tanh ,
- "th" , tanh ,
- "asinh", asinh,
- "ash" , asinh,
- "acosh", acosh,
- "ach" , acosh,
- "atanh", atanh,
- "ath" , atanh,
- "pow" , pow ,
- "log" , log ,
- "ln" , log ,
- "log10", log10,
- "log2" , log2 ,
- "sqrt" , sqrt ,
- "abs" , fabs ,
- 0 , 0 };
-
- #if NeedFunctionPrototypes
- int matha2z(void)
- #else
- int matha2z()
- #endif
- /* set up a symbol table include math "a to z" functions */
- {
- int i=0, j=0;
-
- initargu();
-
- for(i=0;initfnct[i].name!=0;i++)
- {
- j = j + namefnct(initfnct[i].name, initfnct[i].fnctptr);
- }
-
- j = j + namecnst("pi", 2*asin(1.0));
-
- return j;
- };
-
- /* codes for debug ------------------------------------------- */
-
- #if NeedFunctionPrototypes
- int printrec(Symbol_record* ptr, double x)
- #else
- int printrec(ptr, x)
- Symbol_record* ptr;
- double x;
- #endif
- {
- printf("type = %d\n", ptr->type);
- if(ptr->name!=0) printf("name = %s\n", ptr->name);
-
- switch(ptr->type)
- {
- case const_symbol:
- printf("value= %f\n", ptr->content.value);
- break;
-
- case arg_symbol:
- printf("arg[%d] = %s\n", ptr->content.argidx,
- getfnctname(ptr->content.fnctptr));
- break;
-
- case fnct_symbol:
- printf("%s(%f) = %f\n", ptr->name, x, (ptr->content.fnctptr)(x));
- break;
-
- default: break;
- }
-
- return 0;
- };
-
- #if NeedFunctionPrototypes
- int printab(double x)
- #else
- int printab(x)
- double x;
- #endif
- {
- Symbol_record* ptr;
- int len = 0;
-
- for(ptr=sym_table; ptr!=0; ptr=ptr->next)
- {
- len ++;
- printrec(ptr, x);
- }
-
- return len;
- };
-
- #ifdef __cplusplus
- } /* end for c++ */
- #endif
-