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