diff options
Diffstat (limited to 'xlisp/xlsym.c')
-rw-r--r-- | xlisp/xlsym.c | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/xlisp/xlsym.c b/xlisp/xlsym.c new file mode 100644 index 0000000..8932377 --- /dev/null +++ b/xlisp/xlsym.c @@ -0,0 +1,370 @@ +/* xlsym - symbol handling routines */ +/* Copyright (c) 1985, by David Michael Betz + All Rights Reserved + Permission is granted for unrestricted non-commercial use */ + +/* HISTORY + * 28-apr-03 DM eliminate some compiler warnings + * 12-oct-90 RBD added xlatomcount to keep track of how many atoms there are. + * (something I need for writing out score files). + */ + +#include "string.h" +#include "xlisp.h" + +extern int xlatomcount; + +/* forward declarations */ +FORWARD LVAL findprop(LVAL sym, LVAL prp); + +#ifdef FRAME_DEBUG +/* these routines were used to debug a missing call to protect(). + * The routines can check for a consistent set of frames. Note + * that frames must be pushed on the stack declared here because + * XLisp keeps frame pointers as local variables in C routines. + * I deleted the calls to push_xlenv etc throughout the XLisp + * sources, but decided to leave the following code for possible + * future debugging. - RBD + */ +int envstack_top = 0; +LVAL envstack[envstack_max]; +LVAL *fpstack[envstack_max]; +extern long cons_count; + +FORWARD LOCAL void test_one_env(LVAL environment, int i, char *s); + +void push_xlenv(void) +{ + char s[10]; + /* sprintf(s, "<%d ", envstack_top); + stdputstr(s); */ + if (envstack_top >= envstack_max) { + xlabort("envstack overflow"); + } else { + fpstack[envstack_top] = xlfp; + envstack[envstack_top++] = xlenv; + } +} + + +void pop_xlenv(void) +{ + char s[10]; + if (envstack_top <= 0) { + sprintf(s, ", %d! ", envstack_top); + stdputstr(s); + xlabort("envstack underflow!"); + } else envstack_top--; + /* sprintf(s, "%d> ", envstack_top); + stdputstr(s); */ +} + + +void pop_multiple_xlenv(void) +{ + int i; + for (i = envstack_top - 1; i >= 0; i--) { + if (envstack[i] == xlenv) { + char s[10]; + envstack_top = i + 1; + /* sprintf(s, "%d] ", envstack_top); + stdputstr(s); */ + return; + } + } +} + + +void testenv(char *s) +{ + int i; + + for (i = envstack_top - 1; i >= 0; i--) { + test_one_env(envstack[i], i, s); + } +} + +LOCAL void report_exit(char *msg, int i) +{ + sprintf(buf, "env stack index: %d, cons_count %ld, Function: ", i, cons_count); + errputstr(buf); + stdprint(fpstack[i][1]); + xlabort(msg); +} + +LOCAL void test_one_env(LVAL environment, int i, char *s) +{ + register LVAL fp,ep; + LVAL val; + + /* check the environment list */ + for (fp = environment; fp; fp = cdr(fp)) { + /* check that xlenv is good */ + if (!consp(fp)) { + sprintf(buf,"%s: xlenv 0x%lx, frame 0x%lx, type(frame) %d\n", + s, xlenv, fp, ntype(fp)); + errputstr(buf); + report_exit("xlenv points to a bad list", i); + } + + /* check for an instance variable */ + if ((ep = car(fp)) && objectp(car(ep))) { + /* do nothing */ + } + + /* check an environment stack frame */ + else { + for (; ep; ep = cdr(ep)) { + /* check that ep is good */ + if (!consp(ep)) { + sprintf(buf,"%s: fp 0x%lx, ep 0x%lx, type(ep) %d\n", + s, fp, ep, ntype(ep)); + errputstr(buf); + report_exit("car(fp) points to a bad list", i); + } + + /* check that car(ep) is nonnull */ + if (!car(ep)) { + sprintf(buf,"%s: ep 0x%lx, car(ep) 0x%lx\n", + s, ep, car(ep)); + errputstr(buf); + report_exit("car(ep) (an association) is NULL", i); + } + /* check that car(ep) is a cons */ + if (!consp(car(ep))) { + sprintf(buf,"%s: ep 0x%lx, car(ep) 0x%lx, type(car(ep)) %d\n", + s, ep, car(ep), ntype(car(ep))); + errputstr(buf); + report_exit("car(ep) (an association) is not a cons", i); + } + + /* check that car(car(ep)) is a symbol */ + if (!symbolp(car(car(ep)))) { + sprintf(buf,"%s: ep 0x%lx, car(ep) 0x%lx, car(car(ep)) 0x%lx, type(car(car(ep))) %d\n", + s, ep, car(ep), car(car(ep)), ntype(car(car(ep)))); + errputstr(buf); + report_exit("car(car(ep)) is not a symbol", i); + } + } + } + } +} +#endif + + +/* xlenter - enter a symbol into the obarray */ +LVAL xlenter(char *name) +{ + LVAL sym,array; + int i; + + /* check for nil */ + if (strcmp(name,"NIL") == 0) + return (NIL); + + /* check for symbol already in table */ + array = getvalue(obarray); + i = hash(name,HSIZE); + for (sym = getelement(array,i); sym; sym = cdr(sym)) + if (strcmp(name,(char *) getstring(getpname(car(sym)))) == 0) + return (car(sym)); + + /* make a new symbol node and link it into the list */ + xlsave1(sym); + sym = consd(getelement(array,i)); + rplaca(sym,xlmakesym(name)); + setelement(array,i,sym); + xlpop(); + + /* return the new symbol */ + return (car(sym)); +} + +/* xlmakesym - make a new symbol node */ +LVAL xlmakesym(char *name) +{ + LVAL sym; + sym = cvsymbol(name); + if (*name == ':') + setvalue(sym,sym); + return (sym); +} + +/* xlgetvalue - get the value of a symbol (with check) */ +LVAL xlgetvalue(LVAL sym) +{ + LVAL val; + + /* look for the value of the symbol */ + while ((val = xlxgetvalue(sym)) == s_unbound) + xlunbound(sym); + + /* return the value */ + return (val); +} + +/* xlxgetvalue - get the value of a symbol */ +LVAL xlxgetvalue(LVAL sym) +{ + register LVAL fp,ep; + LVAL val; + + /* check the environment list */ + for (fp = xlenv; fp; fp = cdr(fp)) + + /* check for an instance variable */ + if ((ep = car(fp)) && objectp(car(ep))) { + if (xlobgetvalue(ep,sym,&val)) + return (val); + } + + /* check an environment stack frame */ + else { + for (; ep; ep = cdr(ep)) + if (sym == car(car(ep))) + return (cdr(car(ep))); + } + + /* return the global value */ + return (getvalue(sym)); +} + +/* xlsetvalue - set the value of a symbol */ +void xlsetvalue(LVAL sym, LVAL val) +{ + register LVAL fp,ep; + + /* look for the symbol in the environment list */ + for (fp = xlenv; fp; fp = cdr(fp)) + + /* check for an instance variable */ + if ((ep = car(fp)) && objectp(car(ep))) { + if (xlobsetvalue(ep,sym,val)) + return; + } + + /* check an environment stack frame */ + else { + for (; ep; ep = cdr(ep)) + if (sym == car(car(ep))) { + rplacd(car(ep),val); + return; + } + } + + /* store the global value */ + setvalue(sym,val); +} + +/* xlgetfunction - get the functional value of a symbol (with check) */ +LVAL xlgetfunction(LVAL sym) +{ + LVAL val; + + /* look for the functional value of the symbol */ + while ((val = xlxgetfunction(sym)) == s_unbound) + xlfunbound(sym); + + /* return the value */ + return (val); +} + +/* xlxgetfunction - get the functional value of a symbol */ +LVAL xlxgetfunction(LVAL sym) +{ + register LVAL fp,ep; + + /* check the environment list */ + for (fp = xlfenv; fp; fp = cdr(fp)) + for (ep = car(fp); ep; ep = cdr(ep)) + if (sym == car(car(ep))) + return (cdr(car(ep))); + + /* return the global value */ + return (getfunction(sym)); +} + +/* xlsetfunction - set the functional value of a symbol */ +void xlsetfunction(LVAL sym, LVAL val) +{ + register LVAL fp,ep; + + /* look for the symbol in the environment list */ + for (fp = xlfenv; fp; fp = cdr(fp)) + for (ep = car(fp); ep; ep = cdr(ep)) + if (sym == car(car(ep))) { + rplacd(car(ep),val); + return; + } + + /* store the global value */ + setfunction(sym,val); +} + +/* xlgetprop - get the value of a property */ +LVAL xlgetprop(LVAL sym, LVAL prp) +{ + LVAL p; + return ((p = findprop(sym,prp)) ? car(p) : NIL); +} + +/* xlputprop - put a property value onto the property list */ +void xlputprop(LVAL sym, LVAL val, LVAL prp) +{ + LVAL pair; + if ((pair = findprop(sym,prp))) + rplaca(pair,val); + else + setplist(sym,cons(prp,cons(val,getplist(sym)))); +} + +/* xlremprop - remove a property from a property list */ +void xlremprop(LVAL sym, LVAL prp) +{ + LVAL last,p; + last = NIL; + for (p = getplist(sym); consp(p) && consp(cdr(p)); p = cdr(last)) { + if (car(p) == prp) { + if (last) + rplacd(last,cdr(cdr(p))); + else + setplist(sym,cdr(cdr(p))); + } + last = cdr(p); + } +} + +/* findprop - find a property pair */ +LVAL findprop(LVAL sym, LVAL prp) +{ + LVAL p; + for (p = getplist(sym); consp(p) && consp(cdr(p)); p = cdr(cdr(p))) + if (car(p) == prp) + return (cdr(p)); + return (NIL); +} + +/* hash - hash a symbol name string */ +int hash(char *str, int len) +{ + int i; + for (i = 0; *str; ) + i = (i << 2) ^ *str++; + i %= len; + return (i < 0 ? -i : i); +} + +/* xlsinit - symbol initialization routine */ +void xlsinit(void) +{ + LVAL array,p; + + /* initialize the obarray */ + obarray = xlmakesym("*OBARRAY*"); + array = newvector(HSIZE); + setvalue(obarray,array); + + /* add the symbol *OBARRAY* to the obarray */ + p = consa(obarray); + setelement(array,hash("*OBARRAY*",HSIZE),p); +} |