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