|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)rmothers.c 5.1 (Berkeley) 6/5/85"; ! 9: #endif not lint ! 10: ! 11: #ifdef RMOTHERS ! 12: /* and the rest of the file */ ! 13: ! 14: #include "0.h" ! 15: #include "tree.h" ! 16: ! 17: /* ! 18: * translate extended case statements to pascal (for tex). ! 19: * don knuth should know better. enough said. ! 20: * ... peter 5/4/83 ! 21: * ! 22: * extended case statements have the form: ! 23: * case expresion of ! 24: * label1,label2,...: statement1; ! 25: * ... ! 26: * others: otherstatement ! 27: * end ! 28: * which i am going to translate to: ! 29: * if expression in [ label1,label2,...] then ! 30: * case expression of ! 31: * label1,label2,...: statement1; ! 32: * ... ! 33: * end ! 34: * else otherstatement ! 35: * which has the effect that the expression will be evaluated twice. ! 36: * i've looked very briefly at all cases in tex and ! 37: * they seem to be variables or pure functions. ! 38: * for simplicity i'm assuming that the others is the last labeled ! 39: * statement, and that no other labels appear with the label others. ! 40: * this appears correct from the tex82 documentation. ! 41: */ ! 42: ! 43: /* ! 44: * given a case statement tree and the address of an others pointer, ! 45: * amputate the others statement from the case statement tree ! 46: * and hang it on the the others pointer. ! 47: * ! 48: * Case statement ! 49: * r [0] T_CASE ! 50: * [1] lineof "case" ! 51: * [2] expression ! 52: * [3] list of cased statements: ! 53: * cstat [0] T_CSTAT ! 54: * [1] lineof ":" ! 55: * [2] list of constant labels ! 56: * [3] statement ! 57: */ ! 58: needscaseguard(r, otherspp) ! 59: int *r; ! 60: int **otherspp; ! 61: { ! 62: int *statlistp; ! 63: int *cutpointer; ! 64: int *lstatementp; ! 65: int *lablistp; ! 66: int *label; ! 67: int hasothers; ! 68: ! 69: *otherspp = NIL; ! 70: hasothers = 0; ! 71: if (!rmothers) { ! 72: return hasothers; ! 73: } ! 74: for (cutpointer = &r[3], statlistp = r[3]; ! 75: statlistp != NIL; ! 76: cutpointer = &statlistp[2], statlistp = statlistp[2]) { ! 77: lstatementp = statlistp[1]; ! 78: if (lstatementp == NIL) ! 79: continue; ! 80: lablistp = lstatementp[2]; ! 81: if (lablistp != NIL) { ! 82: label = lablistp[1]; ! 83: /* only look at the first label */ ! 84: if (label != NIL && ! 85: label[0] == T_ID && !strcmp(label[1],"others")) { ! 86: hasothers = 1; ! 87: *otherspp = lstatementp[3]; ! 88: *cutpointer = NIL; ! 89: if (statlistp[2] != NIL) { ! 90: panic("others not last case"); ! 91: } ! 92: if (lablistp[2] != NIL) { ! 93: panic("others not only case label"); ! 94: } ! 95: } ! 96: } ! 97: } ! 98: return hasothers; ! 99: } ! 100: ! 101: precaseguard(r) ! 102: int *r; ! 103: { ! 104: int *statlistp; ! 105: int *cutpointer; ! 106: int *lstatementp; ! 107: int *lablistp; ! 108: int *label; ! 109: int hadsome; ! 110: int counter; ! 111: ! 112: if (!rmothers) { ! 113: return; ! 114: } ! 115: ppkw("if"); ! 116: ppspac(); ! 117: rvalue(r[2], NIL); ! 118: ppspac(); ! 119: ppkw("in"); ! 120: ppgoin(DECL); ! 121: ppnl(); ! 122: indent(); ! 123: ppsep("["); ! 124: hadsome = 0; ! 125: counter = 0; ! 126: for (statlistp = r[3]; statlistp != NIL; statlistp = statlistp[2]) { ! 127: lstatementp = statlistp[1]; ! 128: if (lstatementp == NIL) ! 129: continue; ! 130: for (lablistp = lstatementp[2];lablistp != NIL;lablistp = lablistp[2]) { ! 131: label = lablistp[1]; ! 132: if (hadsome) { ! 133: if (counter < 8) { ! 134: ppsep(", "); ! 135: } else { ! 136: ppsep(","); ! 137: ppnl(); ! 138: indent(); ! 139: ppspac(); ! 140: counter = 0; ! 141: } ! 142: } else { ! 143: hadsome = 1; ! 144: } ! 145: gconst(label); ! 146: counter += 1; ! 147: } ! 148: } ! 149: ppsep("]"); ! 150: ppspac(); ! 151: ppkw("then"); ! 152: ppgoout(DECL); ! 153: ppgoin(STAT); ! 154: ppnl(); ! 155: indent(); ! 156: } ! 157: ! 158: /* ! 159: * given an others statement, hang it on the else branch of the guard. ! 160: */ ! 161: postcaseguard(othersp) ! 162: int *othersp; ! 163: { ! 164: if (!rmothers) { ! 165: return; ! 166: } ! 167: ppgoout(STAT); ! 168: ppnl(); ! 169: indent(); ! 170: ppkw("else"); ! 171: ppgoin(STAT); ! 172: if (othersp == NIL) { ! 173: /* ! 174: * this will print a call to the routine ``null''. ! 175: * but it has to be checked first, or we will indirect through ! 176: * NIL to check the statement type. ! 177: */ ! 178: statement(NIL); ! 179: ppgoout(STAT); ! 180: return; ! 181: } ! 182: if (othersp[0] == T_BLOCK) { ! 183: ppnl(); ! 184: indent(); ! 185: ppstbl1(othersp, STAT); ! 186: ppstbl2(); ! 187: } else { ! 188: statement(othersp); ! 189: } ! 190: ppgoout(STAT); ! 191: } ! 192: #endif RMOTHERS
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.