1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2:
3: /*
4: $Header: b2dis.c,v 1.4 85/08/22 16:54:27 timo Exp $
5: */
6:
7: #include "b.h"
8: #include "b1obj.h"
9: #include "b2par.h"
10: #include "b2nod.h"
11:
12: FILE *d_file;
13:
14: #define Indent " "
15:
16: Hidden intlet ilevel= 0;
17:
18: Hidden Procedure set_ilevel() {
19: intlet i;
20: for (i= 0; i<ilevel; i++) fprintf(d_file, Indent);
21: }
22:
23: Hidden bool new_line= Yes, in_comment= No;
24:
25: Hidden Procedure put_char(c) char c; {
26: if (new_line && !in_comment) set_ilevel();
27: putc(c, d_file);
28: new_line= No;
29: }
30:
31: Hidden Procedure put_string(s) string s; {
32: if (new_line && !in_comment) set_ilevel();
33: fprintf(d_file, "%s", s);
34: new_line= No;
35: }
36:
37: Hidden Procedure put_newline() {
38: putc('\n', d_file);
39: new_line= Yes;
40: }
41:
42: #define Putspace put_char(' ')
43:
44: /* ******************************************************************** */
45:
46: Hidden bool displ_one_line, stop_displ;
47:
48: Visible Procedure display(f, v, one_line) FILE *f; parsetree v; bool one_line; {
49: d_file= f;
50: ilevel= 0;
51: displ_one_line= one_line;
52: stop_displ= No;
53: new_line= !one_line;
54: displ(v);
55: if (!new_line) put_newline();
56: }
57:
58: /* ******************************************************************** */
59:
60: char *text[] = {
61: /* HOW_TO */ "HOW'TO #h1:#c2#b34",
62: /* YIELD */ "YIELD 2:#c3#b45",
63: /* TEST */ "TEST 2:#c3#b45",
64: /* REFINEMENT */ "0:#c1#b23",
65: /* SUITE */ "1#c23",
66:
67: /* PUT */ "PUT 0 IN 1",
68: /* INSERT */ "INSERT 0 IN 1",
69: /* REMOVE */ "REMOVE 0 FROM 1",
70: /* CHOOSE */ "CHOOSE 0 FROM 1",
71: /* DRAW */ "DRAW 0",
72: /* SET_RANDOM */ "SET'RANDOM 0",
73: /* DELETE */ "DELETE 0",
74: /* CHECK */ "CHECK 0",
75: /* SHARE */ "SHARE 0",
76:
77: /* WRITE */ "WRITE #j",
78: /* READ */ "READ 0 EG 1",
79: /* READ_RAW */ "READ 0 RAW",
80:
81: /* IF */ "IF 0:#c1#b2",
82: /* WHILE */ "WHILE 0:#c1#b2",
83: /* FOR */ "FOR 0 IN 1:#c2#b3",
84:
85: /* SELECT */ "SELECT:#c0#b1",
86: /* TEST_SUITE */ "1#d:#c2#b34",
87: /* ELSE */ "ELSE:#c1#b2",
88:
89: /* QUIT */ "QUIT",
90: /* RETURN */ "RETURN 0",
91: /* REPORT */ "REPORT 0",
92: /* SUCCEED */ "SUCCEED",
93: /* FAIL */ "FAIL",
94:
95: /* USER_COMMAND */ "#h1",
96: /* EXTENDED_COMMAND */ "0 ...",
97:
98: /* TAG */ "0",
99: /* COMPOUND */ "(0)",
100: /* COLLATERAL */ "#a0",
101: /* SELECTION */ "0[1]",
102: /* BEHEAD */ "0@1",
103: /* CURTAIL */ "0|1",
104: /* UNPARSED */ "1",
105: /* MONF */ "#l",
106: /* DYAF */ "#k",
107: /* NUMBER */ "1",
108: /* TEXT_DIS */ "#e",
109: /* TEXT_LIT */ "#f",
110: /* TEXT_CONV */ "`0`1",
111: /* ELT_DIS */ "{}",
112: /* LIST_DIS */ "{#i0}",
113: /* RANGE_DIS */ "{0..1}",
114: /* TAB_DIS */ "{#g0}",
115: /* AND */ "0 AND 1",
116: /* OR */ "0 OR 1",
117: /* NOT */ "NOT 0",
118: /* SOME_IN */ "SOME 0 IN 1 HAS 2",
119: /* EACH_IN */ "EACH 0 IN 1 HAS 2",
120: /* NO_IN */ "NO 0 IN 1 HAS 2",
121: /* SOME_PARSING */ "SOME 0 PARSING 1 HAS 2",
122: /* EACH_PARSING */ "EACH 0 PARSING 1 HAS 2",
123: /* NO_PARSING */ "NO 0 PARSING 1 HAS 2",
124: /* MONPRD */ "0 1",
125: /* DYAPRD */ "0 1 2",
126: /* LESS_THAN */ "0 < 1",
127: /* AT_MOST */ "0 <= 1",
128: /* GREATER_THAN */ "0 > 1",
129: /* AT_LEAST */ "0 >= 1",
130: /* EQUAL */ "0 = 1",
131: /* UNEQUAL */ "0 <> 1",
132: /* Nonode */ "",
133:
134: /* TAGformal */ "0",
135: /* TAGlocal */ "0",
136: /* TAGglobal */ "0",
137: /* TAGmystery */ "0",
138: /* TAGrefinement */ "0",
139: /* TAGzerfun */ "0",
140: /* TAGzerprd */ "0",
141: };
142:
143: #define Is_digit(d) ((d) >= '0' && (d) <= '9')
144: #define Fld(v, t) *Branch(v, (*(t) - '0') + First_fieldnr)
145:
146: Hidden Procedure displ(v) value v; {
147: if (Is_text(v)) put_string(strval(v));
148: else if (Is_parsetree(v)) {
149: string t= text[nodetype(v)];
150: while (*t) {
151: if (Is_digit(*t)) displ(Fld(v, t));
152: else if (*t == '#') {
153: special(v, &t);
154: if (stop_displ) return;
155: } else put_char(*t);
156: t++;
157: }
158: }
159: }
160:
161: Hidden Procedure special(v, t) parsetree v; string *t; {
162: (*t)++;
163: switch (**t) {
164: case 'a': d_collateral(Fld(v, ++*t)); break;
165: case 'b': indent(Fld(v, ++*t)); break;
166: case 'c': d_comment(Fld(v, ++*t)); break;
167: case 'd': /* test suite */
168: (*t)++;
169: if (!new_line) /* there was a command */
170: put_char(**t);
171: break;
172: case 'e': d_textdis(v); break;
173: case 'f': d_textlit(v); break;
174: case 'g': d_tabdis(Fld(v, ++*t)); break;
175: case 'h': d_actfor_compound(Fld(v, ++*t)); break;
176: case 'i': d_listdis(Fld(v, ++*t)); break;
177: case 'j': d_write(v); break;
178: case 'k': d_dyaf(v); break;
179: case 'l': d_monf(v); break;
180: }
181: }
182:
183: Hidden Procedure indent(v) parsetree v; {
184: if (displ_one_line) { stop_displ= Yes; return; }
185: ilevel++;
186: displ(v);
187: ilevel--;
188: }
189:
190: bool no_space_before_comment(v) value v; {
191: value c, t; bool b;
192: c= curtail(v, one); t= mk_text("\\");
193: b= compare(c, t) == 0;
194: release(c); release(t);
195: return b;
196: }
197:
198:
199: Procedure d_comment(v) value v; {
200: if ( v != Vnil) {
201: in_comment= Yes;
202: if (!new_line && no_space_before_comment(v)) Putspace;
203: displ(v);
204: in_comment= No;
205: }
206: if (!new_line) put_newline();
207: }
208:
209: Hidden value quote= Vnil;
210:
211: Hidden Procedure d_textdis(v) parsetree v; {
212: value s_quote= quote;
213: quote= *Branch(v, XDIS_QUOTE);
214: displ(quote);
215: displ(*Branch(v, XDIS_NEXT));
216: displ(quote);
217: quote= s_quote;
218: }
219:
220: Hidden Procedure d_textlit(v) parsetree v; {
221: value w;
222: displ(w= *Branch(v, XLIT_TEXT));
223: if (character(w)) {
224: value c= mk_text("`");
225: if (compare(quote, w) == 0 || compare(c, w) == 0) displ(w);
226: release(c);
227: }
228: displ(*Branch(v, XLIT_NEXT));
229: }
230:
231: Hidden Procedure d_tabdis(v) value v; {
232: intlet k, len= Nfields(v);
233: k_Over_len {
234: if (k>0) put_string("; ");
235: put_char('[');
236: displ(*Field(v, k));
237: put_string("]: ");
238: displ(*Field(v, ++k));
239: }
240: }
241:
242: Hidden Procedure d_collateral(v) value v; {
243: intlet k, len= Nfields(v);
244: k_Over_len {
245: if (k>0) put_string(", ");
246: displ(*Field(v, k));
247: }
248: }
249:
250: Hidden Procedure d_listdis(v) value v; {
251: intlet k, len= Nfields(v);
252: k_Over_len {
253: if (k>0) put_string("; ");
254: displ(*Field(v, k));
255: }
256: }
257:
258: Hidden Procedure d_actfor_compound(v) value v; {
259: while (v != Vnil) {
260: displ(*Branch(v, ACT_KEYW));
261: if (*Branch(v, ACT_EXPR) != Vnil) {
262: Putspace;
263: displ(*Branch(v, ACT_EXPR));
264: }
265: v= *Branch(v, ACT_NEXT);
266: if (v != Vnil) Putspace;
267: }
268: }
269:
270: Hidden Procedure d_write(v) parsetree v; {
271: value l_lines, e, r_lines;
272: l_lines= *Branch(v, WRT_L_LINES);
273: e= *Branch(v, WRT_EXPR);
274: r_lines= *Branch(v, WRT_R_LINES);
275: displ(l_lines);
276: if (e != NilTree) {
277: value n= size(l_lines);
278: if (intval(n) > 0) Putspace;
279: release(n);
280: displ(e);
281: n= size(r_lines);
282: if (intval(n) > 0) Putspace;
283: release(n);
284: }
285: displ(r_lines);
286: }
287:
288: Hidden Procedure d_dyaf(v) parsetree v; {
289: parsetree l, r; value name;
290: l= *Branch(v, DYA_LEFT);
291: r= *Branch(v, DYA_RIGHT);
292: name= *Branch(v, DYA_NAME);
293: displ(l);
294: if (is_b_tag(name) || nodetype(r) == MONF) {
295: Putspace;
296: displ(name);
297: Putspace;
298: }
299: else displ(name);
300: displ(r);
301: }
302:
303: Hidden Procedure d_monf(v) parsetree v; {
304: parsetree r; value name;
305: name= *Branch(v, MON_NAME);
306: r= *Branch(v, MON_RIGHT);
307: displ(name);
308: if (is_b_tag(name)) {
309: switch (nodetype(r)) {
310: case MONF:
311: if (!is_b_tag(*Branch(r, MON_NAME))) break;
312: case SELECTION:
313: case BEHEAD:
314: case CURTAIL:
315: case TAG:
316: case TAGformal:
317: case TAGlocal:
318: case TAGglobal:
319: case TAGmystery:
320: case TAGrefinement:
321: case TAGzerfun:
322: case TAGzerprd:
323: case NUMBER:
324: case TEXT_DIS:
325: Putspace;
326: break;
327: default:
328: break;
329: }
330: }
331: displ(r);
332: }