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