|
|
1.1 ! root 1: /* Copyright (c) 1979 Regents of the University of California */ ! 2: # ! 3: /* ! 4: * pi - Pascal interpreter code translator ! 5: * ! 6: * Charles Haley, Bill Joy UCB ! 7: * Version 1.2 November 1978 ! 8: * ! 9: * ! 10: * pxp - Pascal execution profiler ! 11: * ! 12: * Bill Joy UCB ! 13: * Version 1.2 November 1978 ! 14: */ ! 15: ! 16: #include "whoami" ! 17: #include "0.h" ! 18: #include "yy.h" ! 19: ! 20: /* ! 21: * The definition for the segmented hash tables. ! 22: */ ! 23: struct ht { ! 24: int *ht_low; ! 25: int *ht_high; ! 26: int ht_used; ! 27: } htab[MAXHASH]; ! 28: ! 29: /* ! 30: * This is the array of keywords and their ! 31: * token values, which are hashed into the table ! 32: * by inithash. ! 33: */ ! 34: struct kwtab yykey[] = { ! 35: "and", YAND, ! 36: "array", YARRAY, ! 37: "assert", YASSERT, ! 38: "begin", YBEGIN, ! 39: "case", YCASE, ! 40: "const", YCONST, ! 41: "div", YDIV, ! 42: "do", YDO, ! 43: "downto", YDOWNTO, ! 44: "else", YELSE, ! 45: "end", YEND, ! 46: "file", YFILE, ! 47: "for", YFOR, ! 48: "forward", YFORWARD, ! 49: "function", YFUNCTION, ! 50: "goto", YGOTO, ! 51: "if", YIF, ! 52: "in", YIN, ! 53: "label", YLABEL, ! 54: "mod", YMOD, ! 55: "nil", YNIL, ! 56: "not", YNOT, ! 57: "of", YOF, ! 58: "or", YOR, ! 59: "packed", YPACKED, ! 60: "procedure", YPROCEDURE, ! 61: "program", YPROG, ! 62: "record", YRECORD, ! 63: "repeat", YREPEAT, ! 64: "set", YSET, ! 65: "then", YTHEN, ! 66: "to", YTO, ! 67: "type", YTYPE, ! 68: "until", YUNTIL, ! 69: "var", YVAR, ! 70: "while", YWHILE, ! 71: "with", YWITH, ! 72: "oct", YOCT, /* non-standard Pascal */ ! 73: "hex", YHEX, /* non-standard Pascal */ ! 74: 0 ! 75: }; ! 76: ! 77: char *lastkey = &yykey[sizeof yykey/sizeof yykey[0]]; ! 78: ! 79: /* ! 80: * Inithash initializes the hash table routines ! 81: * by allocating the first hash table segment using ! 82: * an already existing memory slot. ! 83: */ ! 84: #ifndef PI0 ! 85: inithash() ! 86: #else ! 87: inithash(hshtab) ! 88: int *hshtab; ! 89: #endif ! 90: { ! 91: register int *ip; ! 92: #ifndef PI0 ! 93: static int hshtab[HASHINC]; ! 94: #endif ! 95: ! 96: htab[0].ht_low = hshtab; ! 97: htab[0].ht_high = &hshtab[HASHINC]; ! 98: for (ip = yykey; *ip; ip += 2) ! 99: hash(ip[0], 0)[0] = ip; ! 100: } ! 101: ! 102: /* ! 103: * Hash looks up the s(ymbol) argument ! 104: * in the string table, entering it if ! 105: * it is not found. If save is 0, then ! 106: * the argument string is already in ! 107: * a safe place. Otherwise, if hash is ! 108: * entering the symbol for the first time ! 109: * it will save the symbol in the string ! 110: * table using savestr. ! 111: */ ! 112: int *hash(s, save) ! 113: char *s; ! 114: int save; ! 115: { ! 116: register int *h; ! 117: register i; ! 118: register char *cp; ! 119: int *sym; ! 120: struct ht *htp; ! 121: int sh; ! 122: ! 123: /* ! 124: * The hash function is a modular hash of ! 125: * the sum of the characters with the sum ! 126: * doubled before each successive character ! 127: * is added. ! 128: */ ! 129: cp = s; ! 130: if (cp == NIL) ! 131: cp = token; /* default symbol to be hashed */ ! 132: i = 0; ! 133: while (*cp) ! 134: i = i*2 + *cp++; ! 135: sh = (i&077777) % HASHINC; ! 136: cp = s; ! 137: if (cp == NIL) ! 138: cp = token; ! 139: /* ! 140: * There are as many as MAXHASH active ! 141: * hash tables at any given point in time. ! 142: * The search starts with the first table ! 143: * and continues through the active tables ! 144: * as necessary. ! 145: */ ! 146: for (htp = htab; htp < &htab[MAXHASH]; htp++) { ! 147: if (htp->ht_low == NIL) { ! 148: cp = (char *) calloc(sizeof ( int * ), HASHINC); ! 149: if (cp == -1) { ! 150: yerror("Ran out of memory (hash)"); ! 151: pexit(DIED); ! 152: } ! 153: htp->ht_low = cp; ! 154: htp->ht_high = htp->ht_low + HASHINC; ! 155: cp = s; ! 156: if (cp == NIL) ! 157: cp = token; ! 158: } ! 159: h = htp->ht_low + sh; ! 160: /* ! 161: * quadratic rehash increment ! 162: * starts at 1 and incremented ! 163: * by two each rehash. ! 164: */ ! 165: i = 1; ! 166: do { ! 167: if (*h == 0) { ! 168: if (htp->ht_used > (HASHINC * 3)/4) ! 169: break; ! 170: htp->ht_used++; ! 171: if (save != 0) { ! 172: *h = (int) savestr(cp); ! 173: } else ! 174: *h = s; ! 175: return (h); ! 176: } ! 177: sym = *h; ! 178: if (sym < lastkey && sym >= yykey) ! 179: sym = *sym; ! 180: if (sym->pchar == *cp && strcmp(sym, cp) == 0) ! 181: return (h); ! 182: h += i; ! 183: i += 2; ! 184: if (h >= htp->ht_high) ! 185: h -= HASHINC; ! 186: } while (i < HASHINC); ! 187: } ! 188: yerror("Ran out of hash tables"); ! 189: pexit(DIED); ! 190: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.