BSD 2 development
[unix-history] / src / pi0 / tree.c
CommitLineData
a0ce3a0c
BJ
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 */
8
9#include "tree.h"
10#include "0.h"
11
12/*
13 * TREE SPACE DECLARATIONS
14 */
15struct tr {
16 int *tr_low;
17 int *tr_high;
18} ttab[MAXTREE], *tract;
19
20static int *ltsnt;
21
22/*
23 * The variable space is the
24 * absolute base of the tree segments.
25 * (exactly the same as ttab[0].tr_low)
26 * Spacep is maintained to point at the
27 * beginning of the next tree slot to
28 * be allocated for use by the grammar.
29 * Spacep is used "extern" by the semantic
30 * actions in pas.y.
31 * The variable tract is maintained to point
32 * at the tree segment out of which we are
33 * allocating (the active segment).
34 */
35int *space, *spacep;
36
37/*
38 * TREENMAX is the maximum width
39 * in words that any tree node
40 * due to the way in which the parser uses
41 * the pointer spacep.
42 */
43#define TREENMAX 6
44
45#ifndef PI0
46int trspace[ITREE];
47int *space trspace;
48int *spacep trspace;
49#endif
50struct tr *tract ttab;
51
52int treemax;
53
54/*
55 * Inittree allocates the first tree slot
56 * and sets up the first segment descriptor.
57 * A lot of this work is actually done statically
58 * above.
59 */
60#ifndef PI0
61inittree()
62#else
63inittree(trspace)
64 int *trspace;
65#endif
66{
67
68#ifdef PI0
69 space = spacep = trspace;
70#endif
71 ttab[0].tr_low = space;
72 ttab[0].tr_high = &space[ITREE - 1];
73#ifndef PI1
74 ltsnt = space;
75#endif
76 treemax = ITREE;
77 *spacep = 0;
78}
79
80#ifndef PI1
81/*
82 * Tree builds the nodes in the
83 * parse tree. It is rarely called
84 * directly, rather calls are made
85 * to tree[12345] which supplies the
86 * first argument to save space in
87 * the code. Tree also guarantees
88 * that spacep points to the beginning
89 * of the next slot it will return,
90 * a property required by the parser
91 * which was always true before we
92 * segmented the tree space.
93 */
94int *
95tree(cnt, a)
96 int cnt;
97{
98 register int *p, *q;
99 register int i;
100
101 i = cnt;
102 p = spacep;
103 q = &a;
104 do
105 *p++ = *q++;
106 while (--i);
107 *p = 0;
108 q = spacep;
109 spacep = p;
110 if (p+TREENMAX >= tract->tr_high)
111 /*
112 * this peek-ahead should
113 * save a great number of calls
114 * to tralloc.
115 */
116 tralloc(TREENMAX);
117 return (q);
118}
119#else
120treev(i, q)
121 register int i, *q;
122{
123 register int *p;
124
125 p = spacep;
126 do
127 *p++ = *q++;
128 while (--i);
129 *p = 0;
130 q = spacep;
131 spacep = p;
132 if (p+TREENMAX >= tract->tr_high)
133 tralloc(TREENMAX);
134 return (q);
135}
136#endif
137/*
138 * Tralloc preallocates enough
139 * space in the tree to allow
140 * the grammar to use the variable
141 * spacep, as it did before the
142 * tree was segmented.
143 */
144tralloc(howmuch)
145{
146 register char *cp;
147 register i;
148
149 if (spacep + howmuch >= tract->tr_high) {
150 talloc(++tract);
151 spacep = tract->tr_low;
152 *spacep = 0;
153 }
154}
155
156talloc(tp)
157 register struct tr *tp;
158{
159 register char *cp;
160 register int i;
161
162 if (tp >= &ttab[MAXTREE]) {
163 yerror("Ran out of tree tables");
164 pexit(DIED);
165 }
166 if (tp->tr_low != NIL)
167 return;
168 cp = alloc(TRINC * 2);
169 if (cp == -1) {
170 yerror("Ran out of memory (talloc)");
171 pexit(DIED);
172 }
173 tp->tr_low = cp;
174 tp->tr_high = tp->tr_low + (TRINC - 1);
175 i = (tp - ttab + 1) * TRINC;
176 if (i > treemax)
177 treemax = i;
178}
179#ifndef PI1
180extern int yylacnt;
181extern bottled;
182#endif
183/*
184 * Free up the tree segments
185 * at the end of a block.
186 * If there is scanner lookahead,
187 * i.e. if yylacnt != 0 or there is bottled output, then we
188 * cannot free the tree space.
189 * This happens only when errors
190 * occur and the forward move extends
191 * across "units".
192 */
193trfree()
194{
195
196#ifndef PI1
197 if (yylacnt != 0 || bottled != NIL)
198 return;
199#endif
200#ifndef PI1
201 send(RTRFREE);
202 ltsnt = space;
203#endif
204 spacep = space;
205 while (tract->tr_low > spacep || tract->tr_high <= spacep) {
206 free(tract->tr_low);
207 tract->tr_low = NIL;
208 tract->tr_high = NIL;
209 tract--;
210 if (tract < ttab)
211 panic("ttab");
212 }
213 treemax = ITREE;
214}
215
216/*
217 * Copystr copies a token from
218 * the "token" buffer into the
219 * tree space.
220 */
221copystr(token)
222 register char *token;
223{
224 register char *cp;
225 register int i;
226
227 i = (strlen(token) + 4) & ~1;
228 tralloc(i >> 1);
229 *spacep++ = T_COPSTR;
230 i =- 2;
231 strcpy(spacep, token);
232 cp = spacep;
233 spacep = cp + i;
234 *spacep = 0;
235 tralloc(TREENMAX);
236 return (cp);
237}
238
239/* actually needed in PI1 only if DEBUG... */
240toffset(ap)
241 register int *ap;
242{
243 register struct tr *tp;
244 register int i;
245
246 if (ap == 0)
247 return (0);
248 i = TRINC;
249 for (tp = ttab; tp->tr_low != NIL && tp < &ttab[MAXTREE]; tp++) {
250 if (ap >= tp->tr_low && ap < tp->tr_high)
251 return (i + (ap - tp->tr_low));
252 i =+ TRINC;
253 }
254 return (-soffset(ap));
255}
256
257#ifndef PI1
258tsend()
259{
260 register struct tr *trp;
261 register int *ap;
262
263 ap = ltsnt;
264 for (trp = &ttab[(toffset(ltsnt) / TRINC) - 1]; trp <= tract; trp++) {
265 while (ap < trp->tr_high && *ap)
266 ap = send(RTREE, ap);
267 ltsnt = ap;
268 ap = trp[1].tr_low;
269 }
270#ifdef DEBUG
271 send(RTRCHK, toffset(ltsnt));
272#endif
273}
274#endif
275#ifdef PI1
276treloc(i)
277 register int i;
278{
279
280 if (i == 0)
281 return (0);
282 if (i < TRINC)
283 return (sreloc(-i));
284 i =- TRINC;
285 if (i >= treemax)
286 trmax(i);
287 return (ttab[i / TRINC].tr_low + i % TRINC);
288}
289
290trmax(i)
291 register int i;
292{
293 register struct tr *tp;
294
295 i = (i + TRINC) / TRINC;
296 for (tp = ttab; i > 0; tp++, i--)
297 talloc(tp);
298}
299#endif