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