xref: /csrg-svn/usr.bin/pascal/pxp/rmothers.c (revision 12868)
1*12868Speter static	char *sccsid = "@(#)rmothers.c	1.2 (Berkeley) 06/01/83";
212409Speter /* Copyright (c) 1983 Regents of the University of California */
312409Speter #ifdef RMOTHERS
412409Speter     /* and the rest of the file */
512409Speter 
612409Speter #include "0.h"
712409Speter #include "tree.h"
812409Speter 
912409Speter     /*
1012409Speter      *	translate extended case statements to pascal (for tex).
1112409Speter      *	don knuth should know better.  enough said.
1212409Speter      *		... peter 5/4/83
1312409Speter      *
1412409Speter      *	extended case statements have the form:
1512409Speter      *	    case expresion of
1612409Speter      *		label1,label2,...: statement1;
1712409Speter      *		...
1812409Speter      *		others: otherstatement
1912409Speter      *		end
2012409Speter      *	which i am going to translate to:
2112409Speter      *	    if expression in [ label1,label2,...] then
2212409Speter      *		case expression of
2312409Speter      *		    label1,label2,...: statement1;
2412409Speter      *		    ...
2512409Speter      *		    end
2612409Speter      *	    else otherstatement
2712409Speter      *	which has the effect that the expression will be evaluated twice.
2812409Speter      *	i've looked very briefly at all cases in tex and
2912409Speter      *	they seem to be variables or pure functions.
3012409Speter      *	for simplicity i'm assuming that the others is the last labeled
3112409Speter      *	statement, and that no other labels appear with the label others.
3212409Speter      *	this appears correct from the tex82 documentation.
3312409Speter      */
3412409Speter 
3512409Speter     /*
3612409Speter      *	given a case statement tree and the address of an others pointer,
3712409Speter      *	amputate the others statement from the case statement tree
3812409Speter      *	and hang it on the the others pointer.
3912409Speter      *
4012409Speter      *	Case statement
4112409Speter      *	r	[0]	T_CASE
4212409Speter      *		[1]	lineof "case"
4312409Speter      *		[2]	expression
4412409Speter      *		[3]	list of cased statements:
4512409Speter      *			cstat	[0]	T_CSTAT
4612409Speter      *				[1]	lineof ":"
4712409Speter      *				[2]	list of constant labels
4812409Speter      *				[3]	statement
4912409Speter      */
5012409Speter needscaseguard(r, otherspp)
5112409Speter     int	*r;
5212409Speter     int	**otherspp;
5312409Speter {
5412409Speter     int	*statlistp;
5512409Speter     int	*cutpointer;
5612409Speter     int	*lstatementp;
5712409Speter     int	*lablistp;
5812409Speter     int	*label;
5912409Speter     int	hasothers;
6012409Speter 
6112409Speter     *otherspp = NIL;
6212409Speter     hasothers = 0;
6312409Speter     if (!rmothers) {
6412409Speter 	return hasothers;
6512409Speter     }
6612409Speter     for (cutpointer = &r[3], statlistp = r[3];
6712409Speter 	 statlistp != NIL;
6812409Speter 	 cutpointer = &statlistp[2], statlistp = statlistp[2]) {
6912409Speter 	lstatementp = statlistp[1];
7012409Speter 	if (lstatementp == NIL)
7112409Speter 	    continue;
7212409Speter 	lablistp = lstatementp[2];
7312409Speter 	if (lablistp != NIL) {
7412409Speter 	    label = lablistp[1];
7512409Speter 		/* only look at the first label */
7612409Speter 	    if (label != NIL &&
7712409Speter 		label[0] == T_ID && !strcmp(label[1],"others")) {
7812409Speter 		    hasothers = 1;
7912409Speter 		    *otherspp = lstatementp[3];
8012409Speter 		    *cutpointer = NIL;
8112409Speter 		    if (statlistp[2] != NIL) {
8212409Speter 			panic("others not last case");
8312409Speter 		    }
8412409Speter 		    if (lablistp[2] != NIL) {
8512409Speter 			panic("others not only case label");
8612409Speter 		    }
8712409Speter 	    }
8812409Speter 	}
8912409Speter     }
9012409Speter     return hasothers;
9112409Speter }
9212409Speter 
9312409Speter precaseguard(r)
9412409Speter     int	*r;
9512409Speter {
9612409Speter     int	*statlistp;
9712409Speter     int	*cutpointer;
9812409Speter     int	*lstatementp;
9912409Speter     int	*lablistp;
10012409Speter     int	*label;
10112409Speter     int	hadsome;
10212409Speter     int	counter;
10312409Speter 
10412409Speter     if (!rmothers) {
10512409Speter 	return;
10612409Speter     }
10712409Speter     ppkw("if");
10812409Speter     ppspac();
10912409Speter     rvalue(r[2], NIL);
11012409Speter     ppspac();
11112409Speter     ppkw("in");
11212409Speter     ppgoin(DECL);
11312409Speter     ppnl();
11412409Speter     indent();
11512409Speter     ppsep("[");
11612409Speter     hadsome = 0;
11712409Speter     counter = 0;
11812409Speter     for (statlistp = r[3]; statlistp != NIL; statlistp = statlistp[2]) {
11912409Speter 	lstatementp = statlistp[1];
12012409Speter 	if (lstatementp == NIL)
12112409Speter 	    continue;
12212409Speter 	for (lablistp = lstatementp[2];lablistp != NIL;lablistp = lablistp[2]) {
12312409Speter 	    label = lablistp[1];
12412409Speter 	    if (hadsome) {
12512409Speter 		if (counter < 8) {
12612409Speter 		    ppsep(", ");
12712409Speter 		} else {
12812409Speter 		    ppsep(",");
12912409Speter 		    ppnl();
13012409Speter 		    indent();
13112409Speter 		    ppspac();
13212409Speter 		    counter = 0;
13312409Speter 		}
13412409Speter 	    } else {
13512409Speter 		hadsome = 1;
13612409Speter 	    }
13712409Speter 	    gconst(label);
13812409Speter 	    counter += 1;
13912409Speter 	}
14012409Speter     }
14112409Speter     ppsep("]");
14212409Speter     ppspac();
14312409Speter     ppkw("then");
14412409Speter     ppgoout(DECL);
14512409Speter     ppgoin(STAT);
14612409Speter     ppnl();
14712409Speter     indent();
14812409Speter }
14912409Speter 
15012409Speter     /*
15112409Speter      *	given an others statement, hang it on the else branch of the guard.
15212409Speter      */
15312409Speter postcaseguard(othersp)
15412409Speter     int	*othersp;
15512409Speter {
15612409Speter     if (!rmothers) {
15712409Speter 	return;
15812409Speter     }
15912409Speter     ppgoout(STAT);
16012409Speter     ppnl();
16112409Speter     indent();
162*12868Speter     if (othersp == NIL) {
163*12868Speter 	return;
164*12868Speter     }
16512409Speter     ppkw("else");
16612409Speter     ppgoin(STAT);
16712409Speter     if (othersp[0] == T_BLOCK) {
16812409Speter 	ppnl();
16912409Speter 	indent();
17012409Speter 	ppstbl1(othersp, STAT);
17112409Speter 	ppstbl2();
17212409Speter     } else {
17312409Speter 	statement(othersp);
17412409Speter     }
17512409Speter     ppgoout(STAT);
17612409Speter }
17712409Speter #endif RMOTHERS
178