122566Sdist /* 222566Sdist * Copyright (c) 1980 Regents of the University of California. 322566Sdist * All rights reserved. The Berkeley software License Agreement 422566Sdist * specifies the terms and conditions for redistribution. 522566Sdist */ 65534Slinton 722566Sdist #ifndef lint 8*30851Smckusick static char sccsid[] = "@(#)symtab.c 5.2 (Berkeley) 04/07/87"; 922566Sdist #endif not lint 105534Slinton 115534Slinton /* 126870Slinton * Symbol table implementation. 135534Slinton */ 145534Slinton 155534Slinton #include "defs.h" 165534Slinton #include "symtab.h" 175534Slinton #include "sym.h" 185534Slinton #include "sym/classes.h" 195534Slinton #include "sym/sym.rep" 205534Slinton 215534Slinton /* 226870Slinton * The symbol table structure is currently assumes no deletions. 235534Slinton */ 245534Slinton 256870Slinton #define MAXHASHSIZE 1009 /* largest allowable hash table */ 265534Slinton 275534Slinton struct symtab { 286870Slinton int size; 296870Slinton int hshsize; 306870Slinton SYM **symhsh; 316870Slinton SYM *symarray; 326870Slinton int symindex; 335534Slinton }; 345534Slinton 355534Slinton /* 366870Slinton * Macro to hash a string. 375534Slinton * 385534Slinton * The hash value is returned through the "h" parameter which should 395534Slinton * an unsigned integer. The other parameters are the symbol table, "st", 405534Slinton * and a pointer to the string to be hashed, "name". 415534Slinton */ 425534Slinton 435534Slinton #define hash(h, st, name) \ 445534Slinton { \ 456870Slinton register char *cp; \ 465534Slinton \ 476870Slinton h = 0; \ 486870Slinton for (cp = name; *cp != '\0'; cp++) { \ 496870Slinton h = (h << 1) | (*cp); \ 506870Slinton } \ 516870Slinton h %= st->hshsize; \ 525534Slinton } 535534Slinton 545534Slinton /* 555534Slinton * To create a symbol table, we allocate space for the symbols and 565534Slinton * for a hash table that's twice as big (+1 to make it odd). 575534Slinton */ 585534Slinton 595534Slinton SYMTAB *st_creat(size) 605534Slinton int size; 615534Slinton { 626870Slinton register SYMTAB *st; 636870Slinton register int i; 645534Slinton 656870Slinton st = alloc(1, SYMTAB); 666870Slinton st->size = size; 676870Slinton st->hshsize = 2*size + 1; 686870Slinton if (st->hshsize > MAXHASHSIZE) { 696870Slinton st->hshsize = MAXHASHSIZE; 706870Slinton } 716870Slinton st->symhsh = alloc(st->hshsize, SYM *); 726870Slinton st->symarray = alloc(st->size, SYM); 736870Slinton st->symindex = 0; 746870Slinton for (i = 0; i < st->hshsize; i++) { 756870Slinton st->symhsh[i] = NIL; 766870Slinton } 776870Slinton return(st); 785534Slinton } 795534Slinton 805534Slinton st_destroy(st) 815534Slinton SYMTAB *st; 825534Slinton { 836870Slinton dispose(st->symhsh); 846870Slinton dispose(st->symarray); 856870Slinton dispose(st); 865534Slinton } 875534Slinton 885534Slinton /* 895534Slinton * insert a symbol into a table 905534Slinton */ 915534Slinton 925534Slinton SYM *st_insert(st, name) 935534Slinton register SYMTAB *st; 945534Slinton char *name; 955534Slinton { 966870Slinton register SYM *s; 976870Slinton register unsigned int h; 986870Slinton static SYM zerosym; 995534Slinton 1006870Slinton if (st == NIL) { 1016870Slinton panic("tried to insert into NIL table"); 1026870Slinton } 1036870Slinton if (st->symindex >= st->size) { 1046870Slinton panic("too many symbols"); 1056870Slinton } 1066870Slinton hash(h, st, name); 1076870Slinton s = &(st->symarray[st->symindex++]); 1086870Slinton *s = zerosym; 1096870Slinton s->symbol = name; 1106870Slinton s->next_sym = st->symhsh[h]; 1116870Slinton st->symhsh[h] = s; 1126870Slinton return(s); 1135534Slinton } 1145534Slinton 1155534Slinton /* 1165534Slinton * symbol lookup 1175534Slinton */ 1185534Slinton 1195534Slinton SYM *st_lookup(st, name) 1205534Slinton SYMTAB *st; 1215534Slinton char *name; 1225534Slinton { 1236870Slinton register SYM *s; 1246870Slinton register unsigned int h; 1255534Slinton 1266870Slinton if (st == NIL) { 1276870Slinton panic("tried to lookup in NIL table"); 1286870Slinton } 1296870Slinton hash(h, st, name); 1306870Slinton for (s = st->symhsh[h]; s != NIL; s = s->next_sym) { 1316870Slinton if (strcmp(s->symbol, name) == 0) { 1326870Slinton break; 1335534Slinton } 1346870Slinton } 1356870Slinton return(s); 1365534Slinton } 1375534Slinton 1385534Slinton /* 1395534Slinton * Dump out all the variables associated with the given 1405534Slinton * procedure, function, or program at the given recursive level. 1415534Slinton * 1425534Slinton * This is quite inefficient. We traverse the entire symbol table 1435534Slinton * each time we're called. The assumption is that this routine 1445534Slinton * won't be called frequently enough to merit improved performance. 1455534Slinton */ 1465534Slinton 1475534Slinton dumpvars(f, frame) 1485534Slinton SYM *f; 1495534Slinton FRAME *frame; 1505534Slinton { 1516870Slinton register SYM *s; 1526870Slinton SYM *first, *last; 1535534Slinton 1546870Slinton first = symtab->symarray; 1556870Slinton last = first + symtab->symindex - 1; 1566870Slinton for (s = first; s <= last; s++) { 1576870Slinton if (should_print(s, f)) { 1586870Slinton printv(s, frame); 1596870Slinton putchar('\n'); 1605534Slinton } 1616870Slinton } 1625534Slinton } 1635534Slinton 1645534Slinton /* 1655534Slinton * Create an alias for a command. 1665534Slinton * 1675534Slinton * We put it into the given table with block 1, which is how it 1685534Slinton * is distinguished for printing purposes. 1695534Slinton */ 1705534Slinton 1715534Slinton enter_alias(table, new, old) 1725534Slinton SYMTAB *table; 1735534Slinton char *new, *old; 1745534Slinton { 1756870Slinton SYM *s, *t; 1765534Slinton 1776870Slinton if ((s = st_lookup(table, old)) == NIL) { 1786870Slinton error("%s is not a known command", old); 1796870Slinton } 1806870Slinton if (st_lookup(table, new) != NIL) { 1816870Slinton error("cannot alias command names"); 1826870Slinton } 1836870Slinton make_keyword(table, new, s->symvalue.token.toknum); 1846870Slinton t = st_insert(table, new); 1856870Slinton t->blkno = 1; 1866870Slinton t->symvalue.token.toknum = s->symvalue.token.toknum; 1876870Slinton t->type = s; 1885534Slinton } 1895534Slinton 1905534Slinton /* 1915534Slinton * Print out the currently active aliases. 1925534Slinton * The kludge is that the type pointer for an alias points to the 1935534Slinton * symbol it is aliased to. 1945534Slinton */ 1955534Slinton 1965534Slinton print_alias(table, name) 1975534Slinton SYMTAB *table; 1985534Slinton char *name; 1995534Slinton { 200*30851Smckusick SYM *s; 2016870Slinton SYM *first, *last; 2025534Slinton 2036870Slinton if (name != NIL) { 2046870Slinton s = st_lookup(table, name); 2056870Slinton if (s == NIL) { 2066870Slinton error("\"%s\" is not an alias", name); 2075534Slinton } 2086870Slinton printf("%s\n", s->type->symbol); 2096870Slinton } else { 2106870Slinton first = table->symarray; 2116870Slinton last = first + table->symindex - 1; 2126870Slinton for (s = first; s <= last; s++) { 2136870Slinton if (s->blkno == 1) { 2146870Slinton printf("%s\t%s\n", s->symbol, s->type->symbol); 2156870Slinton } 2166870Slinton } 2176870Slinton } 2185534Slinton } 2195534Slinton 2205534Slinton /* 2215534Slinton * Find a named type that points to t; return NIL if there is none. 2225534Slinton * This is necessary because of the way pi keeps symbols. 2235534Slinton */ 2245534Slinton 2256870Slinton #define NSYMS_BACK 20 /* size of local context to try */ 2265534Slinton 2275534Slinton LOCAL SYM *search(); 2285534Slinton 2295534Slinton SYM *findtype(t) 2305534Slinton SYM *t; 2315534Slinton { 2326870Slinton SYM *s; 2336870Slinton SYM *first, *last; 2346870Slinton SYM *lower; 2355534Slinton 2366870Slinton first = symtab->symarray; 2376870Slinton last = first + symtab->symindex - 1; 2386870Slinton if ((lower = t - NSYMS_BACK) < first) { 2396870Slinton lower = first; 2406870Slinton } 2416870Slinton if ((s = search(t, lower, last)) == NIL) { 2426870Slinton s = search(t, first, last); 2436870Slinton } 2446870Slinton return(s); 2455534Slinton } 2465534Slinton 2475534Slinton /* 2485534Slinton * Search the symbol table from first to last, looking for a 2495534Slinton * named type pointing to the given type symbol. 2505534Slinton */ 2515534Slinton 2525534Slinton LOCAL SYM *search(t, first, last) 2535534Slinton SYM *t; 2545534Slinton register SYM *first, *last; 2555534Slinton { 2566870Slinton register SYM *s; 2575534Slinton 2586870Slinton for (s = first; s <= last; s++) { 2596870Slinton if (s->class == TYPE && s->type == t && s->symbol != NIL) { 2606870Slinton return(s); 2615534Slinton } 2626870Slinton } 2636870Slinton return(NIL); 2645534Slinton } 265