/* * Symbol table manipulation routines for mp. The general symbol table * organization is linked list representation with bucketing to * decrease search time. The buckets are determined by the first * character of the symbol (and thus 54 buckets are needed). * * If this implementation turns out to be a bottleneck, some other type * of bucket mapping function may be defined to reduce crowding. If this * fails to be adequate, then a completely different symbol table * mechanism could be tried (but remember that we need the ability to * delete symbols, which makes a simple hasing technique untenable). */ /* * Include global constant definitions */ #include "mpdefs.h" struct sym *sym_bkts[54]; /* Symbol table buckets */ /* * Symbol table lookup */ struct sym *lookup(symbol) register char *symbol; { register struct sym *ptr; for (ptr = sym_bkts[bkt_map(*symbol)]; ptr != NIL; ptr = ptr->next) if (lexeq(symbol, ptr->name)) break; return(ptr); } /* * Enter a symbol into the symbol table */ struct sym *sym_enter(symbol, nargs, defptr) char *symbol, *defptr; int nargs; { register int bucket; register struct sym *p, *tp; bucket = bkt_map(*symbol); if ((p = lookup(symbol)) != NIL) free(p->defptr); /* free old definition buffer */ else { /* * Allocate a new symbol table node */ p = get_mem(sizeof *sym_bkts[0]); p->next = NIL; if(sym_bkts[bucket] == NIL) sym_bkts[bucket] = p; else { for (tp = sym_bkts[bucket]; tp->next != NIL; tp = tp->next); tp->next = p; } } strcpy(p->name, symbol); /* Copy name into entry */ p->nargs = nargs; /* Set number of parameters */ p->defptr = defptr; /* Set ptr to definition block */ p->ref = 0; /* Clear reference flag */ return(p); } /* * Delete a symbol from the symbol table */ int sym_del(symbol) char *symbol; { register struct sym *p, *tp; register int bucket; bucket = bkt_map(*symbol); for (p = sym_bkts[bucket]; p != NIL; tp = p, p = p->next) if (lexeq(symbol, p->name)) { free(p->defptr); /* Free old definition */ if (p == sym_bkts[bucket]) sym_bkts[bucket] = p->next; else tp->next = p->next; free(p); /* And release node */ return(OK); } return(ERROR); } /* * Map an alphabetic character into a symbol table bucket index */ int bkt_map(c) register char c; { if(!c_alpha(c)) screech("Invalid call to bkt_map()"); if (c == '_') return(52); else if (c == '$') return(53); else if (c >= 'A' && c <= 'Z') return(c - 'A'); else return(c - ('a' - 26)); } /* Dump contents of symbol table */ sym_print() { register int i; register struct sym *p; register char *cp; printf("\n\nSymbol table dump follows:\n"); for (i = 0; i < 54; i++) for (p = sym_bkts[i]; p != NIL; p = p->next) { printf("%s<%d,%d>=", p->name, p->nargs, p->ref); for (cp = p->defptr; *cp != EOS; cp++) if (*cp & 0200) printf("#%c",(*cp & 0177)+'0'); else printf("%c", *cp); printf("\n"); } return; } /* Initialize symbol table buckets */ sym_init() { register int i; for (i = 0; i < 54; i++) sym_bkts[i] = NIL; return; }