xref: /csrg-svn/usr.bin/pascal/pxp/rmothers.c (revision 12409)
1*12409Speter static	char *sccsid = "@(#)rmothers.c	1.1 (Berkeley) 05/12/83";
2*12409Speter /* Copyright (c) 1983 Regents of the University of California */
3*12409Speter #ifdef RMOTHERS
4*12409Speter     /* and the rest of the file */
5*12409Speter 
6*12409Speter #include "0.h"
7*12409Speter #include "tree.h"
8*12409Speter 
9*12409Speter     /*
10*12409Speter      *	translate extended case statements to pascal (for tex).
11*12409Speter      *	don knuth should know better.  enough said.
12*12409Speter      *		... peter 5/4/83
13*12409Speter      *
14*12409Speter      *	extended case statements have the form:
15*12409Speter      *	    case expresion of
16*12409Speter      *		label1,label2,...: statement1;
17*12409Speter      *		...
18*12409Speter      *		others: otherstatement
19*12409Speter      *		end
20*12409Speter      *	which i am going to translate to:
21*12409Speter      *	    if expression in [ label1,label2,...] then
22*12409Speter      *		case expression of
23*12409Speter      *		    label1,label2,...: statement1;
24*12409Speter      *		    ...
25*12409Speter      *		    end
26*12409Speter      *	    else otherstatement
27*12409Speter      *	which has the effect that the expression will be evaluated twice.
28*12409Speter      *	i've looked very briefly at all cases in tex and
29*12409Speter      *	they seem to be variables or pure functions.
30*12409Speter      *	for simplicity i'm assuming that the others is the last labeled
31*12409Speter      *	statement, and that no other labels appear with the label others.
32*12409Speter      *	this appears correct from the tex82 documentation.
33*12409Speter      */
34*12409Speter 
35*12409Speter     /*
36*12409Speter      *	given a case statement tree and the address of an others pointer,
37*12409Speter      *	amputate the others statement from the case statement tree
38*12409Speter      *	and hang it on the the others pointer.
39*12409Speter      *
40*12409Speter      *	Case statement
41*12409Speter      *	r	[0]	T_CASE
42*12409Speter      *		[1]	lineof "case"
43*12409Speter      *		[2]	expression
44*12409Speter      *		[3]	list of cased statements:
45*12409Speter      *			cstat	[0]	T_CSTAT
46*12409Speter      *				[1]	lineof ":"
47*12409Speter      *				[2]	list of constant labels
48*12409Speter      *				[3]	statement
49*12409Speter      */
50*12409Speter needscaseguard(r, otherspp)
51*12409Speter     int	*r;
52*12409Speter     int	**otherspp;
53*12409Speter {
54*12409Speter     int	*statlistp;
55*12409Speter     int	*cutpointer;
56*12409Speter     int	*lstatementp;
57*12409Speter     int	*lablistp;
58*12409Speter     int	*label;
59*12409Speter     int	hasothers;
60*12409Speter 
61*12409Speter     *otherspp = NIL;
62*12409Speter     hasothers = 0;
63*12409Speter     if (!rmothers) {
64*12409Speter 	return hasothers;
65*12409Speter     }
66*12409Speter     for (cutpointer = &r[3], statlistp = r[3];
67*12409Speter 	 statlistp != NIL;
68*12409Speter 	 cutpointer = &statlistp[2], statlistp = statlistp[2]) {
69*12409Speter 	lstatementp = statlistp[1];
70*12409Speter 	if (lstatementp == NIL)
71*12409Speter 	    continue;
72*12409Speter 	lablistp = lstatementp[2];
73*12409Speter 	if (lablistp != NIL) {
74*12409Speter 	    label = lablistp[1];
75*12409Speter 		/* only look at the first label */
76*12409Speter 	    if (label != NIL &&
77*12409Speter 		label[0] == T_ID && !strcmp(label[1],"others")) {
78*12409Speter 		    hasothers = 1;
79*12409Speter 		    *otherspp = lstatementp[3];
80*12409Speter 		    *cutpointer = NIL;
81*12409Speter 		    if (statlistp[2] != NIL) {
82*12409Speter 			panic("others not last case");
83*12409Speter 		    }
84*12409Speter 		    if (lablistp[2] != NIL) {
85*12409Speter 			panic("others not only case label");
86*12409Speter 		    }
87*12409Speter 	    }
88*12409Speter 	}
89*12409Speter     }
90*12409Speter     return hasothers;
91*12409Speter }
92*12409Speter 
93*12409Speter precaseguard(r)
94*12409Speter     int	*r;
95*12409Speter {
96*12409Speter     int	*statlistp;
97*12409Speter     int	*cutpointer;
98*12409Speter     int	*lstatementp;
99*12409Speter     int	*lablistp;
100*12409Speter     int	*label;
101*12409Speter     int	hadsome;
102*12409Speter     int	counter;
103*12409Speter 
104*12409Speter     if (!rmothers) {
105*12409Speter 	return;
106*12409Speter     }
107*12409Speter     ppkw("if");
108*12409Speter     ppspac();
109*12409Speter     rvalue(r[2], NIL);
110*12409Speter     ppspac();
111*12409Speter     ppkw("in");
112*12409Speter     ppgoin(DECL);
113*12409Speter     ppnl();
114*12409Speter     indent();
115*12409Speter     ppsep("[");
116*12409Speter     hadsome = 0;
117*12409Speter     counter = 0;
118*12409Speter     for (statlistp = r[3]; statlistp != NIL; statlistp = statlistp[2]) {
119*12409Speter 	lstatementp = statlistp[1];
120*12409Speter 	if (lstatementp == NIL)
121*12409Speter 	    continue;
122*12409Speter 	for (lablistp = lstatementp[2];lablistp != NIL;lablistp = lablistp[2]) {
123*12409Speter 	    label = lablistp[1];
124*12409Speter 	    if (hadsome) {
125*12409Speter 		if (counter < 8) {
126*12409Speter 		    ppsep(", ");
127*12409Speter 		} else {
128*12409Speter 		    ppsep(",");
129*12409Speter 		    ppnl();
130*12409Speter 		    indent();
131*12409Speter 		    ppspac();
132*12409Speter 		    counter = 0;
133*12409Speter 		}
134*12409Speter 	    } else {
135*12409Speter 		hadsome = 1;
136*12409Speter 	    }
137*12409Speter 	    gconst(label);
138*12409Speter 	    counter += 1;
139*12409Speter 	}
140*12409Speter     }
141*12409Speter     ppsep("]");
142*12409Speter     ppspac();
143*12409Speter     ppkw("then");
144*12409Speter     ppgoout(DECL);
145*12409Speter     ppgoin(STAT);
146*12409Speter     ppnl();
147*12409Speter     indent();
148*12409Speter }
149*12409Speter 
150*12409Speter     /*
151*12409Speter      *	given an others statement, hang it on the else branch of the guard.
152*12409Speter      */
153*12409Speter postcaseguard(othersp)
154*12409Speter     int	*othersp;
155*12409Speter {
156*12409Speter     if (!rmothers) {
157*12409Speter 	return;
158*12409Speter     }
159*12409Speter     ppgoout(STAT);
160*12409Speter     ppnl();
161*12409Speter     indent();
162*12409Speter     ppkw("else");
163*12409Speter     ppgoin(STAT);
164*12409Speter     if (othersp[0] == T_BLOCK) {
165*12409Speter 	ppnl();
166*12409Speter 	indent();
167*12409Speter 	ppstbl1(othersp, STAT);
168*12409Speter 	ppstbl2();
169*12409Speter     } else {
170*12409Speter 	statement(othersp);
171*12409Speter     }
172*12409Speter     ppgoout(STAT);
173*12409Speter }
174*12409Speter #endif RMOTHERS
175