xref: /csrg-svn/usr.bin/pascal/src/tree.c (revision 22198)
1*22198Sdist /*
2*22198Sdist  * Copyright (c) 1980 Regents of the University of California.
3*22198Sdist  * All rights reserved.  The Berkeley software License Agreement
4*22198Sdist  * specifies the terms and conditions for redistribution.
5*22198Sdist  */
6778Speter 
714745Sthien #ifndef lint
8*22198Sdist static char sccsid[] = "@(#)tree.c	5.1 (Berkeley) 06/05/85";
9*22198Sdist #endif not lint
10778Speter 
11778Speter #include "whoami.h"
12778Speter #include "0.h"
13778Speter 
14778Speter /*
15778Speter  * TREE SPACE DECLARATIONS
16778Speter  */
17778Speter struct tr {
18778Speter 	int	*tr_low;
19778Speter 	int	*tr_high;
20778Speter } ttab[MAXTREE], *tract;
21778Speter 
22778Speter /*
23778Speter  * The variable space is the
24778Speter  * absolute base of the tree segments.
25778Speter  * (exactly the same as ttab[0].tr_low)
26778Speter  * Spacep is maintained to point at the
27778Speter  * beginning of the next tree slot to
28778Speter  * be allocated for use by the grammar.
29778Speter  * Spacep is used "extern" by the semantic
30778Speter  * actions in pas.y.
31778Speter  * The variable tract is maintained to point
32778Speter  * at the tree segment out of which we are
33778Speter  * allocating (the active segment).
34778Speter  */
35778Speter int	*space, *spacep;
36778Speter 
37778Speter /*
38778Speter  * TREENMAX is the maximum width
39778Speter  * in words that any tree node
40778Speter  * due to the way in which the parser uses
41778Speter  * the pointer spacep.
42778Speter  */
43778Speter #define	TREENMAX	6
44778Speter 
45778Speter int	trspace[ITREE];
46778Speter int	*space	= trspace;
47778Speter int	*spacep	= trspace;
48778Speter struct	tr *tract	= ttab;
49778Speter 
50778Speter /*
51778Speter  * Inittree allocates the first tree slot
52778Speter  * and sets up the first segment descriptor.
53778Speter  * A lot of this work is actually done statically
54778Speter  * above.
55778Speter  */
56778Speter inittree()
57778Speter {
58778Speter 
59778Speter 	ttab[0].tr_low = space;
60778Speter 	ttab[0].tr_high = &space[ITREE];
61778Speter }
62778Speter 
63778Speter /*
64778Speter  * Tree builds the nodes in the
65778Speter  * parse tree. It is rarely called
66778Speter  * directly, rather calls are made
67778Speter  * to tree[12345] which supplies the
68778Speter  * first argument to save space in
69778Speter  * the code. Tree also guarantees
70778Speter  * that spacep points to the beginning
71778Speter  * of the next slot it will return,
72778Speter  * a property required by the parser
73778Speter  * which was always true before we
74778Speter  * segmented the tree space.
75778Speter  */
7615925Sthien /*VARARGS1*/
7714745Sthien struct tnode *
7814745Sthien tree(cnt, a)
79778Speter 	int cnt;
80778Speter {
81778Speter 	register int *p, *q;
82778Speter 	register int i;
83778Speter 
84778Speter 	i = cnt;
85778Speter 	p = spacep;
86778Speter 	q = &a;
87778Speter 	do
88778Speter 		*p++ = *q++;
89778Speter 	while (--i);
90778Speter 	q = spacep;
91778Speter 	spacep = p;
92778Speter 	if (p+TREENMAX >= tract->tr_high)
93778Speter 		/*
94778Speter 		 * this peek-ahead should
95778Speter 		 * save a great number of calls
96778Speter 		 * to tralloc.
97778Speter 		 */
98778Speter 		tralloc(TREENMAX);
9914745Sthien 	return ((struct tnode *) q);
100778Speter }
101778Speter 
102778Speter /*
103778Speter  * Tralloc preallocates enough
104778Speter  * space in the tree to allow
105778Speter  * the grammar to use the variable
106778Speter  * spacep, as it did before the
107778Speter  * tree was segmented.
108778Speter  */
109778Speter tralloc(howmuch)
110778Speter {
111778Speter 	register char *cp;
112778Speter 	register i;
113778Speter 
114778Speter 	if (spacep + howmuch >= tract->tr_high) {
115778Speter 		i = TRINC;
11614745Sthien 		cp = malloc((unsigned) (i * sizeof ( int )));
1171837Speter 		if (cp == 0) {
118778Speter 			yerror("Ran out of memory (tralloc)");
119778Speter 			pexit(DIED);
120778Speter 		}
12114745Sthien 		spacep = (int *) cp;
122778Speter 		tract++;
123778Speter 		if (tract >= &ttab[MAXTREE]) {
124778Speter 			yerror("Ran out of tree tables");
125778Speter 			pexit(DIED);
126778Speter 		}
12714745Sthien 		tract->tr_low = (int *) cp;
128778Speter 		tract->tr_high = tract->tr_low+i;
129778Speter 	}
130778Speter }
131778Speter 
132778Speter extern	int yylacnt;
13314745Sthien extern	struct B *bottled;
134778Speter #ifdef PXP
135778Speter #endif
136778Speter /*
137778Speter  * Free up the tree segments
138778Speter  * at the end of a block.
139778Speter  * If there is scanner lookahead,
140778Speter  * i.e. if yylacnt != 0 or there is bottled output, then we
141778Speter  * cannot free the tree space.
142778Speter  * This happens only when errors
143778Speter  * occur and the forward move extends
144778Speter  * across "units".
145778Speter  */
146778Speter trfree()
147778Speter {
148778Speter 
149778Speter 	if (yylacnt != 0 || bottled != NIL)
150778Speter 		return;
151778Speter #ifdef PXP
152778Speter 	if (needtree())
153778Speter 		return;
154778Speter #endif
155778Speter 	spacep = space;
156778Speter 	while (tract->tr_low > spacep || tract->tr_high <= spacep) {
15714745Sthien 		free((char *) tract->tr_low);
158778Speter 		tract->tr_low = NIL;
159778Speter 		tract->tr_high = NIL;
160778Speter 		tract--;
161778Speter 		if (tract < ttab)
162778Speter 			panic("ttab");
163778Speter 	}
164778Speter #ifdef PXP
165778Speter 	packtree();
166778Speter #endif
167778Speter }
168778Speter 
169778Speter /*
170778Speter  * Copystr copies a token from
171778Speter  * the "token" buffer into the
172778Speter  * tree space.
173778Speter  */
174778Speter copystr(token)
175778Speter 	register char *token;
176778Speter {
177778Speter 	register char *cp;
178778Speter 	register int i;
179778Speter 
180778Speter 	i = (strlen(token) + sizeof ( int )) & ~( ( sizeof ( int ) ) - 1 );
181778Speter 	tralloc(i / sizeof ( int ));
18214745Sthien 	(void) pstrcpy((char *) spacep, token);
18314745Sthien 	cp = (char *) spacep;
18414745Sthien 	spacep = ((int *) cp + i);
185778Speter 	tralloc(TREENMAX);
18614745Sthien 	return ((int) cp);
187778Speter }
188