148092Sbostic /*-
2*62151Sbostic * Copyright (c) 1980, 1993
3*62151Sbostic * The Regents of the University of California. All rights reserved.
448092Sbostic *
548092Sbostic * %sccs.include.redist.c%
622566Sdist */
75534Slinton
822566Sdist #ifndef lint
9*62151Sbostic static char sccsid[] = "@(#)symtab.c 8.1 (Berkeley) 06/06/93";
1048092Sbostic #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
st_creat(size)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
st_destroy(st)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
st_insert(st,name)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
st_lookup(st,name)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
dumpvars(f,frame)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
enter_alias(table,new,old)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
print_alias(table,name)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
findtype(t)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
search(t,first,last)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