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