15534Slinton /* Copyright (c) 1982 Regents of the University of California */ 25534Slinton 3*6870Slinton static char sccsid[] = "@(#)symtab.c 1.2 05/19/82"; 45534Slinton 55534Slinton /* 6*6870Slinton * Symbol table implementation. 75534Slinton */ 85534Slinton 95534Slinton #include "defs.h" 105534Slinton #include "symtab.h" 115534Slinton #include "sym.h" 125534Slinton #include "sym/classes.h" 135534Slinton #include "sym/sym.rep" 145534Slinton 155534Slinton /* 16*6870Slinton * The symbol table structure is currently assumes no deletions. 175534Slinton */ 185534Slinton 19*6870Slinton #define MAXHASHSIZE 1009 /* largest allowable hash table */ 205534Slinton 215534Slinton struct symtab { 22*6870Slinton int size; 23*6870Slinton int hshsize; 24*6870Slinton SYM **symhsh; 25*6870Slinton SYM *symarray; 26*6870Slinton int symindex; 275534Slinton }; 285534Slinton 295534Slinton /* 30*6870Slinton * Macro to hash a string. 315534Slinton * 325534Slinton * The hash value is returned through the "h" parameter which should 335534Slinton * an unsigned integer. The other parameters are the symbol table, "st", 345534Slinton * and a pointer to the string to be hashed, "name". 355534Slinton */ 365534Slinton 375534Slinton #define hash(h, st, name) \ 385534Slinton { \ 39*6870Slinton register char *cp; \ 405534Slinton \ 41*6870Slinton h = 0; \ 42*6870Slinton for (cp = name; *cp != '\0'; cp++) { \ 43*6870Slinton h = (h << 1) | (*cp); \ 44*6870Slinton } \ 45*6870Slinton h %= st->hshsize; \ 465534Slinton } 475534Slinton 485534Slinton /* 495534Slinton * To create a symbol table, we allocate space for the symbols and 505534Slinton * for a hash table that's twice as big (+1 to make it odd). 515534Slinton */ 525534Slinton 535534Slinton SYMTAB *st_creat(size) 545534Slinton int size; 555534Slinton { 56*6870Slinton register SYMTAB *st; 57*6870Slinton register int i; 585534Slinton 59*6870Slinton st = alloc(1, SYMTAB); 60*6870Slinton st->size = size; 61*6870Slinton st->hshsize = 2*size + 1; 62*6870Slinton if (st->hshsize > MAXHASHSIZE) { 63*6870Slinton st->hshsize = MAXHASHSIZE; 64*6870Slinton } 65*6870Slinton st->symhsh = alloc(st->hshsize, SYM *); 66*6870Slinton st->symarray = alloc(st->size, SYM); 67*6870Slinton st->symindex = 0; 68*6870Slinton for (i = 0; i < st->hshsize; i++) { 69*6870Slinton st->symhsh[i] = NIL; 70*6870Slinton } 71*6870Slinton return(st); 725534Slinton } 735534Slinton 745534Slinton st_destroy(st) 755534Slinton SYMTAB *st; 765534Slinton { 77*6870Slinton dispose(st->symhsh); 78*6870Slinton dispose(st->symarray); 79*6870Slinton dispose(st); 805534Slinton } 815534Slinton 825534Slinton /* 835534Slinton * insert a symbol into a table 845534Slinton */ 855534Slinton 865534Slinton SYM *st_insert(st, name) 875534Slinton register SYMTAB *st; 885534Slinton char *name; 895534Slinton { 90*6870Slinton register SYM *s; 91*6870Slinton register unsigned int h; 92*6870Slinton static SYM zerosym; 935534Slinton 94*6870Slinton if (st == NIL) { 95*6870Slinton panic("tried to insert into NIL table"); 96*6870Slinton } 97*6870Slinton if (st->symindex >= st->size) { 98*6870Slinton panic("too many symbols"); 99*6870Slinton } 100*6870Slinton hash(h, st, name); 101*6870Slinton s = &(st->symarray[st->symindex++]); 102*6870Slinton *s = zerosym; 103*6870Slinton s->symbol = name; 104*6870Slinton s->next_sym = st->symhsh[h]; 105*6870Slinton st->symhsh[h] = s; 106*6870Slinton return(s); 1075534Slinton } 1085534Slinton 1095534Slinton /* 1105534Slinton * symbol lookup 1115534Slinton */ 1125534Slinton 1135534Slinton SYM *st_lookup(st, name) 1145534Slinton SYMTAB *st; 1155534Slinton char *name; 1165534Slinton { 117*6870Slinton register SYM *s; 118*6870Slinton register unsigned int h; 1195534Slinton 120*6870Slinton if (st == NIL) { 121*6870Slinton panic("tried to lookup in NIL table"); 122*6870Slinton } 123*6870Slinton hash(h, st, name); 124*6870Slinton for (s = st->symhsh[h]; s != NIL; s = s->next_sym) { 125*6870Slinton if (strcmp(s->symbol, name) == 0) { 126*6870Slinton break; 1275534Slinton } 128*6870Slinton } 129*6870Slinton return(s); 1305534Slinton } 1315534Slinton 1325534Slinton /* 1335534Slinton * Dump out all the variables associated with the given 1345534Slinton * procedure, function, or program at the given recursive level. 1355534Slinton * 1365534Slinton * This is quite inefficient. We traverse the entire symbol table 1375534Slinton * each time we're called. The assumption is that this routine 1385534Slinton * won't be called frequently enough to merit improved performance. 1395534Slinton */ 1405534Slinton 1415534Slinton dumpvars(f, frame) 1425534Slinton SYM *f; 1435534Slinton FRAME *frame; 1445534Slinton { 145*6870Slinton register SYM *s; 146*6870Slinton SYM *first, *last; 1475534Slinton 148*6870Slinton first = symtab->symarray; 149*6870Slinton last = first + symtab->symindex - 1; 150*6870Slinton for (s = first; s <= last; s++) { 151*6870Slinton if (should_print(s, f)) { 152*6870Slinton printv(s, frame); 153*6870Slinton putchar('\n'); 1545534Slinton } 155*6870Slinton } 1565534Slinton } 1575534Slinton 1585534Slinton /* 1595534Slinton * Create an alias for a command. 1605534Slinton * 1615534Slinton * We put it into the given table with block 1, which is how it 1625534Slinton * is distinguished for printing purposes. 1635534Slinton */ 1645534Slinton 1655534Slinton enter_alias(table, new, old) 1665534Slinton SYMTAB *table; 1675534Slinton char *new, *old; 1685534Slinton { 169*6870Slinton SYM *s, *t; 1705534Slinton 171*6870Slinton if ((s = st_lookup(table, old)) == NIL) { 172*6870Slinton error("%s is not a known command", old); 173*6870Slinton } 174*6870Slinton if (st_lookup(table, new) != NIL) { 175*6870Slinton error("cannot alias command names"); 176*6870Slinton } 177*6870Slinton make_keyword(table, new, s->symvalue.token.toknum); 178*6870Slinton t = st_insert(table, new); 179*6870Slinton t->blkno = 1; 180*6870Slinton t->symvalue.token.toknum = s->symvalue.token.toknum; 181*6870Slinton t->type = s; 1825534Slinton } 1835534Slinton 1845534Slinton /* 1855534Slinton * Print out the currently active aliases. 1865534Slinton * The kludge is that the type pointer for an alias points to the 1875534Slinton * symbol it is aliased to. 1885534Slinton */ 1895534Slinton 1905534Slinton print_alias(table, name) 1915534Slinton SYMTAB *table; 1925534Slinton char *name; 1935534Slinton { 194*6870Slinton SYM *s, *t; 195*6870Slinton SYM *first, *last; 1965534Slinton 197*6870Slinton if (name != NIL) { 198*6870Slinton s = st_lookup(table, name); 199*6870Slinton if (s == NIL) { 200*6870Slinton error("\"%s\" is not an alias", name); 2015534Slinton } 202*6870Slinton printf("%s\n", s->type->symbol); 203*6870Slinton } else { 204*6870Slinton first = table->symarray; 205*6870Slinton last = first + table->symindex - 1; 206*6870Slinton for (s = first; s <= last; s++) { 207*6870Slinton if (s->blkno == 1) { 208*6870Slinton printf("%s\t%s\n", s->symbol, s->type->symbol); 209*6870Slinton } 210*6870Slinton } 211*6870Slinton } 2125534Slinton } 2135534Slinton 2145534Slinton /* 2155534Slinton * Find a named type that points to t; return NIL if there is none. 2165534Slinton * This is necessary because of the way pi keeps symbols. 2175534Slinton */ 2185534Slinton 219*6870Slinton #define NSYMS_BACK 20 /* size of local context to try */ 2205534Slinton 2215534Slinton LOCAL SYM *search(); 2225534Slinton 2235534Slinton SYM *findtype(t) 2245534Slinton SYM *t; 2255534Slinton { 226*6870Slinton SYM *s; 227*6870Slinton SYM *first, *last; 228*6870Slinton SYM *lower; 2295534Slinton 230*6870Slinton first = symtab->symarray; 231*6870Slinton last = first + symtab->symindex - 1; 232*6870Slinton if ((lower = t - NSYMS_BACK) < first) { 233*6870Slinton lower = first; 234*6870Slinton } 235*6870Slinton if ((s = search(t, lower, last)) == NIL) { 236*6870Slinton s = search(t, first, last); 237*6870Slinton } 238*6870Slinton return(s); 2395534Slinton } 2405534Slinton 2415534Slinton /* 2425534Slinton * Search the symbol table from first to last, looking for a 2435534Slinton * named type pointing to the given type symbol. 2445534Slinton */ 2455534Slinton 2465534Slinton LOCAL SYM *search(t, first, last) 2475534Slinton SYM *t; 2485534Slinton register SYM *first, *last; 2495534Slinton { 250*6870Slinton register SYM *s; 2515534Slinton 252*6870Slinton for (s = first; s <= last; s++) { 253*6870Slinton if (s->class == TYPE && s->type == t && s->symbol != NIL) { 254*6870Slinton return(s); 2555534Slinton } 256*6870Slinton } 257*6870Slinton return(NIL); 2585534Slinton } 259