|
|
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.