Annotation of researchv10no/cmd/cfront/optcfront/print.c, revision 1.1

1.1     ! root        1: /*ident        "@(#)ctrans:src/print.c 1.3" */
        !             2: /**************************************************************************
        !             3: 
        !             4:        C++ source for cfront, the C++ compiler front-end
        !             5:        written in the computer science research center of Bell Labs
        !             6: 
        !             7:        Copyright (c) 1984 AT&T, Inc. All rights Reserved
        !             8:        THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC.
        !             9: 
        !            10: print.c:
        !            11: 
        !            12:        print statements and expressions
        !            13: 
        !            14: ****************************************************************************/
        !            15: 
        !            16: #include "cfront.h"
        !            17: 
        !            18: static int addrof_cm ;
        !            19: extern void puttok(TOK);
        !            20: 
        !            21: /*
        !            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 UPLUS: // only preserved for ansi_opt==1
        !           754:        case UMINUS:
        !           755:        case NOT:
        !           756:        case COMPL:
        !           757:         //      puttok(base);
        !           758:         //      eprint(e2);
        !           759:         //      break;
        !           760:                 goto op2;
        !           761:        case ADDROF:
        !           762:        case G_ADDROF:
        !           763:                switch (e2->base) {     // & *e1 or &e1[e2]
        !           764:                case DEREF:
        !           765:                        if (e2->e2 == 0) {      // &*e == e
        !           766:                                e2->e1->print();
        !           767:                                return;
        !           768:                        }
        !           769:                        break;
        !           770:                case ICALL:
        !           771:                        addrof_cm++;    // assumes inline expanded into ,-expression
        !           772:                        eprint(e2);
        !           773:                        addrof_cm--;
        !           774:                        return;
        !           775:                case ASSIGN:            // &(a=b)       ??? works on many cc s
        !           776:                        eprint(e2);     // make sure it breaks!
        !           777:                        return;
        !           778:                case NAME: {
        !           779:                        Pname n = Pname(e2);
        !           780:                        if(n->n_evaluated) {
        !           781:                                n->n_evaluated=0;
        !           782:                                puttok(ADDROF);
        !           783:                                eprint(e2);
        !           784:                                n->n_evaluated=1;
        !           785:                                return;
        !           786:                        }
        !           787:                        break;
        !           788:                        }
        !           789:                }
        !           790: 
        !           791:                // suppress cc warning on &fct
        !           792:                if (e2->tp==0 || e2->tp->base!=FCT) puttok(ADDROF);
        !           793: 
        !           794:                eprint(e2);
        !           795:                break;
        !           796: 
        !           797:        case PLUS:
        !           798:        case MINUS:
        !           799:        case MUL:
        !           800:        case DIV:
        !           801:        case MOD:
        !           802:        case LS:
        !           803:        case RS:
        !           804:        case AND:
        !           805:        case OR:
        !           806:        case ER:
        !           807:        case ANDAND:
        !           808:        case OROR:
        !           809:         case DECR:
        !           810:         case INCR:
        !           811:                 cprint(e1);
        !           812:         op2:
        !           813:                puttok(base);
        !           814:                cprint(e2);
        !           815:                 break;
        !           816:        case ASOR:
        !           817:        case ASER:
        !           818:        case ASAND:
        !           819:        case ASPLUS:
        !           820:        case ASMINUS:
        !           821:        case ASMUL:
        !           822:        case ASMOD:
        !           823:        case ASDIV:
        !           824:        case ASLS:
        !           825:        case ASRS:
        !           826:                 eprint(e1);
        !           827:                 goto op2;
        !           828: 
        !           829:        default:
        !           830:                error('i',"%p->E::print%k",this,base);
        !           831:        //      fprintf(out_file," EEE(%d) ",base);
        !           832:        }
        !           833: }
        !           834: 
        !           835: Pexpr aval(Pname a)
        !           836: {
        !           837:        int argno = int(a->n_val);
        !           838:        Pin il;
        !           839:        for (il=curr_icall; il; il=il->i_next)
        !           840:                if (il->i_table == a->n_table) goto aok;
        !           841:        return 0;
        !           842: aok:
        !           843:        Pexpr aa = il->i_args[argno].arg;
        !           844: ll:
        !           845:        switch (aa->base) {
        !           846:        case CAST:      aa = aa->e1; goto ll;
        !           847:        case ANAME:     return aval(Pname(aa));
        !           848:        default:        return aa;
        !           849:        }
        !           850: }
        !           851: 
        !           852: #define putcond()      putch('('); e->print(); putch(')')
        !           853: 
        !           854: static loc csloc = { 0, 0 }; // loc of last stmt with line!=0
        !           855: 
        !           856: void stmt::print()
        !           857: {
        !           858: //error('d',"S::print %d:%k s %d s_list %d",this,base,s,s_list);
        !           859:        if (where.line == 0) {
        !           860:            if (csloc.line) csloc.putline();
        !           861:        } else {
        !           862:            csloc = where;
        !           863:            if (where.line!=last_line.line)
        !           864:                if (last_ll = where.line)
        !           865:                        where.putline();
        !           866:                else
        !           867:                        last_line.putline();
        !           868:        }
        !           869: 
        !           870:        if (memtbl && base!=BLOCK) { /* also print declarations of temporaries */
        !           871:                puttok(LC);
        !           872:                Ptable tbl = memtbl;
        !           873:                memtbl = 0;
        !           874:                int i;
        !           875:                int bl = 1;
        !           876:                for (Pname n=tbl->get_mem(i=1); n; n=tbl->get_mem(++i)){
        !           877:                        if (n->tp == any_type) continue;
        !           878:                        /* avoid double declarartion of temporaries from inlines */
        !           879:                        char* s = n->string;
        !           880:                        if (s[0]!='_' || s[1]!='_' || s[2]!='X') {
        !           881:                                n->dcl_print(0);
        !           882:                                bl = 0;
        !           883:                        }
        !           884:                        Pname cn;
        !           885:                        if (bl
        !           886:                        && (cn=n->tp->is_cl_obj())
        !           887:                        && Pclass(cn->tp)->has_dtor()) bl = 0;
        !           888:                }
        !           889:                if ( last_ll==0 && (last_ll = where.line) )
        !           890:                        where.putline();
        !           891:                if (bl) {
        !           892:                        Pstmt sl = s_list;
        !           893:                        s_list = 0;
        !           894:                        print();
        !           895:                        memtbl = tbl;
        !           896:                        puttok(RC);
        !           897:                        if (sl) {
        !           898:                                s_list = sl;
        !           899:                                sl->print();
        !           900:                        }
        !           901:                }
        !           902:                else {
        !           903:                        print();
        !           904:                        memtbl = tbl;
        !           905:                        puttok(RC);
        !           906:                }
        !           907:                return;
        !           908:        }
        !           909: 
        !           910:        switch (base) {
        !           911:        default:
        !           912:                error('i',"S::print(base=%k)",base);
        !           913: 
        !           914:        case ASM:
        !           915:                fprintf(out_file,"asm(\"%s\");\n",(char*)e);
        !           916:                break;
        !           917: 
        !           918:        case DCL:
        !           919:                d->dcl_print(SM);
        !           920:                break;
        !           921: 
        !           922:        case BREAK:
        !           923:        case CONTINUE:
        !           924:                puttok(base);
        !           925:                puttok(SM);
        !           926:                break;
        !           927: 
        !           928:        case DEFAULT:
        !           929:                puttok(base);
        !           930:                //puttok(COLON);
        !           931:                putch(':');
        !           932:                s->print();
        !           933:                break;
        !           934: 
        !           935:        case SM:
        !           936:                if (e) {
        !           937:                        e->print();
        !           938:                        if (e->base==ICALL && e->e2) break;     /* a block: no SM */
        !           939:                }
        !           940:                puttok(SM);
        !           941:                break;
        !           942: 
        !           943:        case WHILE:
        !           944:                puttok(WHILE);
        !           945:                putcond();
        !           946:                if (s->s_list) {
        !           947:                        puttok(LC);
        !           948:                        s->print();
        !           949:                        puttok(RC);
        !           950:                }
        !           951:                else
        !           952:                        s->print();
        !           953:                break;
        !           954: 
        !           955:        case DO:
        !           956:                puttok(DO);
        !           957:                s->print();
        !           958:                puttok(WHILE);
        !           959:                putcond();
        !           960:                puttok(SM);
        !           961:                break;
        !           962: 
        !           963:        case SWITCH:
        !           964:                puttok(SWITCH);
        !           965:                putcond();
        !           966:                s->print();
        !           967:                break;
        !           968: 
        !           969:        case RETURN:
        !           970:                {
        !           971:                puttok(RETURN);
        !           972:                if (e) {
        !           973: //error('d',"print return rt %t etp %t",ret_tp,e->tp);
        !           974:                        if (ret_tp && ret_tp!=e->tp) {
        !           975:                                Ptype tt = ret_tp;
        !           976:                        gook:
        !           977:                                switch (tt->base) {
        !           978:                                case TYPE:
        !           979:                                        tt = Pbase(tt)->b_name->tp;
        !           980:                                        goto gook;
        !           981:                                case COBJ:
        !           982:                                        break;  // cannot cast to struct
        !           983:                                case RPTR:
        !           984:                                case PTR:
        !           985:                                        if (Pptr(tt)->typ==Pptr(e->tp)->typ) break;
        !           986:                                        if (Pptr(tt)->memof) break;
        !           987:                                default:
        !           988:                                        if (e->tp==0 || ret_tp->check(e->tp,0)) {
        !           989:                                                int oc = Cast;
        !           990:                                                putch('(');
        !           991:                                                Cast = 1;
        !           992:                                                ret_tp->print();
        !           993:                                                Cast = oc;
        !           994:                                                putch(')');
        !           995:                                        }
        !           996:                                }
        !           997:                        }
        !           998:                        eprint(e);
        !           999:                }
        !          1000:                puttok(SM);
        !          1001:                }
        !          1002:                while (s_list && s_list->base==SM) s_list = s_list->s_list; // FUDGE!!
        !          1003:                break;
        !          1004: 
        !          1005:        case CASE:
        !          1006:                puttok(CASE);
        !          1007:                eprint(e);
        !          1008:                putch(':');
        !          1009:                s->print();
        !          1010:                break;
        !          1011: 
        !          1012:        case GOTO:
        !          1013:                puttok(GOTO);
        !          1014:                d->print();
        !          1015:                puttok(SM);
        !          1016:                break;
        !          1017: 
        !          1018:        case LABEL:
        !          1019:                d->print();
        !          1020:                putch(':');
        !          1021:                s->print();
        !          1022:                break;
        !          1023: 
        !          1024:        case IF:
        !          1025:        {       int val = QUEST;
        !          1026:                if (e->base == ANAME) {
        !          1027:                        Pname a = Pname(e);
        !          1028:                        Pexpr arg = aval(a);
        !          1029: //error('d',"arg %d%k %d (%d)",arg,arg?arg->base:0,arg?arg->base:0,arg?arg->e1:0);
        !          1030:                        if (arg)
        !          1031:                                switch (arg->base) {
        !          1032:                                case ZERO:      val = 0; break;
        !          1033:                                case ADDROF:
        !          1034:                                case G_ADDROF:  val = 1; break;
        !          1035:                                case IVAL:      val = arg->i1!=0;
        !          1036:                        }
        !          1037:                }
        !          1038: //error('d',"val %d",val);
        !          1039:                switch (val) {
        !          1040:                case 1:
        !          1041:                        s->print();
        !          1042:                        break;
        !          1043:                case 0:
        !          1044:                        if (else_stmt)
        !          1045:                                else_stmt->print();
        !          1046:                        else
        !          1047:                                puttok(SM);     /* null statement */
        !          1048:                        break;
        !          1049:                default:
        !          1050:                        puttok(IF);
        !          1051:                        putcond();
        !          1052:                        if (s->s_list) {
        !          1053:                                puttok(LC);
        !          1054:                                s->print();
        !          1055:                                puttok(RC);
        !          1056:                        }
        !          1057:                        else
        !          1058:                                s->print();
        !          1059:                        if (else_stmt) {
        !          1060:                                if (else_stmt->where.line == 0) {
        !          1061:                                    if (csloc.line) csloc.putline();
        !          1062:                                } else {
        !          1063:                                    csloc = else_stmt->where;
        !          1064:                                    if (else_stmt->where.line!=last_line.line)
        !          1065:                                        if (last_ll = else_stmt->where.line)
        !          1066:                                                else_stmt->where.putline();
        !          1067:                                        else
        !          1068:                                                last_line.putline();
        !          1069:                                }
        !          1070:                                puttok(ELSE);
        !          1071:                                if (else_stmt->s_list) {
        !          1072:                                        puttok(LC);
        !          1073:                                        else_stmt->print();
        !          1074:                                        puttok(RC);
        !          1075:                                }
        !          1076:                                else
        !          1077:                                        else_stmt->print();
        !          1078:                        }
        !          1079:                }
        !          1080:                break;
        !          1081:        }
        !          1082: 
        !          1083:        case FOR:
        !          1084:        {
        !          1085:        //      int fi = for_init && ((for_init->base!=SM || for_init->memtbl || for_init->s_list);
        !          1086:                int fi = 0;     // is the initializer statement an expression?
        !          1087:                if (for_init) {
        !          1088:                        fi = 1;
        !          1089:                        if (for_init->memtbl==0 && for_init->s_list==0)
        !          1090:                                if (for_init->base==SM)
        !          1091:                                        if (for_init->e->base!=ICALL || for_init->e->e1)
        !          1092:                                                fi = 0;
        !          1093:                }
        !          1094: //error('d',"for(; %d%k; %d%k)",e,e->base,e2,e2->base);
        !          1095:                if (fi) {
        !          1096:                        puttok(LC);
        !          1097:                        for_init->print();
        !          1098:                }
        !          1099:                putstring("for(");
        !          1100:                if (fi==0 && for_init) for_init->e->print();
        !          1101:                putch(';');     // to avoid newline: not puttok(SM)
        !          1102:                if (e) e->print();
        !          1103:                putch(';');
        !          1104:                if (e2) e2->print();
        !          1105:                puttok(RP);
        !          1106:                s->print();
        !          1107:                if (fi) puttok(RC);
        !          1108:                break;
        !          1109:        }
        !          1110: 
        !          1111:        case PAIR:
        !          1112:                if (s&&s2) {
        !          1113:                        puttok(LC);
        !          1114:                        s->print();
        !          1115:                        s2->print();
        !          1116:                        puttok(RC);
        !          1117:                }
        !          1118:                else {
        !          1119:                        if (s) s->print();
        !          1120:                        if (s2) s2->print();
        !          1121:                }
        !          1122:                break;
        !          1123: 
        !          1124:        case BLOCK:
        !          1125:                puttok(LC);
        !          1126: //error('d',"block %d d %d memtbl %d own_tbl %d",this,d,memtbl,own_tbl);
        !          1127:                if (d) d->dcl_print(SM);
        !          1128:                if (memtbl && own_tbl) {
        !          1129:                        Pname n;
        !          1130:                        int i;
        !          1131:                        for (n=memtbl->get_mem(i=1); n; n=memtbl->get_mem(++i)) {
        !          1132:                                if (n->tp && n->n_union==0 && n->tp!=any_type)
        !          1133:                                        switch (n->n_scope) {
        !          1134:                                        case ARGT:
        !          1135:                                        case ARG:
        !          1136:                                                break;
        !          1137:                                        default:
        !          1138: // error('d', "n: %s %k n_key: %k", n->string, n->base, n->n_key);
        !          1139:                                                if ( n->base == TNAME && n->n_key == NESTED ) 
        !          1140:                                                        continue; // printed from nested class
        !          1141:                                                n->dcl_print(0);
        !          1142:                                        }
        !          1143:                        }
        !          1144:                        if (last_ll==0 && s && (last_ll=s->where.line))
        !          1145:                                s->where.putline();
        !          1146:                }
        !          1147:                if (s) s->print();
        !          1148:                if (where2.line == 0) {
        !          1149:                    if (csloc.line) csloc.putline();
        !          1150:                } else {
        !          1151:                    csloc = where2;
        !          1152:                    if (where2.line!=last_line.line)
        !          1153:                        if (last_ll = where2.line)
        !          1154:                                where2.putline();
        !          1155:                        else
        !          1156:                                last_line.putline();
        !          1157:                }
        !          1158:                putstring("}\n");
        !          1159:                if (last_ll && where.line) last_line.line++;
        !          1160:        }
        !          1161: 
        !          1162:        if (s_list) s_list->print();
        !          1163: }
        !          1164: 
        !          1165: /*
        !          1166: void table::dcl_print(TOK s, TOK pub)
        !          1167: 
        !          1168: //     print the declarations of the entries in the order they were inserted
        !          1169: //     ignore labels (tp==0)
        !          1170: 
        !          1171: {
        !          1172:        register Pname* np;
        !          1173:        register int i;
        !          1174: 
        !          1175:        if (this == 0) return;
        !          1176: 
        !          1177:        np = entries;
        !          1178:        for (i=1; i<free_slot; i++) {
        !          1179:                register Pname n = np[i];
        !          1180:                switch (s) {
        !          1181:                case 0:
        !          1182:                        n->dcl_print(0);
        !          1183:                        break;
        !          1184:                case EQ:
        !          1185:                        if (n->tp && n->n_scope == pub) n->dcl_print(0);
        !          1186:                        break;
        !          1187:                case NE:
        !          1188:                        if (n->tp && n->n_scope != pub) n->dcl_print(0);
        !          1189:                        break;
        !          1190:                }
        !          1191:        }
        !          1192: }
        !          1193: */
        !          1194: 
        !          1195: struct ptbl_rec {
        !          1196:       char* pname;
        !          1197:       char* vname;
        !          1198:       ptbl_rec* next;
        !          1199: };
        !          1200: 
        !          1201: static char* ptbl_name;
        !          1202: static ptbl_rec* ptbl_rec_lookup_head = 0;
        !          1203: static ptbl_rec* ptbl_rec_pair_head = 0;
        !          1204: 
        !          1205: void ptbl_init(int flag)
        !          1206: {
        !          1207:       if (!flag) {
        !          1208:              char *p = st_name( "__ptbl_vec__" );      
        !          1209:               ptbl_name = new char[strlen(p)+1];
        !          1210:               strcpy(ptbl_name, p);                         
        !          1211:               delete p;
        !          1212:               fprintf(out_file, "extern struct __mptr* %s[];\n", ptbl_name);
        !          1213:                if (last_ll) last_line.line++;
        !          1214:       }
        !          1215:       else {
        !          1216:               ptbl_rec *r, *p = ptbl_rec_lookup_head;
        !          1217:              if ( p == 0 ) return; // don't generate an empty object
        !          1218:               fprintf(out_file, "struct __mptr* %s[] = {\n", ptbl_name);
        !          1219:                if (last_ll) last_line.line++;
        !          1220:               int i = 0;
        !          1221:               while (p != 0) {
        !          1222:                       r = ptbl_rec_pair_head;
        !          1223:                       while (r && strcmp(r->pname, p->pname))
        !          1224:                               r = r->next;
        !          1225:                       fprintf(out_file, "%s,\n", r->vname);
        !          1226:                        if (last_ll) last_line.line++;
        !          1227:                       p = p->next;
        !          1228:               }
        !          1229:               // fprintf(out_file, "0\n};\n");
        !          1230:               fprintf(out_file, "\n};\n");
        !          1231:                if (last_ll) last_line.line += 2;
        !          1232:       }
        !          1233: }
        !          1234: 
        !          1235: char* ptbl_lookup(char *name)
        !          1236: {
        !          1237:       ptbl_rec *r, *s, *p = ptbl_rec_lookup_head;
        !          1238:       int i = 0;
        !          1239: 
        !          1240:       while (p && strcmp(name, p->pname)) {
        !          1241:               r = p;
        !          1242:               p = p->next;
        !          1243:               i++;
        !          1244:       }
        !          1245: 
        !          1246:       if (p == 0) {
        !          1247:               s = new ptbl_rec;
        !          1248:               s->pname = new char[strlen(name) + 1];
        !          1249:               s->vname = 0;
        !          1250:               s->next = 0;
        !          1251:               strcpy(s->pname, name);
        !          1252:               if (ptbl_rec_lookup_head == 0) 
        !          1253:                       ptbl_rec_lookup_head = s;
        !          1254:               else r->next = s;
        !          1255:       }
        !          1256: 
        !          1257:       char *pp = new char[ strlen(ptbl_name) + 10 ];   
        !          1258:       sprintf(pp, "%s[%d]", ptbl_name, i);
        !          1259:       return(pp);
        !          1260: }
        !          1261: 
        !          1262: void ptbl_add_pair(char* ptbl, char* vtbl)
        !          1263: {
        !          1264: // error('d', "ptbl_add_pair: ptbl: %s, vtbl: %s", ptbl, vtbl );
        !          1265:       ptbl_rec *p = new ptbl_rec;
        !          1266: 
        !          1267:       p->pname = new char[strlen(ptbl) + 1];
        !          1268:       strcpy(p->pname, ptbl);
        !          1269:       p->vname = new char[strlen(vtbl) + 1];
        !          1270: 
        !          1271:       strcpy(p->vname, vtbl);
        !          1272:       p->next = ptbl_rec_pair_head;
        !          1273: 
        !          1274:       ptbl_rec_pair_head = p;
        !          1275: }

unix.superglobalmegacorp.com

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