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