C:/Users/Dennis/src/lang/russell.orig/src/pass1/stt/stt.c

Go to the documentation of this file.
00001 #
00002 /*
00003  * Russell
00004  *  String table routines
00005  */
00006 
00007 #include "parm.h"
00008 #include "sttdefs.h"
00009 #include "arith.h"
00010 #include <stdio.h>
00011 
00012 /*
00013  *    sttindx(blkno) - maps block numbers into their address in core.
00014  *    sttfirstfree   - relative position of the first free byte in the table.
00015  *    STTHDRSZ       - number of hash table headers.
00016  *    stthdr(hash)   - maps the hash of a string into a chain of entries with
00017  *                     the same hash.
00018  */
00019 sttblock *(sttindx[STTNBLKS]);
00020 sttrelptr sttfirstfree;
00021 #define STTHDRSZ 128
00022 sttrelptr stthdr[STTHDRSZ];
00023 
00024 
00025 /*
00026  * stt_abs(rpt)
00027  *
00028  * convert relative pointer into string table
00029  *   to absolute pointer to string table entry.
00030  */
00031 Sttentry *stt_abs(rpt)
00032 sttrelptr rpt;
00033 {
00034     return(
00035         (Sttentry *)(&(sttindx[STTBLKNO(rpt)]->sttb_data[STTOFFSET(rpt)]))
00036     );
00037 }
00038 
00039 /*
00040  * getname( rpt )
00041  * 
00042  * convert relative string table pointer to absolute
00043  *   pointer to string.
00044  */
00045 char *getname( rpt )
00046 sttrelptr rpt;
00047 {
00048     if (rpt == (sttrelptr)(-1)) {
00049         return("(local type id)");
00050     } else {
00051         return( stt_abs(rpt) -> stte_str );
00052     }
00053 }
00054 
00055 
00056 /*
00057  *  stt_balloc(blkno)
00058  *  Allocate block number blkno, if possible.
00059  */
00060 stt_balloc(blkno)
00061 unsigned blkno;
00062 {
00063     if (blkno >= STTNBLKS) {
00064         yyperror("Too many identifiers");
00065         exit(4);
00066     }
00067     sttindx[blkno] = (sttblock *)gc_malloc_atomic( sizeof(sttblock) );
00068 }
00069 
00070 
00071 /*
00072  * stt_alloc( nbytes )
00073  *   
00074  * find nbytes space in string table
00075  * and return address( relative to start of string table ).
00076  */
00077 sttrelptr stt_alloc( nbytes )
00078 unsigned nbytes;
00079 {
00080     register sttrelptr firstfree = sttfirstfree;
00081     unsigned blkno;
00082 
00083     /* Check for requests that are too large. */
00084         if (nbytes > sizeof(sttblock)) {
00085             fprintf(stderr,"stt_alloc: identifier too large: %u\n",nbytes);
00086             abort();
00087         }
00088 
00089     /* If firstfree's block has not been allocated (due to roundup), do so. */
00090         if ( sttindx[ STTBLKNO(firstfree) ] == 0 )
00091             stt_balloc( STTBLKNO(firstfree) );
00092 
00093     /* Get a new block if there is no space on the current one. */
00094         if ( STTOFFSET(firstfree) + nbytes > sizeof(sttblock) ) {
00095             firstfree = roundup(firstfree,sizeof(sttblock));
00096             stt_balloc( STTBLKNO(firstfree) );
00097         }
00098 
00099     /* Compute new value for sttfirstfree (round up to a multiple of a word). */
00100         sttfirstfree = roundup(firstfree + nbytes, sizeof(int));
00101 
00102 
00103     return( firstfree );
00104 }
00105 
00106 /*
00107  * rp = stt_enter( str, lgth )
00108  *
00109  * enter given string (of given length) into string table,
00110  *   return its relative position.
00111  * the length counts the trailing null
00112  *   therefore, length is at least 2.
00113  */
00114 sttrelptr stt_enter( str, lgth )
00115 char *str; int lgth;
00116 {   sttrelptr p; 
00117     Sttentry *pabs;
00118     static boolean firstentry = TRUE;   /* True on first call of routine. */
00119     unsigned hashval = ( (unsigned) ((13 * str[0]) + (5 * str[lgth-2]) + lgth) )
00120                        % STTHDRSZ;
00121 
00122     if( firstentry ) {
00123         /* Initialize hash table headers and sttfirstfree. */
00124             register int i;
00125             for( i = 0; i < STTHDRSZ; i++ )
00126                 stthdr[i] = STT_NO_NEXT_ENTRY;
00127             stt_balloc(0);
00128             sttfirstfree = 0;
00129             sttnstrings = 0;
00130             firstentry = FALSE;
00131     }
00132     
00133 
00134     /* Search through entries chained off of hash header for one with */
00135     /* the same name as str. If found, return its relative position.  */
00136         for(p = stthdr[hashval]; p != STT_NO_NEXT_ENTRY; p = pabs->stte_next) {
00137             pabs = stt_abs( p );
00138             if( strcmp( pabs->stte_str, str ) == 0 )
00139                 return( p );
00140         }
00141 
00142     sttnstrings++;
00143 
00144     /* Add a new entry to the head of the chain. */
00145         p = stt_alloc( STTENTRYSZ(lgth) );
00146         pabs = stt_abs( p );
00147         pabs->stte_next = stthdr[hashval];
00148         stthdr[hashval] = p;
00149         strcpy( pabs->stte_str, str );
00150         return( p );
00151 }
00152 
00153 /*
00154  * build_Idtable()
00155  * 
00156  * Build Idtable, a mapping between strings and values used to build the
00157  * symbol table.
00158  */
00159 # include "stree/ststructs.mh"
00160 # include "pass2/Idtable.h"
00161 
00162 /* used to be stt_write( sttfildes ) */
00163 build_Idtable()
00164 {
00165     register int i;
00166     register sttblock *p;
00167     register Identry *Ide;   /* First free Idtable entry. */
00168     extern int Idcompare();
00169 
00170     /* Allocate Idtable, then go down each hash header chain, entering */
00171     /* strings and and setting their initial Idtable value to NIL.     */
00172         Idtable = (Identry *)alloc( sttnstrings * sizeof(Identry) );
00173         Ide = &Idtable[0];
00174         for (i = 0; i < STTHDRSZ; i++) {
00175             sttrelptr e;
00176             for (e = stthdr[i]; e != STT_NO_NEXT_ENTRY; e = (stt_abs(e)->stte_next)) {
00177                 Ide->i_sttindx = e;
00178                 Ide->i_value = NIL;
00179                 Ide++;
00180             }
00181         }
00182 #       ifdef DEBUG
00183             if (Ide != Idtable + sttnstrings) {
00184                 dbgmsg( "stt_write: error in identifier count\n" );
00185                 abort();
00186             }
00187 #       endif
00188     /* Sort Idtable by i_sttindx. */
00189         qsort(Idtable, sttnstrings, sizeof(Identry), Idcompare);
00190 
00191 }
00192 
00193 /*
00194  *  Idcompare (e1, e2)
00195  *  Identry *e1, *e2;
00196  *
00197  *  Compare the two Identries and return an integer less than, equal to, or
00198  *  greater than 0 according as e1->i_sttindx is <, ==, or > e2->i_sttindx.
00199  */
00200 Idcompare(e1, e2)
00201 Identry *e1, *e2;
00202 {
00203     return ( (int) (e1->i_sttindx - e2->i_sttindx) );
00204 }

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