xref: /csrg-svn/usr.bin/pascal/pxp/rmothers.c (revision 22237)
1*22237Sdist /*
2*22237Sdist  * Copyright (c) 1980 Regents of the University of California.
3*22237Sdist  * All rights reserved.  The Berkeley software License Agreement
4*22237Sdist  * specifies the terms and conditions for redistribution.
5*22237Sdist  */
6*22237Sdist 
7*22237Sdist #ifndef lint
8*22237Sdist static char sccsid[] = "@(#)rmothers.c	5.1 (Berkeley) 06/05/85";
9*22237Sdist #endif not lint
10*22237Sdist 
1112409Speter #ifdef RMOTHERS
1212409Speter     /* and the rest of the file */
1312409Speter 
1412409Speter #include "0.h"
1512409Speter #include "tree.h"
1612409Speter 
1712409Speter     /*
1812409Speter      *	translate extended case statements to pascal (for tex).
1912409Speter      *	don knuth should know better.  enough said.
2012409Speter      *		... peter 5/4/83
2112409Speter      *
2212409Speter      *	extended case statements have the form:
2312409Speter      *	    case expresion of
2412409Speter      *		label1,label2,...: statement1;
2512409Speter      *		...
2612409Speter      *		others: otherstatement
2712409Speter      *		end
2812409Speter      *	which i am going to translate to:
2912409Speter      *	    if expression in [ label1,label2,...] then
3012409Speter      *		case expression of
3112409Speter      *		    label1,label2,...: statement1;
3212409Speter      *		    ...
3312409Speter      *		    end
3412409Speter      *	    else otherstatement
3512409Speter      *	which has the effect that the expression will be evaluated twice.
3612409Speter      *	i've looked very briefly at all cases in tex and
3712409Speter      *	they seem to be variables or pure functions.
3812409Speter      *	for simplicity i'm assuming that the others is the last labeled
3912409Speter      *	statement, and that no other labels appear with the label others.
4012409Speter      *	this appears correct from the tex82 documentation.
4112409Speter      */
4212409Speter 
4312409Speter     /*
4412409Speter      *	given a case statement tree and the address of an others pointer,
4512409Speter      *	amputate the others statement from the case statement tree
4612409Speter      *	and hang it on the the others pointer.
4712409Speter      *
4812409Speter      *	Case statement
4912409Speter      *	r	[0]	T_CASE
5012409Speter      *		[1]	lineof "case"
5112409Speter      *		[2]	expression
5212409Speter      *		[3]	list of cased statements:
5312409Speter      *			cstat	[0]	T_CSTAT
5412409Speter      *				[1]	lineof ":"
5512409Speter      *				[2]	list of constant labels
5612409Speter      *				[3]	statement
5712409Speter      */
5812409Speter needscaseguard(r, otherspp)
5912409Speter     int	*r;
6012409Speter     int	**otherspp;
6112409Speter {
6212409Speter     int	*statlistp;
6312409Speter     int	*cutpointer;
6412409Speter     int	*lstatementp;
6512409Speter     int	*lablistp;
6612409Speter     int	*label;
6712409Speter     int	hasothers;
6812409Speter 
6912409Speter     *otherspp = NIL;
7012409Speter     hasothers = 0;
7112409Speter     if (!rmothers) {
7212409Speter 	return hasothers;
7312409Speter     }
7412409Speter     for (cutpointer = &r[3], statlistp = r[3];
7512409Speter 	 statlistp != NIL;
7612409Speter 	 cutpointer = &statlistp[2], statlistp = statlistp[2]) {
7712409Speter 	lstatementp = statlistp[1];
7812409Speter 	if (lstatementp == NIL)
7912409Speter 	    continue;
8012409Speter 	lablistp = lstatementp[2];
8112409Speter 	if (lablistp != NIL) {
8212409Speter 	    label = lablistp[1];
8312409Speter 		/* only look at the first label */
8412409Speter 	    if (label != NIL &&
8512409Speter 		label[0] == T_ID && !strcmp(label[1],"others")) {
8612409Speter 		    hasothers = 1;
8712409Speter 		    *otherspp = lstatementp[3];
8812409Speter 		    *cutpointer = NIL;
8912409Speter 		    if (statlistp[2] != NIL) {
9012409Speter 			panic("others not last case");
9112409Speter 		    }
9212409Speter 		    if (lablistp[2] != NIL) {
9312409Speter 			panic("others not only case label");
9412409Speter 		    }
9512409Speter 	    }
9612409Speter 	}
9712409Speter     }
9812409Speter     return hasothers;
9912409Speter }
10012409Speter 
10112409Speter precaseguard(r)
10212409Speter     int	*r;
10312409Speter {
10412409Speter     int	*statlistp;
10512409Speter     int	*cutpointer;
10612409Speter     int	*lstatementp;
10712409Speter     int	*lablistp;
10812409Speter     int	*label;
10912409Speter     int	hadsome;
11012409Speter     int	counter;
11112409Speter 
11212409Speter     if (!rmothers) {
11312409Speter 	return;
11412409Speter     }
11512409Speter     ppkw("if");
11612409Speter     ppspac();
11712409Speter     rvalue(r[2], NIL);
11812409Speter     ppspac();
11912409Speter     ppkw("in");
12012409Speter     ppgoin(DECL);
12112409Speter     ppnl();
12212409Speter     indent();
12312409Speter     ppsep("[");
12412409Speter     hadsome = 0;
12512409Speter     counter = 0;
12612409Speter     for (statlistp = r[3]; statlistp != NIL; statlistp = statlistp[2]) {
12712409Speter 	lstatementp = statlistp[1];
12812409Speter 	if (lstatementp == NIL)
12912409Speter 	    continue;
13012409Speter 	for (lablistp = lstatementp[2];lablistp != NIL;lablistp = lablistp[2]) {
13112409Speter 	    label = lablistp[1];
13212409Speter 	    if (hadsome) {
13312409Speter 		if (counter < 8) {
13412409Speter 		    ppsep(", ");
13512409Speter 		} else {
13612409Speter 		    ppsep(",");
13712409Speter 		    ppnl();
13812409Speter 		    indent();
13912409Speter 		    ppspac();
14012409Speter 		    counter = 0;
14112409Speter 		}
14212409Speter 	    } else {
14312409Speter 		hadsome = 1;
14412409Speter 	    }
14512409Speter 	    gconst(label);
14612409Speter 	    counter += 1;
14712409Speter 	}
14812409Speter     }
14912409Speter     ppsep("]");
15012409Speter     ppspac();
15112409Speter     ppkw("then");
15212409Speter     ppgoout(DECL);
15312409Speter     ppgoin(STAT);
15412409Speter     ppnl();
15512409Speter     indent();
15612409Speter }
15712409Speter 
15812409Speter     /*
15912409Speter      *	given an others statement, hang it on the else branch of the guard.
16012409Speter      */
16112409Speter postcaseguard(othersp)
16212409Speter     int	*othersp;
16312409Speter {
16412409Speter     if (!rmothers) {
16512409Speter 	return;
16612409Speter     }
16712409Speter     ppgoout(STAT);
16812409Speter     ppnl();
16912409Speter     indent();
17014131Speter     ppkw("else");
17114131Speter     ppgoin(STAT);
17212868Speter     if (othersp == NIL) {
17314131Speter 	    /*
17414131Speter 	     *	this will print a call to the routine ``null''.
17514131Speter 	     *	but it has to be checked first, or we will indirect through
17614131Speter 	     *	NIL to check the statement type.
17714131Speter 	     */
17814131Speter 	statement(NIL);
17914131Speter 	ppgoout(STAT);
18012868Speter 	return;
18112868Speter     }
18212409Speter     if (othersp[0] == T_BLOCK) {
18312409Speter 	ppnl();
18412409Speter 	indent();
18512409Speter 	ppstbl1(othersp, STAT);
18612409Speter 	ppstbl2();
18712409Speter     } else {
18812409Speter 	statement(othersp);
18912409Speter     }
19012409Speter     ppgoout(STAT);
19112409Speter }
19212409Speter #endif RMOTHERS
193