1*5534Slinton /* Copyright (c) 1982 Regents of the University of California */ 2*5534Slinton 3*5534Slinton static char sccsid[] = "@(#)symtab.c 1.1 01/18/82"; 4*5534Slinton 5*5534Slinton /* 6*5534Slinton * symbol table implementation 7*5534Slinton */ 8*5534Slinton 9*5534Slinton #include "defs.h" 10*5534Slinton #include "symtab.h" 11*5534Slinton #include "sym.h" 12*5534Slinton #include "sym/classes.h" 13*5534Slinton #include "sym/sym.rep" 14*5534Slinton 15*5534Slinton /* 16*5534Slinton * symbol table structure definition, no deletions allowed. 17*5534Slinton */ 18*5534Slinton 19*5534Slinton #define MAXHASHSIZE 1009 /* largest allowable hash table */ 20*5534Slinton 21*5534Slinton struct symtab { 22*5534Slinton int size; 23*5534Slinton int hshsize; 24*5534Slinton SYM **symhsh; 25*5534Slinton SYM *symarray; 26*5534Slinton int symindex; 27*5534Slinton }; 28*5534Slinton 29*5534Slinton /* 30*5534Slinton * symbol table hash macro 31*5534Slinton * 32*5534Slinton * The hash value is returned through the "h" parameter which should 33*5534Slinton * an unsigned integer. The other parameters are the symbol table, "st", 34*5534Slinton * and a pointer to the string to be hashed, "name". 35*5534Slinton */ 36*5534Slinton 37*5534Slinton #define hash(h, st, name) \ 38*5534Slinton { \ 39*5534Slinton register char *cp; \ 40*5534Slinton \ 41*5534Slinton h = 0; \ 42*5534Slinton for (cp = name; *cp != '\0'; cp++) { \ 43*5534Slinton h = (h << 1) | (*cp); \ 44*5534Slinton } \ 45*5534Slinton h %= st->hshsize; \ 46*5534Slinton } 47*5534Slinton 48*5534Slinton /* 49*5534Slinton * To create a symbol table, we allocate space for the symbols and 50*5534Slinton * for a hash table that's twice as big (+1 to make it odd). 51*5534Slinton */ 52*5534Slinton 53*5534Slinton SYMTAB *st_creat(size) 54*5534Slinton int size; 55*5534Slinton { 56*5534Slinton register SYMTAB *st; 57*5534Slinton register int i; 58*5534Slinton 59*5534Slinton st = alloc(1, SYMTAB); 60*5534Slinton st->size = size; 61*5534Slinton st->hshsize = 2*size + 1; 62*5534Slinton if (st->hshsize > MAXHASHSIZE) { 63*5534Slinton st->hshsize = MAXHASHSIZE; 64*5534Slinton } 65*5534Slinton st->symhsh = alloc(st->hshsize, SYM *); 66*5534Slinton st->symarray = alloc(st->size, SYM); 67*5534Slinton st->symindex = 0; 68*5534Slinton for (i = 0; i < st->hshsize; i++) { 69*5534Slinton st->symhsh[i] = NIL; 70*5534Slinton } 71*5534Slinton return(st); 72*5534Slinton } 73*5534Slinton 74*5534Slinton st_destroy(st) 75*5534Slinton SYMTAB *st; 76*5534Slinton { 77*5534Slinton dispose(st->symhsh); 78*5534Slinton dispose(st->symarray); 79*5534Slinton dispose(st); 80*5534Slinton } 81*5534Slinton 82*5534Slinton /* 83*5534Slinton * insert a symbol into a table 84*5534Slinton */ 85*5534Slinton 86*5534Slinton SYM *st_insert(st, name) 87*5534Slinton register SYMTAB *st; 88*5534Slinton char *name; 89*5534Slinton { 90*5534Slinton register SYM *s; 91*5534Slinton register unsigned int h; 92*5534Slinton static SYM zerosym; 93*5534Slinton 94*5534Slinton if (st == NIL) { 95*5534Slinton panic("tried to insert into NIL table"); 96*5534Slinton } 97*5534Slinton if (st->symindex >= st->size) { 98*5534Slinton panic("too many symbols"); 99*5534Slinton } 100*5534Slinton hash(h, st, name); 101*5534Slinton s = &(st->symarray[st->symindex++]); 102*5534Slinton *s = zerosym; 103*5534Slinton s->symbol = name; 104*5534Slinton s->next_sym = st->symhsh[h]; 105*5534Slinton st->symhsh[h] = s; 106*5534Slinton return(s); 107*5534Slinton } 108*5534Slinton 109*5534Slinton /* 110*5534Slinton * symbol lookup 111*5534Slinton */ 112*5534Slinton 113*5534Slinton SYM *st_lookup(st, name) 114*5534Slinton SYMTAB *st; 115*5534Slinton char *name; 116*5534Slinton { 117*5534Slinton register SYM *s; 118*5534Slinton register unsigned int h; 119*5534Slinton 120*5534Slinton if (st == NIL) { 121*5534Slinton panic("tried to lookup in NIL table"); 122*5534Slinton } 123*5534Slinton hash(h, st, name); 124*5534Slinton for (s = st->symhsh[h]; s != NIL; s = s->next_sym) { 125*5534Slinton if (strcmp(s->symbol, name) == 0) { 126*5534Slinton break; 127*5534Slinton } 128*5534Slinton } 129*5534Slinton return(s); 130*5534Slinton } 131*5534Slinton 132*5534Slinton /* 133*5534Slinton * Dump out all the variables associated with the given 134*5534Slinton * procedure, function, or program at the given recursive level. 135*5534Slinton * 136*5534Slinton * This is quite inefficient. We traverse the entire symbol table 137*5534Slinton * each time we're called. The assumption is that this routine 138*5534Slinton * won't be called frequently enough to merit improved performance. 139*5534Slinton */ 140*5534Slinton 141*5534Slinton dumpvars(f, frame) 142*5534Slinton SYM *f; 143*5534Slinton FRAME *frame; 144*5534Slinton { 145*5534Slinton register SYM *s; 146*5534Slinton SYM *first, *last; 147*5534Slinton 148*5534Slinton first = symtab->symarray; 149*5534Slinton last = first + symtab->symindex - 1; 150*5534Slinton for (s = first; s <= last; s++) { 151*5534Slinton if (should_print(s, f)) { 152*5534Slinton printv(s, frame); 153*5534Slinton putchar('\n'); 154*5534Slinton } 155*5534Slinton } 156*5534Slinton } 157*5534Slinton 158*5534Slinton /* 159*5534Slinton * Create an alias for a command. 160*5534Slinton * 161*5534Slinton * We put it into the given table with block 1, which is how it 162*5534Slinton * is distinguished for printing purposes. 163*5534Slinton */ 164*5534Slinton 165*5534Slinton enter_alias(table, new, old) 166*5534Slinton SYMTAB *table; 167*5534Slinton char *new, *old; 168*5534Slinton { 169*5534Slinton SYM *s, *t; 170*5534Slinton 171*5534Slinton if ((s = st_lookup(table, old)) == NIL) { 172*5534Slinton error("%s is not a known command", old); 173*5534Slinton } 174*5534Slinton if (st_lookup(table, new) != NIL) { 175*5534Slinton error("cannot alias command names"); 176*5534Slinton } 177*5534Slinton make_keyword(table, new, s->symvalue.token.toknum); 178*5534Slinton t = st_insert(table, new); 179*5534Slinton t->blkno = 1; 180*5534Slinton t->symvalue.token.toknum = s->symvalue.token.toknum; 181*5534Slinton t->type = s; 182*5534Slinton } 183*5534Slinton 184*5534Slinton /* 185*5534Slinton * Print out the currently active aliases. 186*5534Slinton * The kludge is that the type pointer for an alias points to the 187*5534Slinton * symbol it is aliased to. 188*5534Slinton */ 189*5534Slinton 190*5534Slinton print_alias(table, name) 191*5534Slinton SYMTAB *table; 192*5534Slinton char *name; 193*5534Slinton { 194*5534Slinton SYM *s, *t; 195*5534Slinton SYM *first, *last; 196*5534Slinton 197*5534Slinton if (name != NIL) { 198*5534Slinton s = st_lookup(table, name); 199*5534Slinton if (s == NIL) { 200*5534Slinton error("\"%s\" is not an alias", name); 201*5534Slinton } 202*5534Slinton printf("%s\n", s->type->symbol); 203*5534Slinton } else { 204*5534Slinton first = table->symarray; 205*5534Slinton last = first + table->symindex - 1; 206*5534Slinton for (s = first; s <= last; s++) { 207*5534Slinton if (s->blkno == 1) { 208*5534Slinton printf("%s\t%s\n", s->symbol, s->type->symbol); 209*5534Slinton } 210*5534Slinton } 211*5534Slinton } 212*5534Slinton } 213*5534Slinton 214*5534Slinton /* 215*5534Slinton * Find a named type that points to t; return NIL if there is none. 216*5534Slinton * This is necessary because of the way pi keeps symbols. 217*5534Slinton */ 218*5534Slinton 219*5534Slinton #define NSYMS_BACK 20 /* size of local context to try */ 220*5534Slinton 221*5534Slinton LOCAL SYM *search(); 222*5534Slinton 223*5534Slinton SYM *findtype(t) 224*5534Slinton SYM *t; 225*5534Slinton { 226*5534Slinton SYM *s; 227*5534Slinton SYM *first, *last; 228*5534Slinton SYM *lower; 229*5534Slinton 230*5534Slinton first = symtab->symarray; 231*5534Slinton last = first + symtab->symindex - 1; 232*5534Slinton if ((lower = t - NSYMS_BACK) < first) { 233*5534Slinton lower = first; 234*5534Slinton } 235*5534Slinton if ((s = search(t, lower, last)) == NIL) { 236*5534Slinton s = search(t, first, last); 237*5534Slinton } 238*5534Slinton return(s); 239*5534Slinton } 240*5534Slinton 241*5534Slinton /* 242*5534Slinton * Search the symbol table from first to last, looking for a 243*5534Slinton * named type pointing to the given type symbol. 244*5534Slinton */ 245*5534Slinton 246*5534Slinton LOCAL SYM *search(t, first, last) 247*5534Slinton SYM *t; 248*5534Slinton register SYM *first, *last; 249*5534Slinton { 250*5534Slinton register SYM *s; 251*5534Slinton 252*5534Slinton for (s = first; s <= last; s++) { 253*5534Slinton if (s->class == TYPE && s->type == t && s->symbol != NIL) { 254*5534Slinton return(s); 255*5534Slinton } 256*5534Slinton } 257*5534Slinton return(NIL); 258*5534Slinton } 259