home *** CD-ROM | disk | FTP | other *** search
- /* xlsym - symbol handling routines */
- /* Copyright (c) 1985, by David Michael Betz
- All Rights Reserved
- Permission is granted for unrestricted non-commercial use */
-
- #include "xlisp.h"
-
- /* external variables */
- extern LVAL obarray,s_unbound;
- extern LVAL xlenv,xlfenv;
- extern LVAL true; /* Bug fix TAA */
-
- /* forward declarations */
- #ifdef ANSI
- LVAL XNEAR findprop(LVAL sym, LVAL prp);
- #else
- FORWARD LVAL findprop();
- #endif
-
- /* xlenter - enter a symbol into the obarray */
- LVAL xlenter(name)
- char *name;
- {
- LVAL sym,array;
- int i;
-
- /* check for symbol already in table */
- array = getvalue(obarray);
- i = hash(name,HSIZE);
- for (sym = getelement(array,i); !null(sym); sym = cdr(sym))
- if (STRCMP(name,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(name)
- char *name;
- {
- LVAL sym;
- sym = cvsymbol(name);
- if (*name == ':') {
- setvalue(sym,sym);
- setsflags(sym, F_CONSTANT);
- }
- else setsflags(sym, F_NORMAL);
-
- return (sym);
- }
-
- /* xlgetvalue - get the value of a symbol (with check) */
- LVAL xlgetvalue(sym)
- 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(sym)
- LVAL sym;
- {
- register LVAL fp,ep;
- LVAL val;
-
- /* check the environment list */
- for (fp = xlenv; !null(fp); fp = cdr(fp))
-
- /* check for an instance variable */
- if (!null(ep = car(fp)) && objectp(car(ep))) {
- if (xlobgetvalue(ep,sym,&val))
- return (val);
- }
-
- /* check an environment stack frame */
- else {
- for (; !null(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(sym,val)
- LVAL sym,val;
- {
- register LVAL fp,ep;
-
- if (constantp(sym)) {
- xlnoassign(sym);
- /* never returns */
- }
-
- /* look for the symbol in the environment list */
- for (fp = xlenv; !null(fp); fp = cdr(fp))
-
- /* check for an instance variable */
- if (!null(ep = car(fp)) && objectp(car(ep))) {
- if (xlobsetvalue(ep,sym,val))
- return;
- }
-
- /* check an environment stack frame */
- else {
- for (; !null(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(sym)
- 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(sym)
- LVAL sym;
- {
- register LVAL fp,ep;
-
- /* check the environment list */
- for (fp = xlfenv; !null(fp); fp = cdr(fp))
- for (ep = car(fp); !null(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(sym,val)
- LVAL sym,val;
- {
- register LVAL fp,ep;
-
- /* look for the symbol in the environment list */
- for (fp = xlfenv; !null(fp); fp = cdr(fp))
- for (ep = car(fp); !null(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(sym,prp)
- LVAL sym,prp;
- {
- LVAL p;
- return (null(p = findprop(sym,prp)) ? NIL : car(p));
- }
-
- /* xlputprop - put a property value onto the property list */
- VOID xlputprop(sym,val,prp)
- LVAL sym,val,prp;
- {
- LVAL pair;
- if (!null(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(sym,prp)
- LVAL sym,prp;
- {
- LVAL last,p;
- last = NIL;
- for (p = getplist(sym); consp(p) && consp(cdr(p)); p = cdr(last)) {
- if (car(p) == prp)
- if (!null(last))
- rplacd(last,cdr(cdr(p)));
- else
- setplist(sym,cdr(cdr(p)));
- last = cdr(p);
- }
- }
-
- /* findprop - find a property pair */
- LOCAL LVAL XNEAR findprop(sym,prp)
- LVAL sym,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(str,len)
- char XFAR *str;
- int len;
- {
- int i;
- for (i = 0; *str; )
- i = (i << 2) ^ *str++;
- i %= len;
- return (i < 0 ? -i : i);
- }
-
- /* xlhash -- hash any xlisp object */
- /* TAA extension */
- int xlhash(obj,len)
- LVAL obj;
- int len;
- {
- int i;
- unsigned long tot;
- union {FIXTYPE i; float j; unsigned FIXTYPE k;} swizzle;
-
- hashloop: /* iterate on conses */
- switch (ntype(obj)) {
- case SYMBOL:
- obj = getpname(obj);
- case STRING:
- return hash(getstring(obj),len);
- case SUBR: case FSUBR:
- return getoffset(obj) % len;
- case FIXNUM:
- swizzle.i = getfixnum(obj);
- return (int) (swizzle.k % len);
- case FLONUM:
- swizzle.j = getflonum(obj);
- return (int) (swizzle.k % len);
- case CHAR:
- return getchcode(obj) % len;
- case CONS: case USTREAM:
- obj = car(obj); /* just base on CAR */
- goto hashloop;
- case STREAM:
- return 0; /* nothing we can do on this */
- default: /* all array types */
- for (i = getsize(obj), tot = 0; i-- > 0;)
- tot += (unsigned)xlhash(getelement(obj,i),len);
- return (int)(tot % len);
- }
- }
-
- /* unbind a variable/constant */
- LVAL xmakunbound()
- {
- LVAL sym;
-
- sym = xlgasymbol();
- xllastarg();
-
- if (constantp(sym))
- xlerror("can't unbind constant", sym);
-
- setvalue(sym, s_unbound);
- setsflags(sym, F_NORMAL);
- return(sym);
- }
-
-
- /* define a constant -- useful in initialization */
-
- VOID defconstant(sym, val)
- LVAL sym, val;
- {
- setvalue(sym, val);
- setsflags(sym, F_CONSTANT | F_SPECIAL);
- }
-
- /* DEFCONSTANT DEFPARAMETER and DEFVAR */
-
- LVAL xdefconstant()
- {
- LVAL sym, val;
-
- sym = xlgasymbol();
- val = xlgetarg();
- xllastarg();
-
- /* evaluate constant value */
- val = xleval(val);
-
- if (null(sym)) xlfail("can't redefine NIL");
-
- if (specialp(sym)) {
- if (constantp(sym)) {
- if (!eql(getvalue(sym),val)) {
- errputstr("WARNING-- redefinition of constant ");
- errprint(sym);
- }
- }
- else xlerror("can't make special variable into a constant", sym);
- }
-
- defconstant(sym, val);
-
- return(sym);
- }
-
-
- LVAL xdefparameter()
- {
- LVAL sym, val;
-
- sym = xlgasymbol();
- val = xlgetarg();
- xllastarg();
-
- if (constantp(sym)) xlnoassign(sym);
-
- setvalue(sym, xleval(val));
- setsflags(sym, F_SPECIAL);
- return(sym);
- }
-
- LVAL xdefvar()
- {
- LVAL sym, val=NIL;
-
- sym = xlgasymbol();
- if (moreargs()) {
- val = xlgetarg();
- xllastarg();
- }
-
- if (constantp(sym)) xlnoassign(sym);
-
- if (getvalue(sym) == s_unbound) setvalue(sym, xleval(val));
- setsflags(sym, F_SPECIAL);
- return(sym);
- }
-
-
- /* xlsinit - symbol initialization routine */
- VOID xlsinit()
- {
- 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);
-
- }
-