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