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