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