|
|
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.