home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / lisp / interpre / xlispdos / source / xlsym.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-05-17  |  4.9 KB  |  230 lines

  1. /* xlsym - symbol handling routines */
  2. /*    Copyright (c) 1985, by David Michael Betz
  3.     All Rights Reserved
  4.     Permission is granted for unrestricted non-commercial use    */
  5.  
  6. #include "xlisp.h"
  7.  
  8. /* external variables */
  9. extern NODE *obarray,*s_unbound;
  10. extern NODE *xlenv;
  11.  
  12. /* forward declarations */
  13. FORWARD NODE *findprop();
  14.  
  15. /* xlenter - enter a symbol into the obarray */
  16. NODE *xlenter(name,type)
  17.   char *name; int type;
  18. {
  19.     NODE ***oldstk,*sym,*array;
  20.     int i;
  21.  
  22.     /* check for nil */
  23.     if (strcmp(name,"NIL") == 0)
  24.     return (NIL);
  25.  
  26.     /* check for symbol already in table */
  27.     array = getvalue(obarray);
  28.     i = hash(name,HSIZE);
  29.     for (sym = getelement(array,i); sym; sym = cdr(sym))
  30.     if (strcmp(name,getstring(getpname(car(sym)))) == 0)
  31.         return (car(sym));
  32.  
  33.     /* make a new symbol node and link it into the list */
  34.     oldstk = xlstack;
  35.     xlsave1(sym);
  36.     sym = consd(getelement(array,i));
  37.     rplaca(sym,xlmakesym(name,type));
  38.     setelement(array,i,sym);
  39.     xlstack = oldstk;
  40.  
  41.     /* return the new symbol */
  42.     return (car(sym));
  43. }
  44.  
  45. /* xlsenter - enter a symbol with a static print name */
  46. NODE *xlsenter(name)
  47.   char *name;
  48. {
  49.     return (xlenter(name,STATIC));
  50. }
  51.  
  52. /* xlmakesym - make a new symbol node */
  53. NODE *xlmakesym(name,type)
  54.   char *name;
  55. {
  56.     NODE *sym;
  57.     sym = (type == DYNAMIC ? cvsymbol(name) : cvcsymbol(name));
  58.     setvalue(sym,*name == ':' ? sym : s_unbound);
  59.     return (sym);
  60. }
  61.  
  62. /* xlframe - create a new environment frame */
  63. NODE *xlframe(env)
  64.   NODE *env;
  65. {
  66.     return (consd(env));
  67. }
  68.  
  69. /* xlbind - bind a value to a symbol */
  70. xlbind(sym,val,env)
  71.   NODE *sym,*val,*env;
  72. {
  73.     NODE *ptr;
  74.  
  75.     /* create a new environment list entry */
  76.     ptr = consd(car(env));
  77.     rplaca(env,ptr);
  78.  
  79.     /* create a new variable binding */
  80.     rplaca(ptr,cons(sym,val));
  81. }
  82.  
  83. /* xlgetvalue - get the value of a symbol */
  84. NODE *xlgetvalue(sym)
  85.   NODE *sym;
  86. {
  87.     register NODE *fp,*ep;
  88.     NODE *val;
  89.  
  90.     /* look for the value of the symbol */
  91.     for (;;) {
  92.  
  93.     /* get the global value */
  94.     val = getvalue(sym);
  95.  
  96.     /* check the environment list */
  97.     for (fp = xlenv; fp; fp = cdr(fp))
  98.  
  99.         /* check for an instance variable */
  100.         if ((ep = car(fp)) && objectp(car(ep))) {
  101.         if (xlobgetvalue(ep,sym,&val))
  102.             goto check_unbound;
  103.         }
  104.  
  105.         /* check an environment stack frame */
  106.         else {
  107.         for (; ep; ep = cdr(ep))
  108.             if (sym == car(car(ep))) {
  109.             val = cdr(car(ep));
  110.             goto check_unbound;
  111.             }
  112.         }
  113.  
  114. check_unbound:
  115.     /* check for a good value */
  116.     if (val != s_unbound)
  117.         break;
  118.  
  119.     /* handle the unbound variable */
  120.     xlunbound(sym);
  121.     }
  122.  
  123.     /* return the value */
  124.     return (val);
  125. }
  126.  
  127. /* xlsetvalue - set the value of a symbol */
  128. xlsetvalue(sym,val)
  129.   NODE *sym,*val;
  130. {
  131.     register NODE *fp,*ep;
  132.  
  133.     /* look for the symbol in the environment list */
  134.     for (fp = xlenv; fp; fp = cdr(fp))
  135.  
  136.     /* check for an instance variable */
  137.     if ((ep = car(fp)) && objectp(car(ep))) {
  138.         if (xlobsetvalue(ep,sym,val))
  139.         return;
  140.     }
  141.  
  142.     /* check an environment stack frame */
  143.     else {
  144.         for (; ep; ep = cdr(ep))
  145.         if (sym == car(car(ep))) {
  146.             rplacd(car(ep),val);
  147.             return;
  148.         }
  149.     }
  150.  
  151.     /* store the global value */
  152.     setvalue(sym,val);
  153. }
  154.  
  155. /* xlgetprop - get the value of a property */
  156. NODE *xlgetprop(sym,prp)
  157.   NODE *sym,*prp;
  158. {
  159.     NODE *p;
  160.     return ((p = findprop(sym,prp)) ? car(p) : NIL);
  161. }
  162.  
  163. /* xlputprop - put a property value onto the property list */
  164. xlputprop(sym,val,prp)
  165.   NODE *sym,*val,*prp;
  166. {
  167.     NODE *pair;
  168.     if (pair = findprop(sym,prp))
  169.     rplaca(pair,val);
  170.     else
  171.     setplist(sym,cons(prp,cons(val,getplist(sym))));
  172. }
  173.  
  174. /* xlremprop - remove a property from a property list */
  175. xlremprop(sym,prp)
  176.   NODE *sym,*prp;
  177. {
  178.     NODE *last,*p;
  179.     last = NIL;
  180.     for (p = getplist(sym); consp(p) && consp(cdr(p)); p = cdr(last)) {
  181.     if (car(p) == prp)
  182.         if (last)
  183.         rplacd(last,cdr(cdr(p)));
  184.         else
  185.         setplist(sym,cdr(cdr(p)));
  186.     last = cdr(p);
  187.     }
  188. }
  189.  
  190. /* findprop - find a property pair */
  191. LOCAL NODE *findprop(sym,prp)
  192.   NODE *sym,*prp;
  193. {
  194.     NODE *p;
  195.     for (p = getplist(sym); consp(p) && consp(cdr(p)); p = cdr(cdr(p)))
  196.     if (car(p) == prp)
  197.         return (cdr(p));
  198.     return (NIL);
  199. }
  200.  
  201. /* hash - hash a symbol name string */
  202. int hash(str,len)
  203.   char *str;
  204. {
  205.     int i;
  206.     for (i = 0; *str; )
  207.     i = (i << 2) ^ *str++;
  208.     i %= len;
  209.     return (i < 0 ? -i : i);
  210. }
  211.  
  212. /* xlsinit - symbol initialization routine */
  213. xlsinit()
  214. {
  215.     NODE *array,*p;
  216.  
  217.     /* initialize the obarray */
  218.     obarray = xlmakesym("*OBARRAY*",STATIC);
  219.     array = newvector(HSIZE);
  220.     setvalue(obarray,array);
  221.  
  222.     /* add the symbol *OBARRAY* to the obarray */
  223.     p = consa(obarray);
  224.     setelement(array,hash("*OBARRAY*",HSIZE),p);
  225.  
  226.     /* enter the unbound symbol indicator */
  227.     s_unbound = xlsenter("*UNBOUND*");
  228.     setvalue(s_unbound,s_unbound);
  229. }
  230.