Annotation of researchv10no/cmd/cfront/ocfront/print.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.