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