# /* * pi - Pascal interpreter code translator * * Charles Haley, Bill Joy UCB * Version 1.2 January 1979 * * * pxp - Pascal execution profiler * * Bill Joy UCB * Version 1.2 January 1979 */ #include "0.h" #include "yy.h" /* * The definition for the segmented hash tables. */ struct ht { int *ht_low; int *ht_high; int ht_used; } htab[MAXHASH]; /* * This is the array of keywords and their * token values, which are hashed into the table * by inithash. */ struct kwtab yykey[] { "and", YAND, "array", YARRAY, "assert", YASSERT, "begin", YBEGIN, "case", YCASE, "const", YCONST, "div", YDIV, "do", YDO, "downto", YDOWNTO, "else", YELSE, "end", YEND, "file", YFILE, "for", YFOR, "forward", YFORWARD, "function", YFUNCTION, "goto", YGOTO, "if", YIF, "in", YIN, "label", YLABEL, "mod", YMOD, "nil", YNIL, "not", YNOT, "of", YOF, "or", YOR, "packed", YPACKED, "procedure", YPROCEDURE, "program", YPROG, "record", YRECORD, "repeat", YREPEAT, "set", YSET, "then", YTHEN, "to", YTO, "type", YTYPE, "until", YUNTIL, "var", YVAR, "while", YWHILE, "with", YWITH, "oct", YOCT, /* non-standard Pascal */ "hex", YHEX, /* non-standard Pascal */ 0 }; char *lastkey &yykey[sizeof yykey/sizeof yykey[0]]; /* * Inithash initializes the hash table routines * by allocating the first hash table segment using * an already existing memory slot. */ #ifndef PI0 inithash() #else inithash(hshtab) int *hshtab; #endif { register int *ip; #ifndef PI0 static int hshtab[HASHINC]; #endif htab[0].ht_low = hshtab; htab[0].ht_high = &hshtab[HASHINC]; for (ip = yykey; *ip; ip =+ 2) hash(ip[0], 0)[0] = ip; } /* * Hash looks up the s(ymbol) argument * in the string table, entering it if * it is not found. If save is 0, then * the argument string is already in * a safe place. Otherwise, if hash is * entering the symbol for the first time * it will save the symbol in the string * table using savestr. */ int *hash(s, save) char *s; int save; { register int *h; register i; register char *cp; int *sym; struct ht *htp; int sh; /* * The hash function is a modular hash of * the sum of the characters with the sum * doubled before each successive character * is added. */ cp = s; if (cp == NIL) cp = token; /* default symbol to be hashed */ i = 0; while (*cp) i = i*2 + *cp++; sh = (i&077777) % HASHINC; cp = s; if (cp == NIL) cp = token; /* * There are as many as MAXHASH active * hash tables at any given point in time. * The search starts with the first table * and continues through the active tables * as necessary. */ for (htp = htab; htp < &htab[MAXHASH]; htp++) { if (htp->ht_low == NIL) { cp = calloc(2, HASHINC); if (cp == -1) { yerror("Ran out of memory (hash)"); pexit(DIED); } htp->ht_low = cp; htp->ht_high = htp->ht_low + HASHINC; cp = s; if (cp == NIL) cp = token; } h = htp->ht_low + sh; /* * quadratic rehash increment * starts at 1 and incremented * by two each rehash. */ i = 1; do { if (*h == 0) { if (htp->ht_used > (HASHINC * 3)/4) break; htp->ht_used++; if (save != 0) { *h = savestr(cp); } else *h = s; return (h); } sym = *h; if (sym < lastkey && sym >= yykey) sym = *sym; if (sym->pchar == *cp && strcmp(sym, cp) == 0) return (h); h =+ i; i =+ 2; if (h >= htp->ht_high) h =- HASHINC; } while (i < HASHINC); } yerror("Ran out of hash tables"); pexit(DIED); }