|
|
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 "0.h"
17: #include "yy.h"
18:
19: /*
20: * The definition for the segmented hash tables.
21: */
22: struct 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: */
33: struct 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:
76: char *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: */
83: #ifndef PI0
84: inithash()
85: #else
86: inithash(hshtab)
87: int *hshtab;
88: #endif
89: {
90: register int *ip;
91: #ifndef PI0
92: static int hshtab[HASHINC];
93: #endif
94:
95: htab[0].ht_low = hshtab;
96: htab[0].ht_high = &hshtab[HASHINC];
97: for (ip = yykey; *ip; ip += 2)
98: hash(ip[0], 0)[0] = ip;
99: }
100:
101: /*
102: * Hash looks up the s(ymbol) argument
103: * in the string table, entering it if
104: * it is not found. If save is 0, then
105: * the argument string is already in
106: * a safe place. Otherwise, if hash is
107: * entering the symbol for the first time
108: * it will save the symbol in the string
109: * table using savestr.
110: */
111: int *hash(s, save)
112: char *s;
113: int save;
114: {
115: register int *h;
116: register i;
117: register char *cp;
118: int *sym;
119: struct ht *htp;
120: int sh;
121:
122: /*
123: * The hash function is a modular hash of
124: * the sum of the characters with the sum
125: * doubled before each successive character
126: * is added.
127: */
128: cp = s;
129: if (cp == NIL)
130: cp = token; /* default symbol to be hashed */
131: i = 0;
132: while (*cp)
133: i = i*2 + *cp++;
134: sh = (i&077777) % HASHINC;
135: cp = s;
136: if (cp == NIL)
137: cp = token;
138: /*
139: * There are as many as MAXHASH active
140: * hash tables at any given point in time.
141: * The search starts with the first table
142: * and continues through the active tables
143: * as necessary.
144: */
145: for (htp = htab; htp < &htab[MAXHASH]; htp++) {
146: if (htp->ht_low == NIL) {
147: cp = (char *) calloc(sizeof ( int * ), HASHINC);
148: if (cp == -1) {
149: yerror("Ran out of memory (hash)");
150: pexit(DIED);
151: }
152: htp->ht_low = cp;
153: htp->ht_high = htp->ht_low + HASHINC;
154: cp = s;
155: if (cp == NIL)
156: cp = token;
157: }
158: h = htp->ht_low + sh;
159: /*
160: * quadratic rehash increment
161: * starts at 1 and incremented
162: * by two each rehash.
163: */
164: i = 1;
165: do {
166: if (*h == 0) {
167: if (htp->ht_used > (HASHINC * 3)/4)
168: break;
169: htp->ht_used++;
170: if (save != 0) {
171: *h = (int) savestr(cp);
172: } else
173: *h = s;
174: return (h);
175: }
176: sym = *h;
177: if (sym < lastkey && sym >= yykey)
178: sym = *sym;
179: if (sym->pchar == *cp && strcmp(sym, cp) == 0)
180: return (h);
181: h += i;
182: i += 2;
183: if (h >= htp->ht_high)
184: h -= HASHINC;
185: } while (i < HASHINC);
186: }
187: yerror("Ran out of hash tables");
188: pexit(DIED);
189: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.