xref: /csrg-svn/usr.bin/pascal/src/tree.c (revision 15021)
1 /* Copyright (c) 1979 Regents of the University of California */
2 
3 #ifndef lint
4 static	char sccsid[] = "@(#)tree.c 1.4 09/19/83";
5 #endif
6 
7 #include "whoami.h"
8 #include "0.h"
9 
10 /*
11  * TREE SPACE DECLARATIONS
12  */
13 struct tr {
14 	int	*tr_low;
15 	int	*tr_high;
16 } ttab[MAXTREE], *tract;
17 
18 /*
19  * The variable space is the
20  * absolute base of the tree segments.
21  * (exactly the same as ttab[0].tr_low)
22  * Spacep is maintained to point at the
23  * beginning of the next tree slot to
24  * be allocated for use by the grammar.
25  * Spacep is used "extern" by the semantic
26  * actions in pas.y.
27  * The variable tract is maintained to point
28  * at the tree segment out of which we are
29  * allocating (the active segment).
30  */
31 int	*space, *spacep;
32 
33 /*
34  * TREENMAX is the maximum width
35  * in words that any tree node
36  * due to the way in which the parser uses
37  * the pointer spacep.
38  */
39 #define	TREENMAX	6
40 
41 int	trspace[ITREE];
42 int	*space	= trspace;
43 int	*spacep	= trspace;
44 struct	tr *tract	= ttab;
45 
46 /*
47  * Inittree allocates the first tree slot
48  * and sets up the first segment descriptor.
49  * A lot of this work is actually done statically
50  * above.
51  */
52 inittree()
53 {
54 
55 	ttab[0].tr_low = space;
56 	ttab[0].tr_high = &space[ITREE];
57 }
58 
59 /*
60  * Tree builds the nodes in the
61  * parse tree. It is rarely called
62  * directly, rather calls are made
63  * to tree[12345] which supplies the
64  * first argument to save space in
65  * the code. Tree also guarantees
66  * that spacep points to the beginning
67  * of the next slot it will return,
68  * a property required by the parser
69  * which was always true before we
70  * segmented the tree space.
71  */
72 /*VARARGS*/
73 struct tnode *
74 tree(cnt, a)
75 	int cnt;
76 {
77 	register int *p, *q;
78 	register int i;
79 
80 	i = cnt;
81 	p = spacep;
82 	q = &a;
83 	do
84 		*p++ = *q++;
85 	while (--i);
86 	q = spacep;
87 	spacep = p;
88 	if (p+TREENMAX >= tract->tr_high)
89 		/*
90 		 * this peek-ahead should
91 		 * save a great number of calls
92 		 * to tralloc.
93 		 */
94 		tralloc(TREENMAX);
95 	return ((struct tnode *) q);
96 }
97 
98 /*
99  * Tralloc preallocates enough
100  * space in the tree to allow
101  * the grammar to use the variable
102  * spacep, as it did before the
103  * tree was segmented.
104  */
105 tralloc(howmuch)
106 {
107 	register char *cp;
108 	register i;
109 
110 	if (spacep + howmuch >= tract->tr_high) {
111 		i = TRINC;
112 		cp = malloc((unsigned) (i * sizeof ( int )));
113 		if (cp == 0) {
114 			yerror("Ran out of memory (tralloc)");
115 			pexit(DIED);
116 		}
117 		spacep = (int *) cp;
118 		tract++;
119 		if (tract >= &ttab[MAXTREE]) {
120 			yerror("Ran out of tree tables");
121 			pexit(DIED);
122 		}
123 		tract->tr_low = (int *) cp;
124 		tract->tr_high = tract->tr_low+i;
125 	}
126 }
127 
128 extern	int yylacnt;
129 extern	struct B *bottled;
130 #ifdef PXP
131 #endif
132 /*
133  * Free up the tree segments
134  * at the end of a block.
135  * If there is scanner lookahead,
136  * i.e. if yylacnt != 0 or there is bottled output, then we
137  * cannot free the tree space.
138  * This happens only when errors
139  * occur and the forward move extends
140  * across "units".
141  */
142 trfree()
143 {
144 
145 	if (yylacnt != 0 || bottled != NIL)
146 		return;
147 #ifdef PXP
148 	if (needtree())
149 		return;
150 #endif
151 	spacep = space;
152 	while (tract->tr_low > spacep || tract->tr_high <= spacep) {
153 		free((char *) tract->tr_low);
154 		tract->tr_low = NIL;
155 		tract->tr_high = NIL;
156 		tract--;
157 		if (tract < ttab)
158 			panic("ttab");
159 	}
160 #ifdef PXP
161 	packtree();
162 #endif
163 }
164 
165 /*
166  * Copystr copies a token from
167  * the "token" buffer into the
168  * tree space.
169  */
170 copystr(token)
171 	register char *token;
172 {
173 	register char *cp;
174 	register int i;
175 
176 	i = (strlen(token) + sizeof ( int )) & ~( ( sizeof ( int ) ) - 1 );
177 	tralloc(i / sizeof ( int ));
178 	(void) pstrcpy((char *) spacep, token);
179 	cp = (char *) spacep;
180 	spacep = ((int *) cp + i);
181 	tralloc(TREENMAX);
182 	return ((int) cp);
183 }
184