C:/Users/Dennis/src/lang/russell.orig/src/stree/mknode.c

Go to the documentation of this file.
00001 /* tree building routines for declaration tree */
00002 # include "parm.h"
00003 
00004 # include <stdio.h>
00005 
00006 # include <varargs.h>
00007 
00008 # include "ststructs.mh"
00009 
00010 # include "stsizes.mh"
00011 
00012 # include "stptrs.mh"
00013 
00014 # include "stmkfields.mh"
00015 
00016 extern char tokenbuf[];  /* temporary string space, shared with scanner */
00017 
00018 /*
00019  *  the BAD flag (Bad Allocation Debug) is used to catch usage of previously
00020  *  freed nodes.
00021  */
00022 #ifdef BAD
00023     extern boolean BADflag;
00024 #endif
00025 
00026 #ifndef BAD
00027 
00028 # ifdef UNDEFINED
00029 #   define MINPTR 10
00030   /* Faster version of initfld. */
00031 #   define initfld(pp,v) \
00032         if ( (*pp = v) > MINPTR) { \
00033             (void) lock(v); \
00034         }
00035 
00036   /* Faster version of lock */
00037 #   define lock(p) \
00038         (((p) -> refcount)++, p)
00039 
00040   /* Faster version of unlock */
00041 #   define unlock(p) \
00042         (((p) -> refcount)--, p)
00043 # endif
00044 
00045 #endif
00046 
00047 int retaddr();
00048 
00049 extern int yyvline;
00050 
00051 /*
00052  *    Construct a structure with kind field strkind. Set the vlineno field
00053  * to the current value of yyvline. Fields with the corresponding bit in 
00054  * stmkfields set are set to the values of the remaining arguments.
00055  * Other fields are initialized to NIL.
00056  *
00057  * The fundamental MACHINE DEPENDENCY here is that all fields must be the
00058  * same length -- the length of a C "unsigned".
00059  */
00060 
00061 NODE *mknode( va_alist )
00062 va_dcl
00063 {
00064     va_list ap;
00065     int strkind;
00066     register unsigned *p;
00067     unsigned q;
00068     register int v; /* bit vector identifying pointer fields in strkind */
00069     register int i; /* bit vector identifying fields to be initialized  */
00070                     /* to the argument values. */
00071     NODE *result;
00072 
00073 #   ifdef BAD
00074         if (BADflag)
00075             flcheck (0,0);  /* Do a complete free list check */
00076         else
00077             flcheck (0,1);  /* Do a quick free list check */
00078 #   endif
00079 
00080     va_start(ap);
00081     strkind = va_arg(ap, int);
00082 
00083     p = (unsigned *)salloc(stsize[strkind] * (sizeof (NODE *)));
00084     result = (NODE *)p;
00085 
00086     v = stptrs[strkind];
00087     i = stmkfields[strkind];
00088     /* p -> refcount = 0; */
00089     result -> kind = strkind;
00090     result -> vlineno = yyvline;
00091     /* adjust p, i & v to skip standard prefix. For efficiency only */
00092         p += SZSTANDARDPREFIX;
00093         i <<= SZSTANDARDPREFIX;
00094         v <<= SZSTANDARDPREFIX;
00095 
00096 
00097     q = va_arg(ap, int);
00098     while( p - (unsigned *)result < stsize[strkind] ) {
00099         if ( i < 0 ) {
00100             /* initialize this field */
00101                 if( v < 0 ) {
00102                     /* store a pointer field */
00103                         initfld( p, q );
00104                 } else {
00105                     /* store a non-pointer field */
00106                         *p = q;
00107                 }
00108                 q = va_arg(ap, int);
00109         } else {
00110             *p = NIL;
00111         }
00112         i <<= 1;
00113         v <<= 1;
00114         p++;
00115     }
00116     va_end(ap);
00117     
00118 #   ifdef BAD
00119         if (BADflag) {
00120             diagmsg("mknode: addr of new node=0%x, kind=%s\n",
00121                      result, kindname(strkind));
00122         }
00123 #   endif
00124 
00125     return( result );
00126 }
00127 
00128 # ifdef UNDEFINED
00129 /*
00130  * vfree(p)
00131  *
00132  * if *p's reference count is zero,
00133  *   free *p
00134  *   decrement reference counts of descendants
00135  *   call self recursively on descendants
00136  */
00137 
00138 # define MIN_PTR 10   /* lower limit for real pointers. lower values */
00139                       /* have special significance.                  */
00140 
00141 vfree(p)
00142 int *p;
00143 {
00144     register int size;
00145     register int v; /* bit vector identifying pointers */
00146     register unsigned *q;
00147 
00148 #   ifdef BAD
00149         if (BADflag)
00150             flcheck (0,0);  /* Do a complete free list check */
00151         else
00152             flcheck (0,1);  /* Do a quick free list check */
00153 #   endif
00154 
00155     if ( p == NIL ) return;
00156 
00157     if ( !is_refd(p) ) {
00158         /* call vfree for each child */
00159             if (( p -> kind) == LISTHEADER ) {
00160                 /* traverse list of descendants */
00161                     maplist(e, p, {
00162                         if( !is_refd(unlock(e)) )
00163                             vfree(e);
00164                     } );
00165                 /* now free the cons nodes */
00166                     {   ConsNode *c;
00167                         for ( c = p -> lh_first; c != NIL; c = cn_del_hd(c) );
00168                     }
00169             }
00170             else {  /* use stptrs to find the children */
00171                 v = stptrs[p -> kind];
00172                 q = p;
00173                 while(v) {
00174                     if(v < 0 /* *q is a pointer */ && *q > MIN_PTR) {
00175                         if( !is_refd( unlock((NODE *) *q) ) )
00176                             vfree((NODE *) *q);
00177                     }
00178                     v <<= 1;
00179                     q++;
00180                 }
00181             }
00182         /* deallocate storage */
00183             size = stsize[p -> kind];
00184 #           ifdef BAD
00185                 if (BADflag) {
00186                     diagmsg("vfree: addr of freed node=0%x, kind=%s, retaddr=0%x\n",
00187                         p, kindname(p->kind), retaddr());
00188                 }
00189 #           endif
00190             sfree(p, size * sizeof(NODE *));
00191     }
00192 }
00193 # endif
00194 
00195 /*
00196  * copynode(np)
00197  *
00198  * copy the node np;
00199  * don't copy the children, but increment their reference counts.
00200  * Return a pointer to the copy.
00201  */
00202 
00203 NODE * copynode(p)
00204 register NODE *p;
00205 {   int size;
00206     register int v;   /* bit vector giving pointer fields */
00207     register unsigned *q; /* pointer to middle of new node      */
00208     register unsigned *r; /* pointer to middle of original node */
00209     NODE * result;
00210 
00211     if ( is_list(p) ) 
00212         return( copylist(p) );
00213     size = stsize[p -> kind];
00214     v = stptrs[p -> kind];
00215     q = (unsigned *)salloc(size * sizeof(NODE *));
00216     result = (NODE *) q;
00217     /* copy and adjust reference counts where necessary */
00218         /* q->refcount = 0; */
00219         result->kind = p->kind;
00220         result->vlineno = p->vlineno;
00221         result->pre_num = p -> pre_num;
00222         result->post_num = p -> post_num;
00223         q += SZSTANDARDPREFIX;
00224         r = (unsigned *)p + SZSTANDARDPREFIX;
00225         size -= SZSTANDARDPREFIX;
00226         v <<= SZSTANDARDPREFIX;
00227         while( size-- ) {
00228             if( v < 0 ) {
00229                 /* copy a pointer */
00230                 initfld( q, *r );
00231                 q++; r++;
00232             } else {
00233                 /* copy a nonpointer */
00234                 *q++ = *r++;
00235             }
00236             v <<= 1;
00237         }
00238 #       ifdef BAD
00239             if (BADflag) {
00240                 diagmsg("copynode: addr of new node=0%x, kind=%s, retaddr=0%x\n",
00241                         result, kindname(result->kind), retaddr());
00242             }
00243 #       endif
00244     return( result );
00245 }
00246 
00247 /*
00248  * copylist(l)
00249  *
00250  * Make a new list which has on it the same elements (not copies) that 
00251  * are on l.
00252  */
00253 LIST copylist(l)
00254 LIST l;
00255 {   ConsNode *p;                /* The first element of the constructed list. */
00256     register ConsNode *q;       /* The last element of the constructed list. */
00257 
00258     p = q = NIL;
00259 
00260 #   ifdef DEBUG
00261         if ( !is_list(l) ) {
00262             dbgmsg("\ncopylist: arg not a list: l=%x\n",l);
00263             abort();
00264         }
00265 #   endif
00266 
00267     maplist(v, l, 
00268             {   if ( v == first(l) ) 
00269                     p = q = cn_cons(lock(v),NIL);
00270                 else {
00271                     cn_settail(q, cn_cons(lock(v), NIL));
00272                     q = cn_tail(q);
00273                 }
00274             } );
00275     return( (LIST) mknode(LISTHEADER, p, q) );
00276 }
00277 
00278 
00279 /*
00280  * Used by maprlist below
00281  */
00282 static void maprl1(l,fn)
00283 ConsNode * l;
00284 void (*fn)();
00285 {
00286     if (l != NIL) {
00287       maprl1(cn_tail(l),fn);
00288       (*fn) (cn_head(l));
00289     }
00290 }
00291 
00292 /*
00293  *  Apply fn to each element of the list l in reverse order
00294  */
00295 void maprlist(l, fn)
00296 LIST l;
00297 void (*fn)();
00298 {
00299     maprl1(l -> lh_first, fn);
00300 }
00301 
00302 /* 
00303  *  Return a pointer to a new LETTERID node with name fldname (a string table
00304  * index).  Set the id_def_found field.
00305  */
00306 NODE * mkcompnm(sttptr)
00307 unsigned sttptr;
00308 {
00309     register NODE * result;
00310     result = mknode(LETTERID, sttptr);
00311     result -> id_def_found = TRUE;
00312     return(result);
00313 }
00314 
00315 /*
00316  * return an identifier node for an identifer with name
00317  * consisting of string concatenated with the name of id.
00318  * Id may not be an OPRID.
00319  * The returned id has id_def_found set.  (It is presumed to be a
00320  * a field name.)
00321  */
00322 NODE * prefix(string, id)
00323 char * string;
00324 NODE * id;
00325 {
00326 #   ifdef DEBUG
00327         if (id -> kind != LETTERID) {
00328             dbgmsg("prefix: bad identifier node\n");
00329         }
00330 #   endif
00331     strcpy(tokenbuf, string);
00332     strcat(tokenbuf, getname(id -> id_str_table_index));
00333     return(mkcompnm(stt_enter(tokenbuf, strlen(tokenbuf)+1)));
00334 }
00335 

Generated on Fri Jan 25 10:39:48 2008 for russell by  doxygen 1.5.4