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
Defined functions
Defined variables
sccsid
defined in line
8;
never used