xref: /csrg-svn/usr.bin/pascal/pxp/stat.c (revision 22239)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 static char sccsid[] = "@(#)stat.c	5.1 (Berkeley) 06/05/85";
9 #endif not lint
10 
11 /*
12  * pxp - Pascal execution profiler
13  *
14  * Bill Joy UCB
15  * Version 1.2 January 1979
16  */
17 
18 #include "0.h"
19 #include "tree.h"
20 
21 int cntstat;
22 int cnts = 3;
23 
24 statlist(r)
25 	int *r;
26 {
27 	register int *sl;
28 
29 	sl = r;
30 	if (sl != NIL)
31 		for (;;) {
32 			statement(sl[1]);
33 			sl = sl[2];
34 			if (sl == NIL)
35 				break;
36 			ppsep(";");
37 		}
38 	else
39 		statement(NIL);
40 }
41 
42 
43 statement(r)
44 	int *r;
45 {
46 	register int *s;
47 
48 	s = r;
49 top:
50 	if (cntstat) {
51 		cntstat = 0;
52 		getcnt();
53 	}
54 	if (s == NIL) {
55 		putcm();
56 		ppitem();
57 		ppid("null");
58 		return;
59 	}
60 	if (s[0] == T_REPEAT)
61 		setinfo(s[1]);
62 	else
63 		setline(s[1]);
64 	if (s[0] == T_LABEL) {
65 		cntstat = 1;
66 		ppnl();
67 		labeled(s[2]);
68 		statement(s[3]);
69 		return;
70 	}
71 	switch (s[0]) {
72 		default:
73 			panic("stat");
74 		case T_PCALL:
75 			ppitem();
76 			proc(s);
77 			break;
78 		case T_IF:
79 		case T_IFEL:
80 			ppnl();
81 			indent();
82 			ifop(s);
83 			break;
84 		case T_WHILE:
85 			ppnl();
86 			indent();
87 			whilop(s);
88 			break;
89 		case T_REPEAT:
90 			ppnl();
91 			indent();
92 			repop(s);
93 			break;
94 		case T_FORU:
95 		case T_FORD:
96 			ppnl();
97 			indent();
98 			forop(s);
99 			break;
100 		case T_BLOCK:
101 			ppnl();
102 			indent();
103 			ppstbl(s, DECL);
104 			break;
105 		case T_ASGN:
106 			ppitem();
107 			asgnop(s);
108 			break;
109 		case T_GOTO:
110 			ppitem();
111 			gotoop(s[2]);
112 			cntstat = 1;
113 			break;
114 		case T_CASE:
115 			ppnl();
116 			indent();
117 			caseop(s);
118 			break;
119 		case T_WITH:
120 			ppnl();
121 			indent();
122 			withop(s);
123 			break;
124 	}
125 	setinfo(s[1]);
126 	putcm();
127 }
128 
129 withop(s)
130 	int *s;
131 {
132 	register *p;
133 
134 	ppkw("with");
135 	ppspac();
136 	p = s[2];
137 	if (p != NIL)
138 		for (;;) {
139 			lvalue(p[1]);
140 			p = p[2];
141 			if (p == NIL)
142 				break;
143 			ppsep(", ");
144 		}
145 	else
146 		ppid("{record variable list}");
147 	ppstdo(s[3], DECL);
148 }
149 
150 asgnop(r)
151 	int *r;
152 {
153 
154 	lvalue(r[2]);
155 	ppsep(" := ");
156 	rvalue(r[3], NIL);
157 }
158 
159 forop(r)
160 	int *r;
161 {
162 	struct pxcnt scnt;
163 
164 	savecnt(&scnt);
165 	ppkw("for");
166 	ppspac();
167 	asgnop(r[2]);
168 	ppspac();
169 	ppkw(r[0] == T_FORU ? "to" : "downto");
170 	ppspac();
171 	rvalue(r[3], NIL);
172 	getcnt();
173 	ppstdo(r[4], STAT);
174 	if (rescnt(&scnt))
175 		getcnt();
176 }
177 
178 ifop(r)
179 	int *r;
180 {
181 	register *s;
182 	struct pxcnt scnt;
183 
184 	ppkw("if");
185 	ppspac();
186 	rvalue(r[2], NIL);
187 	ppspac();
188 	ppkw("then");
189 	ppspac();
190 	s = r[3];
191 	savecnt(&scnt);
192 	getcnt();
193 	if (s != NIL && s[0] == T_BLOCK)
194 		ppstbl1(s, STAT);
195 	else {
196 		ppgoin(STAT);
197 		statement(s);
198 		ppgoout(STAT);
199 	}
200 	if (r[0] == T_IFEL) {
201 		setcnt(cntof(&scnt)-nowcnt());
202 		if (s == NIL || s[0] != T_BLOCK) {
203 			ppnl();
204 			indent();
205 		} else {
206 			ppstbl2();
207 			ppspac();
208 		}
209 		s = r[4];
210 		ppkw("else");
211 		unprint();
212 		ppspac();
213 		if (s == NIL)
214 			goto burp;
215 		if (s[0] == T_BLOCK)
216 			ppstbl1(s, STAT);
217 		else if (s[0] == T_IF || s[0] == T_IFEL)
218 			ifop(s);
219 		else {
220 burp:
221 			ppgoin(STAT);
222 			statement(s);
223 			ppgoout(STAT);
224 		}
225 	}
226 	if (rescnt(&scnt))
227 		getcnt();
228 	if (r[4] != NIL)
229 		unprint();
230 	if (s != NIL && s[0] == T_BLOCK)
231 		ppstbl2();
232 }
233 
234 whilop(r)
235 	int *r;
236 {
237 	struct pxcnt scnt;
238 
239 	ppkw("while");
240 	ppspac();
241 	rvalue(r[2], NIL);
242 	savecnt(&scnt);
243 	getcnt();
244 	ppstdo(r[3], STAT);
245 	if (rescnt(&scnt))
246 		getcnt();
247 }
248 
249 repop(r)
250 	int *r;
251 {
252 	struct pxcnt scnt;
253 
254 	ppkw("repeat");
255 	ppgoin(STAT);
256 	savecnt(&scnt);
257 	getcnt();
258 	statlist(r[2]);
259 	ppgoout(DECL);
260 	ppnl();
261 	indent();
262 	ppkw("until");
263 	ppspac();
264 	rvalue(r[3], NIL);
265 	ppgoin(DECL);
266 	ppgoout(STAT);
267 	if (rescnt(&scnt))
268 		getcnt();
269 }
270 
271 ppstbl(r, m)
272 int *r;
273 {
274 	ppstbl1(r, m);
275 	ppstbl2();
276 }
277 
278 ppstbl1(r, m)
279 int *r;
280 {
281 	ppkw("begin");
282 	ppgoin(m);
283 	statlist(r[2]);
284 	ppgoout(m);
285 }
286 
287 ppstbl2()
288 {
289 	ppnl();
290 	indent();
291 	ppkw("end");
292 }
293 
294 ppstdo(r, l)
295 int *r;
296 {
297 	register *s;
298 
299 	ppspac();
300 	ppkw("do");
301 	ppspac();
302 	s = r;
303 	if (s != NIL && s[0] == T_BLOCK)
304 		ppstbl(s, l);
305 	else {
306 		ppgoin(l);
307 		statement(s);
308 		ppgoout(l);
309 	}
310 }
311