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