|
|
1.1 root 1: /*ident "@(#)ctrans:src/print.c 1.1.5.20" */
2: /**************************************************************************
3:
4: C++ source for cfront, the C++ compiler front-end
5: written in the computer science research center of Bell Labs
6:
7: Copyright (c) 1984 AT&T, Inc. All rigths Reserved
8: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC.
9:
10: print.c:
11:
12: print statements and expressions
13:
14: ****************************************************************************/
15:
16: #include "cfront.h"
17:
18: extern FILE* out_file;
19: extern bit Cast;
20: extern int last_ll;
21:
22: static int addrof_cm ;
23:
24: void puttok(TOK);
25: /*
26: void cprint(Pexpr e)
27: {
28: if (e == 0) return;
29: //error('d',"%k %n %t",e->base,e->base==NAME?e:0,e->tp);
30: // if ((e->base==NAME || e->base==ANAME)
31: // && Pname(e)->n_evaluated==0) {
32: Ptype t = e->tp;
33: while (t->base == TYPE) t = Pbase(t)->b_name->tp;
34: if (t->base == EOBJ) fprintf(out_file,"(int)");
35: // }
36:
37: Eprint(e);
38: }
39: */
40: #define cprint(e) if (e) Eprint(e)
41: #define eprint(e) if (e) Eprint(e)
42:
43: void Eprint(Pexpr e)
44: {
45: switch (e->base) {
46: case REF:
47: if (Pref(e)->mem && Pref(e)->mem->tp && Pref(e)->mem->tp->base == FCT) {
48: // suppress ``this'' in ``this->f''
49: Pref(e)->mem->print();
50: break;
51: }
52: case NAME:
53: case MDOT:
54: case ID:
55: case ZERO:
56: case ICON:
57: case CCON:
58: case FCON:
59: case STRING:
60: case IVAL:
61: case TEXT:
62: case CM:
63: case G_CM:
64: case ELIST:
65: case COLON:
66: case ILIST:
67: case DOT:
68: case THIS:
69: case CALL:
70: case G_CALL:
71: case ICALL:
72: case ANAME:
73: e->print();
74: case DUMMY:
75: break;
76: default:
77: putch('(');
78: e->print();
79: putch(')');
80: }
81: }
82:
83: void expr::print()
84: {
85: if (this == 0) error('i',"0->E::print()");
86: if (this==e1 || this==e2) error('i',"(%p%k)->E::print(%p %p)",this,base,e1,e2);
87: //error('d',"(%d %k)->expr::print(%d %d)",this,base,e1,e2);
88:
89: switch (base) {
90: case MDOT:
91: //error('d',"mdot %s i1 %d %t",string2,i1,mem->tp);
92: switch (i1) {
93: case 0:
94: putcat('O',string2);
95: puttok(DOT); // use sub-object directly
96: mem->print();
97: break;
98: case 1:
99: putcat('P',string2);
100: puttok(REF); // use through pointer
101: mem->print();
102: break;
103: case 2:
104: if (mem->tp->is_ptr_or_ref()==0) {
105: mem->print();
106: puttok(DOT);
107: putcat('O',string2);
108: }
109: else
110: {
111: putch('('); // REF turns pointer into object: add &
112: putch('&'); // ``this'' is a pointer
113: putch('(');
114: eprint(mem);//mem->print();
115: puttok(REF); // call sub-object directly
116: putcat('O',string2);
117: putch(')');
118: putch(')');
119: }
120: break;
121: case 3:
122: if (mem->tp->is_ptr_or_ref()==0) {
123: putch('('); // Px is a pointer (T*) turn it back to a T
124: putch('*'); // *Px
125: putch('(');
126: eprint(mem);//mem->print();
127: puttok(DOT); // call through pointer
128: putcat('P',string2);
129: putch(')');
130: putch(')');
131: }
132: else {
133: eprint(mem); // <<< mem->print()
134: puttok(REF); // call through pointer
135: putcat('P',string2);
136: }
137: break;
138:
139: case 9: // vtbl entry: (p->_vtbl).f, (p->_vtbl).i, (p->_vtbl).d
140: // or memptr: mp.f, mp.i, mp.d
141: eprint(mem);
142: putch('.');
143: putstring(string2);
144:
145: }
146: break;
147: case NAME:
148: { Pname n = Pname(this);
149: if (n->n_evaluated
150: // && n->tp->base!=EOBJ // this output enumerators
151: && n->n_scope!=ARG) {
152: Ptype t = tp;
153: while (t->base == TYPE) t = Pbase(t)->b_name->tp;
154: if (t->base == EOBJ) t = Penum(Pbase(t)->b_name->tp)->e_type;
155: if (t->base!=INT || t->is_unsigned()) {
156: putstring("((");
157: bit oc = Cast;
158: Cast = 1;
159: t->print();
160: Cast = oc;
161: fprintf(out_file,")%d)",n->n_val);
162: }
163: else
164: fprintf(out_file,"%d",n->n_val);
165: }
166: else
167: n->print();
168: break;
169: }
170: case ANAME:
171: if (curr_icall) { // in expansion: look it up
172: Pname n = Pname(this);
173: int argno = int(n->n_val);
174:
175: for (Pin il=curr_icall; il; il=il->i_next)
176: if (n->n_table == il->i_table) goto aok;
177: goto bok;
178: aok:
179: if (n = il->i_args[argno].local) {
180: n->print();
181: }
182: else {
183: Pexpr ee = il->i_args[argno].arg;
184: Ptype t = il->i_args[argno].tp;
185: if (ee==0 || ee==this) error('i',"%p->E::print(A %p)",this,ee);
186: if (ee->tp==0
187: || (t!=ee->tp
188: && t->check(ee->tp,0)
189: && t->is_cl_obj()==0
190: // && eobj==0)
191: )
192: ) {
193: putstring("((");
194: bit oc = Cast;
195: Cast = 1;
196: t->print();
197: Cast = oc;
198: putch(')');
199: // eprint(ee);
200: // if (ee->base == CAST) {
201: // eprint(ee->e1);
202: // }
203: // else
204: eprint(ee);
205: putch(')');
206: }
207: else
208: eprint(ee);
209: }
210: }
211: else {
212: bok: /* in body: print it: */
213: Pname(this)->print();
214: }
215: break;
216:
217: case ICALL:
218: { il->i_next = curr_icall;
219: curr_icall = il;
220: //error('d',"icall %n",il->fct_name);
221: if (il == 0) error('i',"E::print: iline missing");
222: Pexpr a0 = il->i_args[0].arg;
223: int val = QUEST;
224: if (il->fct_name->n_oper != CTOR) goto dumb;
225:
226: /*
227: find the value of "this"
228: if the argument is a "this" NOT assigned to
229: by the programmer, it was initialized
230: */
231: switch (a0->base) {
232: case ZERO:
233: val = 0;
234: break;
235: case ADDROF:
236: case G_ADDROF:
237: val = 1;
238: break;
239: case CAST:
240: if (a0->e1->base == ANAME || a0->e1->base == NAME) {
241: Pname a = (Pname)a0->e1;
242: if (a->n_assigned_to == FUDGE111) val = FUDGE111;
243: }
244: }
245: if (val==QUEST) goto dumb;
246: /*
247: now find the test: "(this==0) ? _new(sizeof(X)) : 0"
248:
249: e1 is a comma expression,
250: the test is either the first sub-expression
251: or the first sub-expression after the assignments
252: initializing temporary variables
253: */
254: dumb:
255: eprint(e1);
256: if (e2) Pstmt(e2)->print();
257: curr_icall = il->i_next;
258: break;
259: }
260: case REF:
261: case DOT:
262: eprint(e1);
263: puttok(base);
264: if (mem == 0) {
265: fprintf(out_file,"MEM0");
266: break;
267: }
268: if (mem->base == NAME)
269: Pname(mem)->print();
270: else
271: mem->print();
272: break;
273:
274: case MEMPTR:
275: error("P toMF not called");
276: break;
277:
278: case VALUE:
279: tp2->print();
280: puttok(LP);
281:
282: // if (e2) {
283: // putstring("/* &");
284: // e2->print();
285: // putstring(", */");
286: // }
287: if (e1) e1->print();
288: puttok(RP);
289: break;
290:
291: case SIZEOF:
292: puttok(SIZEOF);
293: if (e1 && e1!=dummy) {
294: eprint(e1);
295: }
296: else if (tp2) {
297: putch('(');
298: if (tp2->base == CLASS) {
299: Pclass cl = Pclass(tp2);
300: putstring((cl->csu == UNION)?"union ":"struct ");
301: char *str = 0;
302: extern char *make_local_name(Pclass, int=0);
303: if ( cl->lex_level ) str = make_local_name( cl );
304: putstring( str?str:cl->string );
305: delete str;
306: }
307: else
308: tp2->print();
309: putch(')');
310: }
311: break;
312:
313: /*
314: // always turned into function calls:
315: case NEW:
316: case GNEW:
317: // error('d',"print new %d tp2 %t e1 %d e2 %d",base,tp2,e1,e2);
318: puttok(NEW);
319: tp2->print();
320: if (e1) {
321: putch('(');
322: e1->print();
323: putch(')');
324: }
325: break;
326:
327: case DELETE:
328: case GDELETE:
329: //error('d',"print delete");
330: puttok(DELETE);
331: e1->print();
332: break;
333: */
334: case CAST:
335: putch('(');
336: //error('d',"print cast %t",tp2);
337: if (tp2->base != VOID && tp2->memptr() == 0 ) {
338: // when VOID is represented as CHAR not everything
339: // can be cast to VOID
340: putch('(');
341: bit oc = Cast;
342: Cast = 1;
343: tp2->print();
344: Cast = oc;
345: putch(')');
346: }
347: eprint(e1);
348: putch(')');
349: break;
350:
351: case ICON:
352: case FCON:
353: case CCON:
354: case ID:
355: if (string) putst(string);
356: break;
357:
358: case STRING:
359: extern ntok;
360: // avoid printing very long lines
361: ntok += 4;
362: fprintf(out_file,"\"%s\"",string);
363: break;
364:
365: case THIS:
366: case ZERO:
367: putstring("0 ");
368: break;
369:
370: case IVAL:
371: fprintf(out_file,"%d",i1);
372: break;
373:
374: case TEXT:
375: {
376: int oo = vtbl_opt; // make `simulated static' name
377: vtbl_opt = -1;
378: char* s = vtbl_name(string,string2);
379: vtbl_opt = oo;
380: s[2] = 'p'; // pointer, not tbl itself
381: fprintf(out_file, " %s",s);
382: delete s;
383: }
384: // no break;
385:
386: case DUMMY:
387: break;
388:
389: case G_CALL:
390: case CALL:
391: { Pname fn = fct_name;
392: Pname at;
393: int m_ptr = 0;
394:
395: if (fn) {
396: Pfct f = Pfct(fn->tp);
397:
398: if (f->base==OVERLOAD) { // overloaded after call
399: fct_name = fn = Pgen(f)->fct_list->f;
400: f = Pfct(fn->tp);
401: }
402:
403: fn->print();
404: at = f->f_args;
405: }
406: else {
407: Pfct f = Pfct(e1->tp);
408:
409: if (f) { // pointer to fct
410: Pexpr exex = e1;
411: if ( exex->base == DEREF ) {
412: exex = exex->e1;
413: while ( exex->base == CAST )
414: exex = exex->e1;
415: if ( exex->base == MDOT )
416: m_ptr = 1;
417: }
418:
419: if (f->base == OVERLOAD) { // overloaded after call
420: fct_name = fn = Pgen(f)->fct_list->f;
421: f = Pfct(fn->tp);
422: }
423:
424: while (f->base == TYPE) f = Pfct(Pbase(f)->b_name->tp);
425: if (f->base == PTR) {
426: putstring("(*");
427: e1->print();
428: putch(')');
429: f = Pfct(Pptr(f)->typ);
430: while (f->base == TYPE) f = Pfct(Pbase(f)->b_name->tp);
431: }
432: else
433: eprint(e1);
434:
435: // at = (f->f_result) ? f->f_result : f->argtype;
436: at = f->f_args;
437: }
438: else { // virtual: argtype encoded
439: // f_this already linked to f_result and/or argtype
440: at = (e1->base==QUEST) ? Pname(e1->e1->tp2) : Pname(e1->tp2);
441: eprint(e1);
442: }
443: }
444:
445: puttok(LP);
446:
447: if (e2) {
448: if (at) {
449: Pexpr e = e2;
450: while (at) {
451: Pexpr ex;
452: Ptype t = at->tp;
453:
454: if (t == 0) error('i',"T ofA missing for%n",fn);
455: if (e == 0) error('i',"%tA missing for%n",t,fn);
456: if (e->base == ELIST) {
457: ex = e->e1;
458: e = e->e2;
459: }
460: else
461: ex = e;
462:
463: if (ex == 0) error('i',"A ofT%t missing",t);
464: extern Pclass Mptr;
465: if (t!=ex->tp
466: && ex->tp
467: && t->check(ex->tp,0)
468: && t->is_cl_obj()==0
469: && eobj==0
470: && m_ptr == 0
471: && (t->is_ptr()==0 || Mptr==0)) {
472: putch('(');
473: bit oc = Cast;
474: Cast = 1;
475: t->print();
476: Cast = oc;
477: putch(')');
478: #ifdef sun
479: if (ex->base == DIV) { // defend against perverse SUN cc bug
480: putstring("(0+");
481: eprint(ex);
482: putch(')');
483: }
484: else
485: #endif
486: // eprint(ex);
487: // if (ex->base==CAST) {
488: // eprint(ex->e1);
489: // }
490: // else
491: eprint(ex);
492: }
493: else
494: ex->print();
495:
496: // if m_ptr is set, then don't advance at
497: // at does not know about generated `this'
498: if ( m_ptr ) {
499: m_ptr = 0;
500: if (at) puttok(CM);
501: continue;
502: }
503:
504: at = at->n_list;
505: if (at) puttok(CM);
506: }
507: if (e) {
508: puttok(CM);
509: e->print();
510: }
511: }
512: else
513: e2->print();
514: }
515: puttok(RP);
516: break;
517: }
518:
519: case ASSIGN:
520: if (e1->base==ANAME && Pname(e1)->n_assigned_to==FUDGE111) {
521: // suppress assignment to "this" that has been optimized away
522: Pname n = Pname(e1);
523: int argno = int(n->n_val);
524: for (Pin il=curr_icall; il; il=il->i_next)
525: if (il->i_table == n->n_table) goto akk;
526: goto bkk;
527: akk:
528: if (il->i_args[argno].local == 0) {
529: e2->print();
530: break;
531: }
532: }
533: //no break
534: case EQ:
535: case NE:
536: case GT:
537: case GE:
538: case LE:
539: case LT:
540: bkk:
541: { Ptype t1 = e1->tp;
542: Ptype t2 = e2->tp;
543:
544: if (base!=ASSIGN) {
545: cprint(e1);
546: }
547: else
548: eprint(e1);
549: puttok(base);
550:
551: if (t1 && t1!=t2 && e2->base!=ZERO) {
552: // cast, but beware of int!=long etc.
553: cmp:
554: switch (t1->base) {
555: case TYPE:
556: t1 = Pbase(t1)->b_name->tp;
557: goto cmp;
558: default:
559: // if (e2->base==NAME
560: // && Pname(e2)->n_evaluated==0
561: // && e2->tp->base==EOBJ)
562: // fprintf(out_file,"(int)");
563: break;
564: // case EOBJ:
565: // if (base==ASSIGN) goto cst;
566: // break;
567: case PTR:
568: case RPTR:
569: case VEC:
570: if (t2)
571: while ( t2->base == TYPE )
572: t2 = Pbase(t2)->b_name->tp;
573:
574: if (e2->tp==0
575: || (Pptr(t1)->typ!=Pptr(t2)->typ && t1->check(t2,0))) {
576: // cst:
577: putch('(');
578: bit oc = Cast;
579: Cast = 1;
580: e1->tp->print();
581: Cast = oc;
582: putch(')');
583: }
584: }
585: }
586:
587: eprint(e2);
588: break;
589: }
590:
591: case DEREF:
592: if (e2) {
593:
594: eprint(e1);
595: putch('[');
596: cprint(e2);
597: putch(']');
598: }
599: else {
600: putch('(');
601: putch('*');
602: eprint(e1);
603: putch(')');
604: }
605: break;
606:
607: case ILIST:
608: puttok(LC);
609: if (e1) e1->print();
610: if (e2) { // member pointer initiliazers
611: puttok(CM);
612: e2->print();
613: }
614: puttok(RC);
615: break;
616:
617: case ELIST:
618: { Pexpr e = this;
619: for(;;) {
620: if (e->base == ELIST) {
621: e->e1->print();
622: if (e = e->e2) {
623: extern ntok;
624: puttok(CM);
625: }
626: else
627: return;
628: }
629: else {
630: e->print();
631: return;
632: }
633: }
634: }
635:
636: case QUEST:
637: { // look for (&a == 0) etc.
638: extern bit binary_val;
639: Neval = 0;
640: binary_val = 1;
641: long i = cond->eval();
642: binary_val = 0;
643: if (Neval == 0)
644: (i?e1:e2)->print();
645: else {
646: eprint(cond);
647: putch('?');
648: cprint(e1);
649: putch(':');
650: cprint(e2);
651: }
652: break;
653: }
654:
655: case CM: // do &(a,b) => (a,&b) for previously checked inlines
656: case G_CM:
657: puttok(LP);
658: switch (e1->base) {
659: case ZERO:
660: case IVAL:
661: case ICON:
662: case NAME:
663: case MDOT:
664: case DOT:
665: case REF:
666: case FCON:
667: case FVAL:
668: case STRING:
669: goto le2; // suppress constant a: &(a,b) => (&b)
670: default:
671: { int oo = addrof_cm; // &(a,b) does not affect a
672: addrof_cm = 0;
673: eprint(e1);
674: addrof_cm = oo;
675: }
676: puttok(CM);
677: le2:
678: if (addrof_cm) {
679: switch (e2->base) {
680: case CAST:
681: if (e2->e2)
682: switch (e2->e2->base) {
683: case CM:
684: case G_CM:
685: case ICALL: goto ec;
686: }
687: case NAME:
688: case MDOT:
689: case DOT:
690: case DEREF:
691: case REF:
692: case ANAME:
693: puttok(ADDROF);
694: addrof_cm--;
695: eprint(e2);
696: addrof_cm++;
697: break;
698: case ICALL:
699: // case CALL:
700: case CM:
701: case G_CM:
702: ec:
703: eprint(e2);
704: break;
705: case G_CALL:
706: /* & ( e, ctor() ) with temporary optimized away */
707: if (e2->fct_name
708: && e2->fct_name->n_oper==CTOR) {
709: addrof_cm--;
710: eprint(e2);
711: addrof_cm++;
712: break;
713: }
714: default:
715: error('i',"& inlineF call (%k)",e2->base);
716: }
717: }
718: else
719: // e2->print();
720: eprint(e2);
721: puttok(RP);
722: }
723: break;
724:
725: case UMINUS:
726: case NOT:
727: case COMPL:
728: // puttok(base);
729: // eprint(e2);
730: // break;
731: goto op2;
732: case ADDROF:
733: case G_ADDROF:
734: switch (e2->base) { // & *e1 or &e1[e2]
735: case DEREF:
736: if (e2->e2 == 0) { // &*e == e
737: e2->e1->print();
738: return;
739: }
740: break;
741: case ICALL:
742: addrof_cm++; // assumes inline expanded into ,-expression
743: eprint(e2);
744: addrof_cm--;
745: return;
746: case ASSIGN: // &(a=b) ??? works on many cc s
747: eprint(e2); // make sure it breaks!
748: return;
749: }
750:
751: // suppress cc warning on &fct
752: if (e2->tp==0 || e2->tp->base!=FCT) puttok(ADDROF);
753:
754: eprint(e2);
755: break;
756:
757: case PLUS:
758: case MINUS:
759: case MUL:
760: case DIV:
761: case MOD:
762: case LS:
763: case RS:
764: #ifdef DK
765: case AND: putc('&'); break;
766: case OR: putc('|'); break;
767: case ER: putc('^'); break;
768: case ANDAND: putstring("&&"); break;
769: case OROR: putstring("||"); break;
770: #else
771: case AND:
772: case OR:
773: case ER:
774: case ANDAND:
775: case OROR:
776: #endif
777: case DECR:
778: case INCR:
779: cprint(e1);
780: op2:
781: puttok(base);
782: cprint(e2);
783: break;
784: case ASOR:
785: case ASER:
786: case ASAND:
787: case ASPLUS:
788: case ASMINUS:
789: case ASMUL:
790: case ASMOD:
791: case ASDIV:
792: case ASLS:
793: case ASRS:
794: eprint(e1);
795: goto op2;
796:
797: default:
798: error('i',"%p->E::print%k",this,base);
799: // fprintf(out_file," EEE(%d) ",base);
800: }
801: }
802:
803: Pexpr aval(Pname a)
804: {
805: int argno = int(a->n_val);
806: Pin il;
807: for (il=curr_icall; il; il=il->i_next)
808: if (il->i_table == a->n_table) goto aok;
809: return 0;
810: aok:
811: Pexpr aa = il->i_args[argno].arg;
812: ll:
813: switch (aa->base) {
814: case CAST: aa = aa->e1; goto ll;
815: case ANAME: return aval(Pname(aa));
816: default: return aa;
817: }
818: }
819:
820: #define putcond() putch('('); e->print(); putch(')')
821:
822: void stmt::print()
823: {
824: //error('d',"S::print %d:%k s %d s_list %d",this,base,s,s_list);
825: if (where.line && where.line!=last_line.line)
826: if (last_ll = where.line)
827: where.putline();
828: else
829: last_line.putline();
830:
831: if (memtbl && base!=BLOCK) { /* also print declarations of temporaries */
832: puttok(LC);
833: Ptable tbl = memtbl;
834: memtbl = 0;
835: int i;
836: int bl = 1;
837: for (Pname n=tbl->get_mem(i=1); n; n=tbl->get_mem(++i)){
838: if (n->tp == any_type) continue;
839: /* avoid double declarartion of temporaries from inlines */
840: char* s = n->string;
841: if (s[0]!='_' || s[1]!='_' || s[2]!='X') {
842: n->dcl_print(0);
843: bl = 0;
844: }
845: Pname cn;
846: if (bl
847: && (cn=n->tp->is_cl_obj())
848: && Pclass(cn->tp)->has_dtor()) bl = 0;
849: }
850:
851: if (bl) {
852: Pstmt sl = s_list;
853: s_list = 0;
854: print();
855: memtbl = tbl;
856: puttok(RC);
857: if (sl) {
858: s_list = sl;
859: sl->print();
860: }
861: }
862: else {
863: print();
864: memtbl = tbl;
865: puttok(RC);
866: }
867: return;
868: }
869:
870: switch (base) {
871: default:
872: error('i',"S::print(base=%k)",base);
873:
874: case ASM:
875: fprintf(out_file,"asm(\"%s\");\n",(char*)e);
876: break;
877:
878: case DCL:
879: d->dcl_print(SM);
880: break;
881:
882: case BREAK:
883: case CONTINUE:
884: puttok(base);
885: puttok(SM);
886: break;
887:
888: case DEFAULT:
889: puttok(base);
890: //puttok(COLON);
891: putch(':');
892: s->print();
893: break;
894:
895: case SM:
896: if (e) {
897: e->print();
898: if (e->base==ICALL && e->e2) break; /* a block: no SM */
899: }
900: puttok(SM);
901: break;
902:
903: case WHILE:
904: puttok(WHILE);
905: putcond();
906: if (s->s_list) {
907: puttok(LC);
908: s->print();
909: puttok(RC);
910: }
911: else
912: s->print();
913: break;
914:
915: case DO:
916: puttok(DO);
917: s->print();
918: puttok(WHILE);
919: putcond();
920: puttok(SM);
921: break;
922:
923: case SWITCH:
924: puttok(SWITCH);
925: putcond();
926: s->print();
927: break;
928:
929: case RETURN:
930: {
931: puttok(RETURN);
932: if (e) {
933: //error('d',"print return rt %t etp %t",ret_tp,e->tp);
934: if (ret_tp && ret_tp!=e->tp) {
935: Ptype tt = ret_tp;
936: gook:
937: switch (tt->base) {
938: case TYPE:
939: tt = Pbase(tt)->b_name->tp;
940: goto gook;
941: case COBJ:
942: break; // cannot cast to struct
943: case RPTR:
944: case PTR:
945: if (Pptr(tt)->typ==Pptr(e->tp)->typ) break;
946: if (Pptr(tt)->memof) break;
947: default:
948: if (e->tp==0 || ret_tp->check(e->tp,0)) {
949: int oc = Cast;
950: putch('(');
951: Cast = 1;
952: ret_tp->print();
953: Cast = oc;
954: putch(')');
955: }
956: }
957: }
958: eprint(e);
959: }
960: puttok(SM);
961: }
962: while (s_list && s_list->base==SM) s_list = s_list->s_list; // FUDGE!!
963: break;
964:
965: case CASE:
966: puttok(CASE);
967: eprint(e);
968: //puttok(COLON);
969: putch(':');
970: s->print();
971: break;
972:
973: case GOTO:
974: puttok(GOTO);
975: d->print();
976: puttok(SM);
977: break;
978:
979: case LABEL:
980: d->print();
981: putch(':');
982: s->print();
983: break;
984:
985: case IF:
986: { int val = QUEST;
987: if (e->base == ANAME) {
988: Pname a = Pname(e);
989: Pexpr arg = aval(a);
990: //error('d',"arg %d%k %d (%d)",arg,arg?arg->base:0,arg?arg->base:0,arg?arg->e1:0);
991: if (arg)
992: switch (arg->base) {
993: case ZERO: val = 0; break;
994: case ADDROF:
995: case G_ADDROF: val = 1; break;
996: case IVAL: val = arg->i1!=0;
997: }
998: }
999: //error('d',"val %d",val);
1000: switch (val) {
1001: case 1:
1002: s->print();
1003: break;
1004: case 0:
1005: if (else_stmt)
1006: else_stmt->print();
1007: else
1008: puttok(SM); /* null statement */
1009: break;
1010: default:
1011: puttok(IF);
1012: putcond();
1013: if (s->s_list) {
1014: puttok(LC);
1015: s->print();
1016: puttok(RC);
1017: }
1018: else
1019: s->print();
1020: if (else_stmt) {
1021: puttok(ELSE);
1022: if (else_stmt->s_list) {
1023: puttok(LC);
1024: else_stmt->print();
1025: puttok(RC);
1026: }
1027: else
1028: else_stmt->print();
1029: }
1030: }
1031: break;
1032: }
1033:
1034: case FOR:
1035: {
1036: // int fi = for_init && ((for_init->base!=SM || for_init->memtbl || for_init->s_list);
1037: int fi = 0; // is the initializer statement an expression?
1038: if (for_init) {
1039: fi = 1;
1040: if (for_init->memtbl==0 && for_init->s_list==0)
1041: if (for_init->base==SM)
1042: if (for_init->e->base!=ICALL || for_init->e->e1)
1043: fi = 0;
1044: }
1045: //error('d',"for(; %d%k; %d%k)",e,e->base,e2,e2->base);
1046: if (fi) {
1047: puttok(LC);
1048: for_init->print();
1049: }
1050: putstring("for(");
1051: if (fi==0 && for_init) for_init->e->print();
1052: putch(';'); // to avoid newline: not puttok(SM)
1053: if (e) e->print();
1054: putch(';');
1055: if (e2) e2->print();
1056: puttok(RP);
1057: s->print();
1058: if (fi) puttok(RC);
1059: break;
1060: }
1061:
1062: case PAIR:
1063: if (s&&s2) {
1064: puttok(LC);
1065: s->print();
1066: s2->print();
1067: puttok(RC);
1068: }
1069: else {
1070: if (s) s->print();
1071: if (s2) s2->print();
1072: }
1073: break;
1074:
1075: case BLOCK:
1076: puttok(LC);
1077: //error('d',"block %d d %d memtbl %d own_tbl %d",this,d,memtbl,own_tbl);
1078: if (d) d->dcl_print(SM);
1079: if (memtbl && own_tbl) {
1080: Pname n;
1081: int i;
1082: for (n=memtbl->get_mem(i=1); n; n=memtbl->get_mem(++i)) {
1083: if (n->tp && n->n_union==0 && n->tp!=any_type)
1084: switch (n->n_scope) {
1085: case ARGT:
1086: case ARG:
1087: break;
1088: default:
1089: n->dcl_print(0);
1090: }
1091: }
1092: }
1093: if (s) s->print();
1094: putstring("}\n");
1095: if (last_ll && where.line) last_line.line++;
1096: }
1097:
1098: if (s_list) s_list->print();
1099: }
1100: /*
1101: void table::dcl_print(TOK s, TOK pub)
1102:
1103: // print the declarations of the entries in the order they were inserted
1104: // ignore labels (tp==0)
1105:
1106: {
1107: register Pname* np;
1108: register int i;
1109:
1110: if (this == 0) return;
1111:
1112: np = entries;
1113: for (i=1; i<free_slot; i++) {
1114: register Pname n = np[i];
1115: switch (s) {
1116: case 0:
1117: n->dcl_print(0);
1118: break;
1119: case EQ:
1120: if (n->tp && n->n_scope == pub) n->dcl_print(0);
1121: break;
1122: case NE:
1123: if (n->tp && n->n_scope != pub) n->dcl_print(0);
1124: break;
1125: }
1126: }
1127: }
1128: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.