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