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