Annotation of 42BSD/ucb/pascal/src/stat.c, revision 1.1

1.1     ! root        1: /* Copyright (c) 1979 Regents of the University of California */
        !             2: 
        !             3: static char sccsid[] = "@(#)stat.c 1.12 9/5/83";
        !             4: 
        !             5: #include "whoami.h"
        !             6: #include "0.h"
        !             7: #include "tree.h"
        !             8: #include "objfmt.h"
        !             9: #ifdef PC
        !            10: #   include "pcops.h"
        !            11: #   include "pc.h"
        !            12: #endif PC
        !            13: #include "tmps.h"
        !            14: 
        !            15: int cntstat;
        !            16: short cnts = 3;
        !            17: #include "opcode.h"
        !            18: 
        !            19: /*
        !            20:  * Statement list
        !            21:  */
        !            22: statlist(r)
        !            23:        int *r;
        !            24: {
        !            25:        register *sl;
        !            26: 
        !            27:        for (sl=r; sl != NIL; sl=sl[2])
        !            28:                statement(sl[1]);
        !            29: }
        !            30: 
        !            31: /*
        !            32:  * Statement
        !            33:  */
        !            34: statement(r)
        !            35:        int *r;
        !            36: {
        !            37:        register *s;
        !            38:        register struct nl *snlp;
        !            39:        struct tmps soffset;
        !            40: 
        !            41:        s = r;
        !            42:        snlp = nlp;
        !            43:        soffset = sizes[cbn].curtmps;
        !            44: top:
        !            45:        if (cntstat) {
        !            46:                cntstat = 0;
        !            47:                putcnt();
        !            48:        }
        !            49:        if (s == NIL)
        !            50:                return;
        !            51:        line = s[1];
        !            52:        if (s[0] == T_LABEL) {
        !            53:                labeled(s[2]);
        !            54:                s = s[3];
        !            55:                noreach = 0;
        !            56:                cntstat = 1;
        !            57:                goto top;
        !            58:        }
        !            59:        if (noreach) {
        !            60:                noreach = 0;
        !            61:                warning();
        !            62:                error("Unreachable statement");
        !            63:        }
        !            64:        switch (s[0]) {
        !            65:                case T_PCALL:
        !            66:                        putline();
        !            67: #                      ifdef OBJ
        !            68:                            proc(s);
        !            69: #                      endif OBJ
        !            70: #                      ifdef PC
        !            71:                            pcproc( s );
        !            72: #                      endif PC
        !            73:                        break;
        !            74:                case T_ASGN:
        !            75:                        putline();
        !            76:                        asgnop(s);
        !            77:                        break;
        !            78:                case T_GOTO:
        !            79:                        putline();
        !            80:                        gotoop(s[2]);
        !            81:                        noreach = 1;
        !            82:                        cntstat = 1;
        !            83:                        break;
        !            84:                default:
        !            85:                        level++;
        !            86:                        switch (s[0]) {
        !            87:                                default:
        !            88:                                        panic("stat");
        !            89:                                case T_IF:
        !            90:                                case T_IFEL:
        !            91:                                        ifop(s);
        !            92:                                        break;
        !            93:                                case T_WHILE:
        !            94:                                        whilop(s);
        !            95:                                        noreach = 0;
        !            96:                                        break;
        !            97:                                case T_REPEAT:
        !            98:                                        repop(s);
        !            99:                                        break;
        !           100:                                case T_FORU:
        !           101:                                case T_FORD:
        !           102:                                        forop(s);
        !           103:                                        noreach = 0;
        !           104:                                        break;
        !           105:                                case T_BLOCK:
        !           106:                                        statlist(s[2]);
        !           107:                                        break;
        !           108:                                case T_CASE:
        !           109:                                        putline();
        !           110: #                                      ifdef OBJ
        !           111:                                            caseop(s);
        !           112: #                                      endif OBJ
        !           113: #                                      ifdef PC
        !           114:                                            pccaseop( s );
        !           115: #                                      endif PC
        !           116:                                        break;
        !           117:                                case T_WITH:
        !           118:                                        withop(s);
        !           119:                                        break;
        !           120:                        }
        !           121:                        --level;
        !           122:                        if (gotos[cbn])
        !           123:                                ungoto();
        !           124:                        break;
        !           125:        }
        !           126:        /*
        !           127:         * Free the temporary name list entries defined in
        !           128:         * expressions, e.g. STRs, and WITHPTRs from withs.
        !           129:         */
        !           130:        nlfree(snlp);
        !           131:            /*
        !           132:             *  free any temporaries allocated for this statement
        !           133:             *  these come from strings and sets.
        !           134:             */
        !           135:        tmpfree(&soffset);
        !           136: }
        !           137: 
        !           138: ungoto()
        !           139: {
        !           140:        register struct nl *p;
        !           141: 
        !           142:        for (p = gotos[cbn]; p != NIL; p = p->chain)
        !           143:                if ((p->nl_flags & NFORWD) != 0) {
        !           144:                        if (p->value[NL_GOLEV] != NOTYET)
        !           145:                                if (p->value[NL_GOLEV] > level)
        !           146:                                        p->value[NL_GOLEV] = level;
        !           147:                } else
        !           148:                        if (p->value[NL_GOLEV] != DEAD)
        !           149:                                if (p->value[NL_GOLEV] > level)
        !           150:                                        p->value[NL_GOLEV] = DEAD;
        !           151: }
        !           152: 
        !           153: putcnt()
        !           154: {
        !           155: 
        !           156:        if (monflg == 0) {
        !           157:                return;
        !           158:        }
        !           159:        inccnt( getcnt() );
        !           160: }
        !           161: 
        !           162: int
        !           163: getcnt()
        !           164:     {
        !           165:        
        !           166:        return ++cnts;
        !           167:     }
        !           168: 
        !           169: inccnt( counter )
        !           170:     int        counter;
        !           171:     {
        !           172: 
        !           173: #      ifdef OBJ
        !           174:            put(2, O_COUNT, counter );
        !           175: #      endif OBJ
        !           176: #      ifdef PC
        !           177:            putRV( PCPCOUNT , 0 , counter * sizeof (long) , NGLOBAL , P2INT );
        !           178:            putleaf( P2ICON , 1 , 0 , P2INT , 0 );
        !           179:            putop( P2ASG P2PLUS , P2INT );
        !           180:            putdot( filename , line );
        !           181: #      endif PC
        !           182:     }
        !           183: 
        !           184: putline()
        !           185: {
        !           186: 
        !           187: #      ifdef OBJ
        !           188:            if (opt('p') != 0)
        !           189:                    put(2, O_LINO, line);
        !           190: 
        !           191:            /*
        !           192:             * put out line number information for pdx
        !           193:             */
        !           194:            lineno(line);
        !           195: 
        !           196: #      endif OBJ
        !           197: #      ifdef PC
        !           198:            static lastline;
        !           199: 
        !           200:            if ( line != lastline ) {
        !           201:                stabline( line );
        !           202:                lastline = line;
        !           203:            }
        !           204:            if ( opt( 'p' ) ) {
        !           205:                if ( opt('t') ) {
        !           206:                    putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
        !           207:                            , "_LINO" );
        !           208:                    putop( P2UNARY P2CALL , P2INT );
        !           209:                    putdot( filename , line );
        !           210:                } else {
        !           211:                    putRV( STMTCOUNT , 0 , 0 , NGLOBAL , P2INT );
        !           212:                    putleaf( P2ICON , 1 , 0 , P2INT , 0 );
        !           213:                    putop( P2ASG P2PLUS , P2INT );
        !           214:                    putdot( filename , line );
        !           215:                }
        !           216:            }
        !           217: #      endif PC
        !           218: }
        !           219: 
        !           220: /*
        !           221:  * With varlist do stat
        !           222:  *
        !           223:  * With statement requires an extra word
        !           224:  * in automatic storage for each level of withing.
        !           225:  * These indirect pointers are initialized here, and
        !           226:  * the scoping effect of the with statement occurs
        !           227:  * because lookup examines the field names of the records
        !           228:  * associated with the WITHPTRs on the withlist.
        !           229:  */
        !           230: withop(s)
        !           231:        int *s;
        !           232: {
        !           233:        register *p;
        !           234:        register struct nl *r;
        !           235:        struct nl       *tempnlp;
        !           236:        int *swl;
        !           237: 
        !           238:        putline();
        !           239:        swl = withlist;
        !           240:        for (p = s[2]; p != NIL; p = p[2]) {
        !           241:                    /*
        !           242:                     *  no one uses the allocated temporary namelist entry,
        !           243:                     *  since we have to use it before we know its type;
        !           244:                     *  but we use its runtime location for the with pointer.
        !           245:                     */
        !           246:                tempnlp = tmpalloc(sizeof(int *), nl + TPTR, REGOK);
        !           247: #              ifdef OBJ
        !           248:                    put(2, O_LV | cbn <<8+INDX, tempnlp -> value[ NL_OFFS ] );
        !           249: #              endif OBJ
        !           250: #              ifdef PC
        !           251:                    putRV( 0 , cbn , tempnlp -> value[ NL_OFFS ] ,
        !           252:                            tempnlp -> extra_flags , P2PTR|P2STRTY );
        !           253: #              endif PC
        !           254:                r = lvalue(p[1], MOD , LREQ );
        !           255:                if (r == NIL)
        !           256:                        continue;
        !           257:                if (r->class != RECORD) {
        !           258:                        error("Variable in with statement refers to %s, not to a record", nameof(r));
        !           259:                        continue;
        !           260:                }
        !           261:                r = defnl(0, WITHPTR, r, tempnlp -> value[ NL_OFFS ] );
        !           262: #              ifdef PC
        !           263:                    r -> extra_flags |= tempnlp -> extra_flags;
        !           264: #              endif PC
        !           265:                r->nl_next = withlist;
        !           266:                withlist = r;
        !           267: #              ifdef OBJ
        !           268:                    put(1, PTR_AS);
        !           269: #              endif OBJ
        !           270: #              ifdef PC
        !           271:                    putop( P2ASSIGN , P2PTR|P2STRTY );
        !           272:                    putdot( filename , line );
        !           273: #              endif PC
        !           274:        }
        !           275:        statement(s[3]);
        !           276:        withlist = swl;
        !           277: }
        !           278: 
        !           279: extern flagwas;
        !           280: /*
        !           281:  * var := expr
        !           282:  */
        !           283: asgnop(r)
        !           284:        int *r;
        !           285: {
        !           286:        register struct nl *p;
        !           287:        register *av;
        !           288: 
        !           289:        if (r == NIL)
        !           290:                return (NIL);
        !           291:        /*
        !           292:         * Asgnop's only function is
        !           293:         * to handle function variable
        !           294:         * assignments.  All other assignment
        !           295:         * stuff is handled by asgnop1.
        !           296:         * the if below checks for unqualified lefthandside:
        !           297:         * necessary for fvars.
        !           298:         */
        !           299:        av = r[2];
        !           300:        if (av != NIL && av[0] == T_VAR && av[3] == NIL) {
        !           301:                p = lookup1(av[2]);
        !           302:                if (p != NIL)
        !           303:                        p->nl_flags = flagwas;
        !           304:                if (p != NIL && p->class == FVAR) {
        !           305:                        /*
        !           306:                         * Give asgnop1 the func
        !           307:                         * which is the chain of
        !           308:                         * the FVAR.
        !           309:                         */
        !           310:                        p->nl_flags |= NUSED|NMOD;
        !           311:                        p = p->chain;
        !           312:                        if (p == NIL) {
        !           313:                                rvalue(r[3], NIL , RREQ );
        !           314:                                return;
        !           315:                        }
        !           316: #                      ifdef OBJ
        !           317:                            put(2, O_LV | bn << 8+INDX, (int)p->value[NL_OFFS]);
        !           318:                            if (isa(p->type, "i") && width(p->type) == 1)
        !           319:                                    asgnop1(r, nl+T2INT);
        !           320:                            else
        !           321:                                    asgnop1(r, p->type);
        !           322: #                      endif OBJ
        !           323: #                      ifdef PC
        !           324:                                /*
        !           325:                                 * this should be the lvalue of the fvar,
        !           326:                                 * but since the second pass knows to use
        !           327:                                 * the address of the left operand of an
        !           328:                                 * assignment, what i want here is an rvalue.
        !           329:                                 * see note in funchdr about fvar allocation.
        !           330:                                 */
        !           331:                            p = p -> ptr[ NL_FVAR ];
        !           332:                            putRV( p -> symbol , bn , p -> value[ NL_OFFS ] ,
        !           333:                                    p -> extra_flags , p2type( p -> type ) );
        !           334:                            asgnop1( r , p -> type );
        !           335: #                      endif PC
        !           336:                        return;
        !           337:                }
        !           338:        }
        !           339:        asgnop1(r, NIL);
        !           340: }
        !           341: 
        !           342: /*
        !           343:  * Asgnop1 handles all assignments.
        !           344:  * If p is not nil then we are assigning
        !           345:  * to a function variable, otherwise
        !           346:  * we look the variable up ourselves.
        !           347:  */
        !           348: struct nl *
        !           349: asgnop1(r, p)
        !           350:        int *r;
        !           351:        register struct nl *p;
        !           352: {
        !           353:        register struct nl *p1;
        !           354:        int w;
        !           355: 
        !           356:        if (r == NIL)
        !           357:                return (NIL);
        !           358:        if (p == NIL) {
        !           359: #          ifdef OBJ
        !           360:                p = lvalue(r[2], MOD|ASGN|NOUSE , LREQ );
        !           361:                w = width(p);
        !           362: #          endif OBJ
        !           363: #          ifdef PC
        !           364:                    /*
        !           365:                     * since the second pass knows that it should reference
        !           366:                     * the lefthandside of asignments, what i need here is
        !           367:                     * an rvalue.
        !           368:                     */
        !           369:                p = lvalue( r[2] , MOD|ASGN|NOUSE , RREQ );
        !           370: #          endif PC
        !           371:            if ( p == NIL ) {
        !           372:                rvalue( r[3] , NIL , RREQ );
        !           373:                return NIL;
        !           374:            }
        !           375:        }
        !           376: #      ifdef OBJ
        !           377:            /*
        !           378:             * assigning to the return value, which is at least
        !           379:             * of width two since it resides on the stack
        !           380:             */
        !           381:            else {
        !           382:                w = width(p);
        !           383:                if (w < 2)
        !           384:                    w = 2;
        !           385:            }
        !           386:            p1 = rvalue(r[3], p , RREQ );
        !           387: #      endif OBJ
        !           388: #      ifdef PC
        !           389:                /*
        !           390:                 *      if this is a scalar assignment,
        !           391:                 *          then i want to rvalue the righthandside.
        !           392:                 *      if this is a structure assignment,
        !           393:                 *          then i want an lvalue to the righthandside.
        !           394:                 *  that's what the intermediate form sez.
        !           395:                 */
        !           396:            switch ( classify( p ) ) {
        !           397:                case TINT:
        !           398:                case TCHAR:
        !           399:                case TBOOL:
        !           400:                case TSCAL:
        !           401:                    precheck( p , "_RANG4" , "_RSNG4" );
        !           402:                case TDOUBLE:
        !           403:                case TPTR:
        !           404:                    p1 = rvalue( r[3] , p , RREQ );
        !           405:                    break;
        !           406:                default:
        !           407:                    p1 = rvalue( r[3] , p , LREQ );
        !           408:                    break;
        !           409:            }
        !           410: #      endif PC
        !           411:        if (p1 == NIL)
        !           412:                return (NIL);
        !           413:        if (incompat(p1, p, r[3])) {
        !           414:                cerror("Type of expression clashed with type of variable in assignment");
        !           415:                return (NIL);
        !           416:        }
        !           417: #      ifdef OBJ
        !           418:            switch (classify(p)) {
        !           419:                    case TINT:
        !           420:                    case TBOOL:
        !           421:                    case TCHAR:
        !           422:                    case TSCAL:
        !           423:                            rangechk(p, p1);
        !           424:                            gen(O_AS2, O_AS2, w, width(p1));
        !           425:                            break;
        !           426:                    case TDOUBLE:
        !           427:                    case TPTR:
        !           428:                            gen(O_AS2, O_AS2, w, width(p1));
        !           429:                            break;
        !           430:                    default:
        !           431:                            put(2, O_AS, w);
        !           432:                            break;
        !           433:            }
        !           434: #      endif OBJ
        !           435: #      ifdef PC
        !           436:            switch (classify(p)) {
        !           437:                    case TINT:
        !           438:                    case TBOOL:
        !           439:                    case TCHAR:
        !           440:                    case TSCAL:
        !           441:                            postcheck(p, p1);
        !           442:                            sconv(p2type(p1), p2type(p));
        !           443:                            putop( P2ASSIGN , p2type( p ) );
        !           444:                            putdot( filename , line );
        !           445:                            break;
        !           446:                    case TPTR:
        !           447:                            putop( P2ASSIGN , p2type( p ) );
        !           448:                            putdot( filename , line );
        !           449:                            break;
        !           450:                    case TDOUBLE:
        !           451:                            sconv(p2type(p1), p2type(p));
        !           452:                            putop( P2ASSIGN , p2type( p ) );
        !           453:                            putdot( filename , line );
        !           454:                            break;
        !           455:                    default:
        !           456:                            putstrop(P2STASG, ADDTYPE(p2type(p), P2PTR),
        !           457:                                        lwidth(p), align(p));
        !           458:                            putdot( filename , line );
        !           459:                            break;
        !           460:            }
        !           461: #      endif PC
        !           462:        return (p);     /* Used by for statement */
        !           463: }
        !           464: 
        !           465: /*
        !           466:  * if expr then stat [ else stat ]
        !           467:  */
        !           468: ifop(r)
        !           469:        int *r;
        !           470: {
        !           471:        register struct nl *p;
        !           472:        register l1, l2;        /* l1 is start of else, l2 is end of else */
        !           473:        int goc;
        !           474:        bool nr;
        !           475: 
        !           476:        goc = gocnt;
        !           477:        if (r == NIL)
        !           478:                return;
        !           479:        putline();
        !           480:        p = rvalue(r[2], NIL , RREQ );
        !           481:        if (p == NIL) {
        !           482:                statement(r[3]);
        !           483:                noreach = 0;
        !           484:                statement(r[4]);
        !           485:                noreach = 0;
        !           486:                return;
        !           487:        }
        !           488:        if (isnta(p, "b")) {
        !           489:                error("Type of expression in if statement must be Boolean, not %s", nameof(p));
        !           490:                statement(r[3]);
        !           491:                noreach = 0;
        !           492:                statement(r[4]);
        !           493:                noreach = 0;
        !           494:                return;
        !           495:        }
        !           496: #      ifdef OBJ
        !           497:            l1 = put(2, O_IF, getlab());
        !           498: #      endif OBJ
        !           499: #      ifdef PC
        !           500:            l1 = getlab();
        !           501:            putleaf( P2ICON , l1 , 0 , P2INT , 0 );
        !           502:            putop( P2CBRANCH , P2INT );
        !           503:            putdot( filename , line );
        !           504: #      endif PC
        !           505:        putcnt();
        !           506:        statement(r[3]);
        !           507:        nr = noreach;
        !           508:        if (r[4] != NIL) {
        !           509:                /*
        !           510:                 * else stat
        !           511:                 */
        !           512:                --level;
        !           513:                ungoto();
        !           514:                ++level;
        !           515: #              ifdef OBJ
        !           516:                    l2 = put(2, O_TRA, getlab());
        !           517: #              endif OBJ
        !           518: #              ifdef PC
        !           519:                    l2 = getlab();
        !           520:                    putjbr( l2 );
        !           521: #              endif PC
        !           522:                patch(l1);
        !           523:                noreach = 0;
        !           524:                statement(r[4]);
        !           525:                noreach = (noreach && nr);
        !           526:                l1 = l2;
        !           527:        } else
        !           528:                noreach = 0;
        !           529:        patch(l1);
        !           530:        if (goc != gocnt)
        !           531:                putcnt();
        !           532: }
        !           533: 
        !           534: /*
        !           535:  * while expr do stat
        !           536:  */
        !           537: whilop(r)
        !           538:        int *r;
        !           539: {
        !           540:        register struct nl *p;
        !           541:        register l1, l2;
        !           542:        int goc;
        !           543: 
        !           544:        goc = gocnt;
        !           545:        if (r == NIL)
        !           546:                return;
        !           547:        putlab(l1 = getlab());
        !           548:        putline();
        !           549:        p = rvalue(r[2], NIL , RREQ );
        !           550:        if (p == NIL) {
        !           551:                statement(r[3]);
        !           552:                noreach = 0;
        !           553:                return;
        !           554:        }
        !           555:        if (isnta(p, "b")) {
        !           556:                error("Type of expression in while statement must be Boolean, not %s", nameof(p));
        !           557:                statement(r[3]);
        !           558:                noreach = 0;
        !           559:                return;
        !           560:        }
        !           561:        l2 = getlab();
        !           562: #      ifdef OBJ
        !           563:            put(2, O_IF, l2);
        !           564: #      endif OBJ
        !           565: #      ifdef PC
        !           566:            putleaf( P2ICON , l2 , 0 , P2INT , 0 );
        !           567:            putop( P2CBRANCH , P2INT );
        !           568:            putdot( filename , line );
        !           569: #      endif PC
        !           570:        putcnt();
        !           571:        statement(r[3]);
        !           572: #      ifdef OBJ
        !           573:            put(2, O_TRA, l1);
        !           574: #      endif OBJ
        !           575: #      ifdef PC
        !           576:            putjbr( l1 );
        !           577: #      endif PC
        !           578:        patch(l2);
        !           579:        if (goc != gocnt)
        !           580:                putcnt();
        !           581: }
        !           582: 
        !           583: /*
        !           584:  * repeat stat* until expr
        !           585:  */
        !           586: repop(r)
        !           587:        int *r;
        !           588: {
        !           589:        register struct nl *p;
        !           590:        register l;
        !           591:        int goc;
        !           592: 
        !           593:        goc = gocnt;
        !           594:        if (r == NIL)
        !           595:                return;
        !           596:        l = putlab(getlab());
        !           597:        putcnt();
        !           598:        statlist(r[2]);
        !           599:        line = r[1];
        !           600:        p = rvalue(r[3], NIL , RREQ );
        !           601:        if (p == NIL)
        !           602:                return;
        !           603:        if (isnta(p,"b")) {
        !           604:                error("Until expression type must be Boolean, not %s, in repeat statement", nameof(p));
        !           605:                return;
        !           606:        }
        !           607: #      ifdef OBJ
        !           608:            put(2, O_IF, l);
        !           609: #      endif OBJ
        !           610: #      ifdef PC
        !           611:            putleaf( P2ICON , l , 0 , P2INT , 0 );
        !           612:            putop( P2CBRANCH , P2INT );
        !           613:            putdot( filename , line );
        !           614: #      endif PC
        !           615:        if (goc != gocnt)
        !           616:                putcnt();
        !           617: }

unix.superglobalmegacorp.com

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