ignore .lib and .exe
[prop.git] / prop-src / printgen.cc
blob3ec0ef9216f2409b74d943dcefb73087ea865dfa
1 ///////////////////////////////////////////////////////////////////////////////
2 // This file is generated automatically using Prop (version 2.3.6),
3 // last updated on Nov 2, 1999.
4 // The original source file is "printgen.pcc".
5 ///////////////////////////////////////////////////////////////////////////////
7 #define PROP_QUARK_USED
8 #include <propdefs.h>
9 ///////////////////////////////////////////////////////////////////////////////
10 // Quark literals
11 ///////////////////////////////////////////////////////////////////////////////
12 static const Quark _p_r_i_n_t_g_e_nco_c_c_Q1("obj__");
13 #line 1 "printgen.pcc"
14 ///////////////////////////////////////////////////////////////////////////////
16 // This file implements the pretty printer generator.
18 ///////////////////////////////////////////////////////////////////////////////
19 #include <ctype.h>
20 #include <string.h>
21 #include <AD/strings/quark.h>
22 #include <AD/strings/charesc.h>
23 #include "ir.h"
24 #include "ast.h"
25 #include "datatype.h"
26 #include "type.h"
27 #include "matchcom.h"
28 #include "list.h"
29 #include "codegen.h"
31 ///////////////////////////////////////////////////////////////////////////////
33 // Method to generate the interface definition for the pretty printers
35 ///////////////////////////////////////////////////////////////////////////////
36 void DatatypeClass::generate_print_interface(CodeGen& C)
40 void DatatypeHierarchy::generate_print_interface(CodeGen& C)
42 C.pr("%^%/"
43 "%^//"
44 "%^// Pretty printing methods for %s%V"
45 "%^//"
46 "%^%/"
47 "%^class PrettyOStream;"
48 "%^%Hextern std::ostream& operator<<(std::ostream&, %s%v);"
49 "%^%Hextern PrettyOStream& operator<<(PrettyOStream&, %s%v);",
50 datatype_name, parameters,
51 parameters, datatype_name, parameters,
52 parameters, datatype_name, parameters
56 ///////////////////////////////////////////////////////////////////////////////
58 // Method to generate the pretty printer implementation.
60 ///////////////////////////////////////////////////////////////////////////////
61 void DatatypeClass::generate_print_implementation(CodeGen&, Tys, DefKind)
65 void DatatypeHierarchy::generate_print_implementation
66 (CodeGen& C, Tys tys, DefKind k)
68 Ty ty = NOty;
70 #line 56 "printgen.pcc"
71 #line 59 "printgen.pcc"
73 if (datatype_ty) {
74 switch (datatype_ty->tag__) {
75 case a_Ty::tag_TYCONty: {
76 if (boxed(((Ty_TYCONty *)datatype_ty)->_1)) {
77 switch (((Ty_TYCONty *)datatype_ty)->_1->tag__) {
78 case a_TyCon::tag_DATATYPEtycon: {
79 #line 57 "printgen.pcc"
80 ty = apply_ty(((TyCon_DATATYPEtycon *)((Ty_TYCONty *)datatype_ty)->_1)->polyty,tys);
81 #line 57 "printgen.pcc"
82 } break;
83 default: {
84 L1:; } break;
86 } else { goto L1; }
87 } break;
88 default: { goto L1; } break;
90 } else { goto L1; }
92 #line 59 "printgen.pcc"
93 #line 59 "printgen.pcc"
96 C.pr("%^%/"
97 "%^//"
98 "%^// Pretty printing methods for %s%P"
99 "%^//"
100 "%^%/",
101 datatype_name, tys);
104 // Generate the ostream based method
106 C.pr("%^std::ostream& operator << (std::ostream& strm__, %t obj__)", ty, "");
108 if (k == EXTERNAL_INSTANTIATION)
109 C.pr("%^{ PrettyOStream S(strm__); S << obj__; return strm__; }\n\n");
110 else
111 C.pr(";");
114 // Generate the PrettyOStream based method
116 C.pr("%^PrettyOStream& operator << (PrettyOStream& strm__, %t obj__)",
117 ty,"");
119 if (k == EXTERNAL_INSTANTIATION)
120 C.pr("%^{%+");
121 else
122 C.pr(";");
124 if (k != EXTERNAL_INSTANTIATION) return;
126 if (arity > 1) C.pr("%^switch (%U)%^{%+", IDexp(
127 #line 91 "printgen.pcc"
128 #line 91 "printgen.pcc"
129 _p_r_i_n_t_g_e_nco_c_c_Q1
130 #line 91 "printgen.pcc"
131 #line 91 "printgen.pcc"
132 ), ty);
134 for (int i = 0; i < arity; i++)
135 { Cons term = constructor_terms[i];
136 if (arity > 1) C.pr("%^case %*: %+", term, true);
137 generate_printer(C,tys,k,ty,term);
138 if (arity > 1) C.pr("%^break;%-");
141 if (arity > 1) C.pr("%-%^}");
142 C.pr("%^return strm__;"
143 "%-%^}");
145 C.pr("\n\n");
149 ///////////////////////////////////////////////////////////////////////////////
151 // Pretty printer for one single variant
153 ///////////////////////////////////////////////////////////////////////////////
154 void DatatypeHierarchy::generate_printer
155 (CodeGen& C, Tys tys, DefKind k, Ty mono_ty, Cons cons)
157 #line 115 "printgen.pcc"
158 #line 126 "printgen.pcc"
160 if (cons) {
161 #line 117 "printgen.pcc"
162 cons_arg_ty = cons->ty == NOty ? NOty : apply_ty(cons->cons_ty,tys);
163 if (cons->print_formats ==
164 #line 118 "printgen.pcc"
165 #line 118 "printgen.pcc"
166 nil_1_
167 #line 118 "printgen.pcc"
168 #line 118 "printgen.pcc"
170 { generate_default_printer(C,tys,k,mono_ty,cons,cons_arg_ty);
171 } else
172 { generate_formatted_printer(C,tys,k,mono_ty,
173 cons,cons_arg_ty,cons->print_formats);
176 #line 124 "printgen.pcc"
177 } else {}
179 #line 126 "printgen.pcc"
180 #line 126 "printgen.pcc"
184 ///////////////////////////////////////////////////////////////////////////////
186 // Method to generate a default pretty printer
188 ///////////////////////////////////////////////////////////////////////////////
189 void DatatypeHierarchy::generate_default_printer
190 (CodeGen& C, Tys tys, DefKind k, Ty mono_ty, Cons cons, Ty ty)
191 { PrintFormats fmt =
192 #line 136 "printgen.pcc"
193 #line 136 "printgen.pcc"
194 nil_1_
195 #line 136 "printgen.pcc"
196 #line 136 "printgen.pcc"
199 #line 137 "printgen.pcc"
200 #line 182 "printgen.pcc"
202 Ty _V1 = deref_all(ty);
203 if (cons) {
204 if (_V1) {
205 switch (_V1->tag__) {
206 case a_Ty::tag_TYCONty: {
207 if (boxed(((Ty_TYCONty *)_V1)->_1)) {
208 switch (((Ty_TYCONty *)_V1)->_1->tag__) {
209 case a_TyCon::tag_RECORDtycon: {
210 #line 167 "printgen.pcc"
211 Ids ls; Tys ts;
212 fmt =
213 #line 168 "printgen.pcc"
214 #line 168 "printgen.pcc"
215 list_1_(TERMsym('{'),list_1_(TERMSTRINGsym(cons->name)))
216 #line 168 "printgen.pcc"
217 #line 168 "printgen.pcc"
219 Bool comma = false;
220 for(ls = ((TyCon_RECORDtycon *)((Ty_TYCONty *)_V1)->_1)->_1, ts = ((Ty_TYCONty *)_V1)->_2; ls && ts; ls = ls->_2, ts = ts->_2)
221 { if (comma) fmt =
222 #line 171 "printgen.pcc"
223 #line 171 "printgen.pcc"
224 list_1_(TERMsym(','),fmt)
225 #line 171 "printgen.pcc"
226 #line 171 "printgen.pcc"
228 fmt =
229 #line 172 "printgen.pcc"
230 #line 172 "printgen.pcc"
231 list_1_(SPECIALsym('_'),list_1_(TERMsym('='),list_1_(TERMSTRINGsym(ls->_1),fmt)))
232 #line 172 "printgen.pcc"
233 #line 172 "printgen.pcc"
235 comma = true;
237 fmt =
238 #line 175 "printgen.pcc"
239 #line 175 "printgen.pcc"
240 list_1_(TERMsym('}'),fmt)
241 #line 175 "printgen.pcc"
242 #line 175 "printgen.pcc"
244 fmt = rev(fmt);
246 #line 177 "printgen.pcc"
247 } break;
248 default: {
249 L2:;
250 #line 179 "printgen.pcc"
251 fmt =
252 #line 179 "printgen.pcc"
253 #line 179 "printgen.pcc"
254 list_1_(TERMSTRINGsym(cons->name),list_1_(TERMsym('('),list_1_(SPECIALsym('_'),list_1_(TERMsym(')')))))
255 #line 179 "printgen.pcc"
256 #line 179 "printgen.pcc"
259 #line 180 "printgen.pcc"
260 } break;
262 } else {
263 switch ((int)((Ty_TYCONty *)_V1)->_1) {
264 case ((int)TUPLEtycon): {
265 if (((Ty_TYCONty *)_V1)->_2) {
266 if (((Ty_TYCONty *)_V1)->_2->_2) {
267 if (((Ty_TYCONty *)_V1)->_2->_2->_2) {
268 L3:;
269 #line 145 "printgen.pcc"
270 Tys ts;
271 fmt =
272 #line 146 "printgen.pcc"
273 #line 146 "printgen.pcc"
274 list_1_(TERMsym(')'))
275 #line 146 "printgen.pcc"
276 #line 146 "printgen.pcc"
278 Bool comma = false;
279 for(ts = ((Ty_TYCONty *)_V1)->_2; ts; ts = ts->_2)
280 { if (comma) fmt =
281 #line 149 "printgen.pcc"
282 #line 149 "printgen.pcc"
283 list_1_(TERMsym(','),fmt)
284 #line 149 "printgen.pcc"
285 #line 149 "printgen.pcc"
287 fmt =
288 #line 150 "printgen.pcc"
289 #line 150 "printgen.pcc"
290 list_1_(SPECIALsym('_'),fmt)
291 #line 150 "printgen.pcc"
292 #line 150 "printgen.pcc"
294 comma = true;
296 fmt =
297 #line 153 "printgen.pcc"
298 #line 153 "printgen.pcc"
299 list_1_(TERMSTRINGsym(cons->name),list_1_(TERMsym('('),fmt))
300 #line 153 "printgen.pcc"
301 #line 153 "printgen.pcc"
304 #line 154 "printgen.pcc"
305 } else {
306 if (
307 #line 142 "printgen.pcc"
308 is_list_constructor(cons->name)
309 #line 142 "printgen.pcc"
312 #line 143 "printgen.pcc"
313 fmt =
314 #line 143 "printgen.pcc"
315 #line 143 "printgen.pcc"
316 list_1_(SPECIALsym('['),list_1_(SPECIALsym('L'),list_1_(SPECIALsym(']'))))
317 #line 143 "printgen.pcc"
318 #line 143 "printgen.pcc"
320 #line 143 "printgen.pcc"
321 } else {
322 goto L3; }
324 } else { goto L3; }
325 } else { goto L3; }
326 } break;
327 case ((int)EXTUPLEtycon): {
328 #line 156 "printgen.pcc"
329 Tys ts;
330 fmt =
331 #line 157 "printgen.pcc"
332 #line 157 "printgen.pcc"
333 list_1_(TERMsym(')'))
334 #line 157 "printgen.pcc"
335 #line 157 "printgen.pcc"
337 Bool comma = false;
338 for(ts = ((Ty_TYCONty *)_V1)->_2; ts; ts = ts->_2)
339 { if (comma) fmt =
340 #line 160 "printgen.pcc"
341 #line 160 "printgen.pcc"
342 list_1_(TERMsym(','),fmt)
343 #line 160 "printgen.pcc"
344 #line 160 "printgen.pcc"
346 fmt =
347 #line 161 "printgen.pcc"
348 #line 161 "printgen.pcc"
349 list_1_(SPECIALsym('_'),fmt)
350 #line 161 "printgen.pcc"
351 #line 161 "printgen.pcc"
353 comma = true;
355 fmt =
356 #line 164 "printgen.pcc"
357 #line 164 "printgen.pcc"
358 list_1_(TERMSTRINGsym(cons->name),list_1_(TERMsym('('),fmt))
359 #line 164 "printgen.pcc"
360 #line 164 "printgen.pcc"
363 #line 165 "printgen.pcc"
364 } break;
365 default: { goto L2; } break;
368 } break;
369 default: { goto L2; } break;
371 } else {
372 if (
373 #line 138 "printgen.pcc"
374 is_list_constructor(cons->name)
375 #line 138 "printgen.pcc"
378 #line 139 "printgen.pcc"
379 fmt =
380 #line 139 "printgen.pcc"
381 #line 139 "printgen.pcc"
382 list_1_(SPECIALsym('['),list_1_(SPECIALsym(']')))
383 #line 139 "printgen.pcc"
384 #line 139 "printgen.pcc"
386 #line 139 "printgen.pcc"
387 } else {
389 #line 141 "printgen.pcc"
390 fmt =
391 #line 141 "printgen.pcc"
392 #line 141 "printgen.pcc"
393 list_1_(TERMSTRINGsym(cons->name))
394 #line 141 "printgen.pcc"
395 #line 141 "printgen.pcc"
397 #line 141 "printgen.pcc"
400 } else {}
402 #line 182 "printgen.pcc"
403 #line 182 "printgen.pcc"
405 generate_formatted_printer(C,tys,k,mono_ty,cons,ty,fmt);
408 ///////////////////////////////////////////////////////////////////////////////
410 // Method to generate a formatted pretty printer
412 ///////////////////////////////////////////////////////////////////////////////
413 void DatatypeHierarchy::generate_formatted_printer
414 (CodeGen& C, Tys tys, DefKind k, Ty mono_ty,
415 Cons cons, Ty ty, PrintFormats fmt)
416 { Tys tyl =
417 #line 194 "printgen.pcc"
418 #line 194 "printgen.pcc"
419 nil_1_
420 #line 194 "printgen.pcc"
421 #line 194 "printgen.pcc"
423 Ids label_list =
424 #line 195 "printgen.pcc"
425 #line 195 "printgen.pcc"
426 nil_1_
427 #line 195 "printgen.pcc"
428 #line 195 "printgen.pcc"
432 #line 197 "printgen.pcc"
433 #line 201 "printgen.pcc"
435 Ty _V2 = deref_all(ty);
436 if (_V2) {
437 switch (_V2->tag__) {
438 case a_Ty::tag_TYCONty: {
439 if (boxed(((Ty_TYCONty *)_V2)->_1)) {
440 switch (((Ty_TYCONty *)_V2)->_1->tag__) {
441 case a_TyCon::tag_RECORDtycon: {
442 #line 200 "printgen.pcc"
443 tyl = ((Ty_TYCONty *)_V2)->_2; label_list = ((TyCon_RECORDtycon *)((Ty_TYCONty *)_V2)->_1)->_1;
444 #line 200 "printgen.pcc"
445 } break;
446 default: {
447 L4:;
448 #line 201 "printgen.pcc"
449 tyl =
450 #line 201 "printgen.pcc"
451 #line 201 "printgen.pcc"
452 list_1_(_V2)
453 #line 201 "printgen.pcc"
454 #line 201 "printgen.pcc"
456 #line 201 "printgen.pcc"
457 } break;
459 } else {
460 switch ((int)((Ty_TYCONty *)_V2)->_1) {
461 case ((int)TUPLEtycon): {
462 #line 199 "printgen.pcc"
463 tyl = ((Ty_TYCONty *)_V2)->_2;
464 #line 199 "printgen.pcc"
465 } break;
466 default: { goto L4; } break;
469 } break;
470 default: { goto L4; } break;
472 } else {
473 #line 198 "printgen.pcc"
474 tyl =
475 #line 198 "printgen.pcc"
476 #line 198 "printgen.pcc"
477 nil_1_
478 #line 198 "printgen.pcc"
479 #line 198 "printgen.pcc"
481 #line 198 "printgen.pcc"
484 #line 202 "printgen.pcc"
485 #line 202 "printgen.pcc"
488 int N = length(tyl);
489 int index = 1;
491 Exp exp = select(IDexp("obj__"),cons,mono_ty);
493 for_each (ProductionSymbol, f, fmt)
495 #line 210 "printgen.pcc"
496 #line 276 "printgen.pcc"
498 switch (f->tag__) {
499 case a_ProductionSymbol::tag_TERMsym: {
500 #line 215 "printgen.pcc"
501 C.pr("%^strm__ << '%s';", print_char(((ProductionSymbol_TERMsym *)f)->TERMsym));
502 #line 215 "printgen.pcc"
503 } break;
504 case a_ProductionSymbol::tag_TERMSTRINGsym: {
505 #line 217 "printgen.pcc"
506 int len = strlen(((ProductionSymbol_TERMSTRINGsym *)f)->TERMSTRINGsym);
507 if (len == 1)
508 { C.pr("%^strm__ << '%s';",((ProductionSymbol_TERMSTRINGsym *)f)->TERMSTRINGsym);
509 } else if (len == 3 && ((ProductionSymbol_TERMSTRINGsym *)f)->TERMSTRINGsym[0] == '"' && ((ProductionSymbol_TERMSTRINGsym *)f)->TERMSTRINGsym[2] == '"' &&
510 ! isalnum(((ProductionSymbol_TERMSTRINGsym *)f)->TERMSTRINGsym[1]))
511 { C.pr("%^strm__ << '%s';",print_char(((ProductionSymbol_TERMSTRINGsym *)f)->TERMSTRINGsym[1]));
512 } else
513 { Id quote = ((ProductionSymbol_TERMSTRINGsym *)f)->TERMSTRINGsym[0] == '"' ? "" : "\"";
514 C.pr("%^strm__ << %s%s%s;",quote,((ProductionSymbol_TERMSTRINGsym *)f)->TERMSTRINGsym,quote);
517 #line 227 "printgen.pcc"
518 } break;
519 case a_ProductionSymbol::tag_NONTERMsym: {
520 #line 211 "printgen.pcc"
521 gen_print_field(C,DOTexp(exp,((ProductionSymbol_NONTERMsym *)f)->NONTERMsym),component_ty(ty,((ProductionSymbol_NONTERMsym *)f)->NONTERMsym));
522 #line 211 "printgen.pcc"
523 } break;
524 case a_ProductionSymbol::tag_POSNONTERMsym: {
525 #line 213 "printgen.pcc"
526 gen_print_field(C,DOTexp(exp,index_of(((ProductionSymbol_POSNONTERMsym *)f)->POSNONTERMsym)),component_ty(ty,((ProductionSymbol_POSNONTERMsym *)f)->POSNONTERMsym));
527 #line 213 "printgen.pcc"
528 } break;
529 case a_ProductionSymbol::tag_SPECIALsym: {
530 switch (((ProductionSymbol_SPECIALsym *)f)->SPECIALsym) {
531 case '/': {
532 #line 255 "printgen.pcc"
533 C.pr("%^strm__.newline().tab();");
534 #line 255 "printgen.pcc"
535 } break;
536 case 'L': {
537 #line 235 "printgen.pcc"
538 char nil_name[4];
539 nil_name[0] = '#'; nil_name[1] = cons->name[1];
540 nil_name[2] = cons->name[5]; nil_name[3] = '\0';
541 Cons nil = lookup_cons(nil_name);
542 C.pr("%^{%+"
543 "%^int comma__ = 0;"
544 "%^for (%S%P * l__ = obj__; l__ != %S; l__ = %e)"
545 "%^{%+"
546 "%^if (comma__) strm__ << ',';"
547 "%^strm__ << %e;"
548 "%^comma__ = 1;"
549 "%-%^}"
550 "%-%^}",
551 class_name, tys, nil->name,
552 DOTexp(select(IDexp("l__"),cons,mono_ty),"_2"),
553 DOTexp(select(IDexp("l__"),cons,mono_ty),"_1")
556 #line 252 "printgen.pcc"
557 } break;
558 case '[': {
559 #line 229 "printgen.pcc"
560 C.pr("%^strm__ << '%c';", (int)cons->name[1]);
561 #line 229 "printgen.pcc"
562 } break;
563 case ']': {
564 #line 231 "printgen.pcc"
565 char c = cons->name[strlen(cons->name)-1];
566 C.pr("%^strm__ << '%c';", (int)c);
568 #line 233 "printgen.pcc"
569 } break;
570 case '_': {
571 if (
572 #line 256 "printgen.pcc"
573 (tyl != nil_1_)
574 #line 256 "printgen.pcc"
577 #line 257 "printgen.pcc"
579 if (N == 1)
580 { gen_print_field(C, exp, ty); }
581 else if (label_list ==
582 #line 260 "printgen.pcc"
583 #line 260 "printgen.pcc"
584 nil_1_
585 #line 260 "printgen.pcc"
586 #line 260 "printgen.pcc"
588 { gen_print_field(C,DOTexp(exp,index_of(index)),tyl->_1); }
589 else
590 { gen_print_field(C,DOTexp(exp,label_list->_1),tyl->_1); }
591 C.pr(" // %T", tyl->_1);
592 if (tyl !=
593 #line 265 "printgen.pcc"
594 #line 265 "printgen.pcc"
595 nil_1_
596 #line 265 "printgen.pcc"
597 #line 265 "printgen.pcc"
598 ) tyl = tyl->_2;
599 if (label_list !=
600 #line 266 "printgen.pcc"
601 #line 266 "printgen.pcc"
602 nil_1_
603 #line 266 "printgen.pcc"
604 #line 266 "printgen.pcc"
605 ) label_list = label_list->_2;
606 index++;
608 #line 268 "printgen.pcc"
609 } else {
611 L5:;
612 #line 270 "printgen.pcc"
613 error ("%!illegal print format '%c' in constructor %s %T\n",
614 cons->location, (int)((ProductionSymbol_SPECIALsym *)f)->SPECIALsym, cons->name, ty);
616 #line 272 "printgen.pcc"
618 } break;
619 case '{': {
620 #line 253 "printgen.pcc"
621 C.pr("%^strm__.indent().newline().tab();");
622 #line 253 "printgen.pcc"
623 } break;
624 case '}': {
625 #line 254 "printgen.pcc"
626 C.pr("%^strm__.unindent().newline().tab();");
627 #line 254 "printgen.pcc"
628 } break;
629 default: { goto L5; }
631 } break;
632 default: {
633 #line 274 "printgen.pcc"
634 bug ("%!illegal print format in constructor %s %T\n",
635 cons->location, cons->name, ty);
637 #line 276 "printgen.pcc"
638 } break;
641 #line 277 "printgen.pcc"
642 #line 277 "printgen.pcc"
647 ///////////////////////////////////////////////////////////////////////////////
649 // Method to generate a formatted pretty printer for a field
651 ///////////////////////////////////////////////////////////////////////////////
652 void DatatypeHierarchy::gen_print_field(CodeGen& C, Exp exp, Ty ty)
654 Id stream = (ty_equal(ty,integer_ty) ||
655 ty_equal(ty,character_ty) ||
656 ty_equal(ty,string_ty) ||
657 ty_equal(ty,bool_ty) ||
658 ty_equal(ty,real_ty) ||
659 ty_equal(ty,quark_ty) ||
660 has_qual(QUALprintable,ty) ||
661 has_qual(QUALprintable,deref_all(ty))) ? "" : ".stream()";
662 C.pr("%^strm__%s << %e;", stream, exp);
664 #line 298 "printgen.pcc"
666 ------------------------------- Statistics -------------------------------
667 Merge matching rules = yes
668 Number of DFA nodes merged = 77
669 Number of ifs generated = 14
670 Number of switches generated = 10
671 Number of labels = 5
672 Number of gotos = 11
673 Adaptive matching = enabled
674 Fast string matching = disabled
675 Inline downcasts = enabled
676 --------------------------------------------------------------------------