1*48092Sbostic /*- 2*48092Sbostic * Copyright (c) 1980 The Regents of the University of California. 3*48092Sbostic * All rights reserved. 4*48092Sbostic * 5*48092Sbostic * %sccs.include.redist.c% 622566Sdist */ 75534Slinton 822566Sdist #ifndef lint 9*48092Sbostic static char sccsid[] = "@(#)symtab.c 5.3 (Berkeley) 04/16/91"; 10*48092Sbostic #endif /* not lint */ 115534Slinton 125534Slinton /* 136870Slinton * Symbol table implementation. 145534Slinton */ 155534Slinton 165534Slinton #include "defs.h" 175534Slinton #include "symtab.h" 185534Slinton #include "sym.h" 195534Slinton #include "sym/classes.h" 205534Slinton #include "sym/sym.rep" 215534Slinton 225534Slinton /* 236870Slinton * The symbol table structure is currently assumes no deletions. 245534Slinton */ 255534Slinton 266870Slinton #define MAXHASHSIZE 1009 /* largest allowable hash table */ 275534Slinton 285534Slinton struct symtab { 296870Slinton int size; 306870Slinton int hshsize; 316870Slinton SYM **symhsh; 326870Slinton SYM *symarray; 336870Slinton int symindex; 345534Slinton }; 355534Slinton 365534Slinton /* 376870Slinton * Macro to hash a string. 385534Slinton * 395534Slinton * The hash value is returned through the "h" parameter which should 405534Slinton * an unsigned integer. The other parameters are the symbol table, "st", 415534Slinton * and a pointer to the string to be hashed, "name". 425534Slinton */ 435534Slinton 445534Slinton #define hash(h, st, name) \ 455534Slinton { \ 466870Slinton register char *cp; \ 475534Slinton \ 486870Slinton h = 0; \ 496870Slinton for (cp = name; *cp != '\0'; cp++) { \ 506870Slinton h = (h << 1) | (*cp); \ 516870Slinton } \ 526870Slinton h %= st->hshsize; \ 535534Slinton } 545534Slinton 555534Slinton /* 565534Slinton * To create a symbol table, we allocate space for the symbols and 575534Slinton * for a hash table that's twice as big (+1 to make it odd). 585534Slinton */ 595534Slinton 605534Slinton SYMTAB *st_creat(size) 615534Slinton int size; 625534Slinton { 636870Slinton register SYMTAB *st; 646870Slinton register int i; 655534Slinton 666870Slinton st = alloc(1, SYMTAB); 676870Slinton st->size = size; 686870Slinton st->hshsize = 2*size + 1; 696870Slinton if (st->hshsize > MAXHASHSIZE) { 706870Slinton st->hshsize = MAXHASHSIZE; 716870Slinton } 726870Slinton st->symhsh = alloc(st->hshsize, SYM *); 736870Slinton st->symarray = alloc(st->size, SYM); 746870Slinton st->symindex = 0; 756870Slinton for (i = 0; i < st->hshsize; i++) { 766870Slinton st->symhsh[i] = NIL; 776870Slinton } 786870Slinton return(st); 795534Slinton } 805534Slinton 815534Slinton st_destroy(st) 825534Slinton SYMTAB *st; 835534Slinton { 846870Slinton dispose(st->symhsh); 856870Slinton dispose(st->symarray); 866870Slinton dispose(st); 875534Slinton } 885534Slinton 895534Slinton /* 905534Slinton * insert a symbol into a table 915534Slinton */ 925534Slinton 935534Slinton SYM *st_insert(st, name) 945534Slinton register SYMTAB *st; 955534Slinton char *name; 965534Slinton { 976870Slinton register SYM *s; 986870Slinton register unsigned int h; 996870Slinton static SYM zerosym; 1005534Slinton 1016870Slinton if (st == NIL) { 1026870Slinton panic("tried to insert into NIL table"); 1036870Slinton } 1046870Slinton if (st->symindex >= st->size) { 1056870Slinton panic("too many symbols"); 1066870Slinton } 1076870Slinton hash(h, st, name); 1086870Slinton s = &(st->symarray[st->symindex++]); 1096870Slinton *s = zerosym; 1106870Slinton s->symbol = name; 1116870Slinton s->next_sym = st->symhsh[h]; 1126870Slinton st->symhsh[h] = s; 1136870Slinton return(s); 1145534Slinton } 1155534Slinton 1165534Slinton /* 1175534Slinton * symbol lookup 1185534Slinton */ 1195534Slinton 1205534Slinton SYM *st_lookup(st, name) 1215534Slinton SYMTAB *st; 1225534Slinton char *name; 1235534Slinton { 1246870Slinton register SYM *s; 1256870Slinton register unsigned int h; 1265534Slinton 1276870Slinton if (st == NIL) { 1286870Slinton panic("tried to lookup in NIL table"); 1296870Slinton } 1306870Slinton hash(h, st, name); 1316870Slinton for (s = st->symhsh[h]; s != NIL; s = s->next_sym) { 1326870Slinton if (strcmp(s->symbol, name) == 0) { 1336870Slinton break; 1345534Slinton } 1356870Slinton } 1366870Slinton return(s); 1375534Slinton } 1385534Slinton 1395534Slinton /* 1405534Slinton * Dump out all the variables associated with the given 1415534Slinton * procedure, function, or program at the given recursive level. 1425534Slinton * 1435534Slinton * This is quite inefficient. We traverse the entire symbol table 1445534Slinton * each time we're called. The assumption is that this routine 1455534Slinton * won't be called frequently enough to merit improved performance. 1465534Slinton */ 1475534Slinton 1485534Slinton dumpvars(f, frame) 1495534Slinton SYM *f; 1505534Slinton FRAME *frame; 1515534Slinton { 1526870Slinton register SYM *s; 1536870Slinton SYM *first, *last; 1545534Slinton 1556870Slinton first = symtab->symarray; 1566870Slinton last = first + symtab->symindex - 1; 1576870Slinton for (s = first; s <= last; s++) { 1586870Slinton if (should_print(s, f)) { 1596870Slinton printv(s, frame); 1606870Slinton putchar('\n'); 1615534Slinton } 1626870Slinton } 1635534Slinton } 1645534Slinton 1655534Slinton /* 1665534Slinton * Create an alias for a command. 1675534Slinton * 1685534Slinton * We put it into the given table with block 1, which is how it 1695534Slinton * is distinguished for printing purposes. 1705534Slinton */ 1715534Slinton 1725534Slinton enter_alias(table, new, old) 1735534Slinton SYMTAB *table; 1745534Slinton char *new, *old; 1755534Slinton { 1766870Slinton SYM *s, *t; 1775534Slinton 1786870Slinton if ((s = st_lookup(table, old)) == NIL) { 1796870Slinton error("%s is not a known command", old); 1806870Slinton } 1816870Slinton if (st_lookup(table, new) != NIL) { 1826870Slinton error("cannot alias command names"); 1836870Slinton } 1846870Slinton make_keyword(table, new, s->symvalue.token.toknum); 1856870Slinton t = st_insert(table, new); 1866870Slinton t->blkno = 1; 1876870Slinton t->symvalue.token.toknum = s->symvalue.token.toknum; 1886870Slinton t->type = s; 1895534Slinton } 1905534Slinton 1915534Slinton /* 1925534Slinton * Print out the currently active aliases. 1935534Slinton * The kludge is that the type pointer for an alias points to the 1945534Slinton * symbol it is aliased to. 1955534Slinton */ 1965534Slinton 1975534Slinton print_alias(table, name) 1985534Slinton SYMTAB *table; 1995534Slinton char *name; 2005534Slinton { 20130851Smckusick SYM *s; 2026870Slinton SYM *first, *last; 2035534Slinton 2046870Slinton if (name != NIL) { 2056870Slinton s = st_lookup(table, name); 2066870Slinton if (s == NIL) { 2076870Slinton error("\"%s\" is not an alias", name); 2085534Slinton } 2096870Slinton printf("%s\n", s->type->symbol); 2106870Slinton } else { 2116870Slinton first = table->symarray; 2126870Slinton last = first + table->symindex - 1; 2136870Slinton for (s = first; s <= last; s++) { 2146870Slinton if (s->blkno == 1) { 2156870Slinton printf("%s\t%s\n", s->symbol, s->type->symbol); 2166870Slinton } 2176870Slinton } 2186870Slinton } 2195534Slinton } 2205534Slinton 2215534Slinton /* 2225534Slinton * Find a named type that points to t; return NIL if there is none. 2235534Slinton * This is necessary because of the way pi keeps symbols. 2245534Slinton */ 2255534Slinton 2266870Slinton #define NSYMS_BACK 20 /* size of local context to try */ 2275534Slinton 2285534Slinton LOCAL SYM *search(); 2295534Slinton 2305534Slinton SYM *findtype(t) 2315534Slinton SYM *t; 2325534Slinton { 2336870Slinton SYM *s; 2346870Slinton SYM *first, *last; 2356870Slinton SYM *lower; 2365534Slinton 2376870Slinton first = symtab->symarray; 2386870Slinton last = first + symtab->symindex - 1; 2396870Slinton if ((lower = t - NSYMS_BACK) < first) { 2406870Slinton lower = first; 2416870Slinton } 2426870Slinton if ((s = search(t, lower, last)) == NIL) { 2436870Slinton s = search(t, first, last); 2446870Slinton } 2456870Slinton return(s); 2465534Slinton } 2475534Slinton 2485534Slinton /* 2495534Slinton * Search the symbol table from first to last, looking for a 2505534Slinton * named type pointing to the given type symbol. 2515534Slinton */ 2525534Slinton 2535534Slinton LOCAL SYM *search(t, first, last) 2545534Slinton SYM *t; 2555534Slinton register SYM *first, *last; 2565534Slinton { 2576870Slinton register SYM *s; 2585534Slinton 2596870Slinton for (s = first; s <= last; s++) { 2606870Slinton if (s->class == TYPE && s->type == t && s->symbol != NIL) { 2616870Slinton return(s); 2625534Slinton } 2636870Slinton } 2646870Slinton return(NIL); 2655534Slinton } 266