Annotation of 3BSD/cmd/pi/stat.c, revision 1.1

1.1     ! root        1: /* Copyright (c) 1979 Regents of the University of California */
        !             2: #
        !             3: /*
        !             4:  * pi - Pascal interpreter code translator
        !             5:  *
        !             6:  * Charles Haley, Bill Joy UCB
        !             7:  * Version 1.2 November 1978
        !             8:  */
        !             9: 
        !            10: #include "whoami"
        !            11: #include "0.h"
        !            12: #include "tree.h"
        !            13: 
        !            14: int cntstat;
        !            15: short cnts = 2;
        !            16: #include "opcode.h"
        !            17: 
        !            18: /*
        !            19:  * Statement list
        !            20:  */
        !            21: statlist(r)
        !            22:        int *r;
        !            23: {
        !            24:        register *sl;
        !            25: 
        !            26:        for (sl=r; sl != NIL; sl=sl[2])
        !            27:                statement(sl[1]);
        !            28: }
        !            29: 
        !            30: /*
        !            31:  * Statement
        !            32:  */
        !            33: statement(r)
        !            34:        int *r;
        !            35: {
        !            36:        register *s;
        !            37:        register struct nl *snlp;
        !            38: 
        !            39:        s = r;
        !            40:        snlp = nlp;
        !            41: top:
        !            42:        if (cntstat) {
        !            43:                cntstat = 0;
        !            44:                putcnt();
        !            45:        }
        !            46:        if (s == NIL)
        !            47:                return;
        !            48:        line = s[1];
        !            49:        if (s[0] == T_LABEL) {
        !            50:                labeled(s[2]);
        !            51:                s = s[3];
        !            52:                noreach = 0;
        !            53:                cntstat = 1;
        !            54:                goto top;
        !            55:        }
        !            56:        if (noreach) {
        !            57:                noreach = 0;
        !            58:                warning();
        !            59:                error("Unreachable statement");
        !            60:        }
        !            61:        switch (s[0]) {
        !            62:                case T_PCALL:
        !            63:                        putline();
        !            64:                        proc(s);
        !            65:                        break;
        !            66:                case T_ASGN:
        !            67:                        putline();
        !            68:                        asgnop(s);
        !            69:                        break;
        !            70:                case T_GOTO:
        !            71:                        putline();
        !            72:                        gotoop(s[2]);
        !            73:                        noreach = 1;
        !            74:                        cntstat = 1;
        !            75:                        break;
        !            76:                default:
        !            77:                        level++;
        !            78:                        switch (s[0]) {
        !            79:                                default:
        !            80:                                        panic("stat");
        !            81:                                case T_IF:
        !            82:                                case T_IFEL:
        !            83:                                        ifop(s);
        !            84:                                        break;
        !            85:                                case T_WHILE:
        !            86:                                        whilop(s);
        !            87:                                        noreach = 0;
        !            88:                                        break;
        !            89:                                case T_REPEAT:
        !            90:                                        repop(s);
        !            91:                                        break;
        !            92:                                case T_FORU:
        !            93:                                case T_FORD:
        !            94:                                        forop(s);
        !            95:                                        noreach = 0;
        !            96:                                        break;
        !            97:                                case T_BLOCK:
        !            98:                                        statlist(s[2]);
        !            99:                                        break;
        !           100:                                case T_CASE:
        !           101:                                        putline();
        !           102:                                        caseop(s);
        !           103:                                        break;
        !           104:                                case T_WITH:
        !           105:                                        withop(s);
        !           106:                                        break;
        !           107:                                case T_ASRT:
        !           108:                                        putline();
        !           109:                                        asrtop(s);
        !           110:                                        break;
        !           111:                        }
        !           112:                        --level;
        !           113:                        if (gotos[cbn])
        !           114:                                ungoto();
        !           115:                        break;
        !           116:        }
        !           117:        /*
        !           118:         * Free the temporary name list entries defined in
        !           119:         * expressions, e.g. STRs, and WITHPTRs from withs.
        !           120:         */
        !           121:        nlfree(snlp);
        !           122: }
        !           123: 
        !           124: ungoto()
        !           125: {
        !           126:        register struct nl *p;
        !           127: 
        !           128:        for (p = gotos[cbn]; p != NIL; p = p->chain)
        !           129:                if ((p->nl_flags & NFORWD) != 0) {
        !           130:                        if (p->value[NL_GOLEV] != NOTYET)
        !           131:                                if (p->value[NL_GOLEV] > level)
        !           132:                                        p->value[NL_GOLEV] = level;
        !           133:                } else
        !           134:                        if (p->value[NL_GOLEV] != DEAD)
        !           135:                                if (p->value[NL_GOLEV] > level)
        !           136:                                        p->value[NL_GOLEV] = DEAD;
        !           137: }
        !           138: 
        !           139: putcnt()
        !           140: {
        !           141: 
        !           142:        if (monflg == 0)
        !           143:                return;
        !           144:        cnts++;
        !           145:        put2(O_COUNT, cnts);
        !           146: }
        !           147: 
        !           148: putline()
        !           149: {
        !           150: 
        !           151: #      ifdef OBJ
        !           152:            if (opt('p') != 0)
        !           153:                    put2(O_LINO, line);
        !           154: #      endif
        !           155: }
        !           156: 
        !           157: /*
        !           158:  * With varlist do stat
        !           159:  *
        !           160:  * With statement requires an extra word
        !           161:  * in automatic storage for each level of withing.
        !           162:  * These indirect pointers are initialized here, and
        !           163:  * the scoping effect of the with statement occurs
        !           164:  * because lookup examines the field names of the records
        !           165:  * associated with the WITHPTRs on the withlist.
        !           166:  */
        !           167: withop(s)
        !           168:        int *s;
        !           169: {
        !           170:        register *p;
        !           171:        register struct nl *r;
        !           172:        int i;
        !           173:        int *swl;
        !           174:        long soffset;
        !           175: 
        !           176:        putline();
        !           177:        swl = withlist;
        !           178:        soffset = sizes[cbn].om_off;
        !           179:        for (p = s[2]; p != NIL; p = p[2]) {
        !           180:                sizes[cbn].om_off -= sizeof ( int * );
        !           181: #              ifdef PPC
        !           182:                    putlbracket();
        !           183: #              endif
        !           184:                put2(O_LV | cbn <<9, i = sizes[cbn].om_off);
        !           185:                r = lvalue(p[1], MOD);
        !           186:                if (r == NIL)
        !           187:                        continue;
        !           188:                if (r->class != RECORD) {
        !           189:                        error("Variable in with statement refers to %s, not to a record", nameof(r));
        !           190:                        continue;
        !           191:                }
        !           192:                r = defnl(0, WITHPTR, r, i);
        !           193:                r->nl_next = withlist;
        !           194:                withlist = r;
        !           195: #              ifdef   VAX
        !           196:                    put1 ( O_AS4 );
        !           197: #              endif
        !           198: #              ifdef PDP11
        !           199:                    put1(O_AS2);
        !           200: #              endif
        !           201:        }
        !           202:        if (sizes[cbn].om_off < sizes[cbn].om_max)
        !           203:                sizes[cbn].om_max = sizes[cbn].om_off;
        !           204:        statement(s[3]);
        !           205:        sizes[cbn].om_off = soffset;
        !           206: #      ifdef PPC
        !           207:            putlbracket();
        !           208: #      endif
        !           209:        withlist = swl;
        !           210: }
        !           211: 
        !           212: extern flagwas;
        !           213: /*
        !           214:  * var := expr
        !           215:  */
        !           216: asgnop(r)
        !           217:        int *r;
        !           218: {
        !           219:        register struct nl *p;
        !           220:        register *av;
        !           221: 
        !           222:        if (r == NIL)
        !           223:                return (NIL);
        !           224:        /*
        !           225:         * Asgnop's only function is
        !           226:         * to handle function variable
        !           227:         * assignments.  All other assignment
        !           228:         * stuff is handled by asgnop1.
        !           229:         */
        !           230:        av = r[2];
        !           231:        if (av != NIL && av[0] == T_VAR && av[3] == NIL) {
        !           232:                p = lookup1(av[2]);
        !           233:                if (p != NIL)
        !           234:                        p->nl_flags = flagwas;
        !           235:                if (p != NIL && p->class == FVAR) {
        !           236:                        /*
        !           237:                         * Give asgnop1 the func
        !           238:                         * which is the chain of
        !           239:                         * the FVAR.
        !           240:                         */
        !           241:                        p->nl_flags |= NUSED|NMOD;
        !           242:                        p = p->chain;
        !           243:                        if (p == NIL) {
        !           244:                                rvalue(r[3], NIL);
        !           245:                                return;
        !           246:                        }
        !           247:                        put2(O_LV | bn << 9, p->value[NL_OFFS]);
        !           248:                        if (isa(p->type, "i") && width(p->type) == 1)
        !           249:                                asgnop1(r, nl+T2INT);
        !           250:                        else
        !           251:                                asgnop1(r, p->type);
        !           252:                        return;
        !           253:                }
        !           254:        }
        !           255:        asgnop1(r, NIL);
        !           256: }
        !           257: 
        !           258: /*
        !           259:  * Asgnop1 handles all assignments.
        !           260:  * If p is not nil then we are assigning
        !           261:  * to a function variable, otherwise
        !           262:  * we look the variable up ourselves.
        !           263:  */
        !           264: struct nl *
        !           265: asgnop1(r, p)
        !           266:        int *r;
        !           267:        register struct nl *p;
        !           268: {
        !           269:        register struct nl *p1;
        !           270: 
        !           271:        if (r == NIL)
        !           272:                return (NIL);
        !           273:        if (p == NIL) {
        !           274:                p = lvalue(r[2], MOD|ASGN|NOUSE);
        !           275:                if (p == NIL) {
        !           276:                        rvalue(r[3], NIL);
        !           277:                        return (NIL);
        !           278:                }
        !           279:        }
        !           280:        p1 = rvalue(r[3], p);
        !           281:        if (p1 == NIL)
        !           282:                return (NIL);
        !           283:        if (incompat(p1, p, r[3])) {
        !           284:                cerror("Type of expression clashed with type of variable in assignment");
        !           285:                return (NIL);
        !           286:        }
        !           287:        switch (classify(p)) {
        !           288:                case TBOOL:
        !           289:                case TCHAR:
        !           290:                case TINT:
        !           291:                case TSCAL:
        !           292:                        rangechk(p, p1);
        !           293:                case TDOUBLE:
        !           294:                case TPTR:
        !           295:                        gen(O_AS2, O_AS2, width(p), width(p1));
        !           296:                        break;
        !           297:                default:
        !           298:                        put2(O_AS, width(p));
        !           299:        }
        !           300: #      ifdef PPC
        !           301:            putexpr();
        !           302: #      endif
        !           303:        return (p);     /* Used by for statement */
        !           304: }
        !           305: 
        !           306: /*
        !           307:  * for var := expr [down]to expr do stat
        !           308:  */
        !           309: forop(r)
        !           310:        int *r;
        !           311: {
        !           312:        register struct nl *t1, *t2;
        !           313:        int l1, l2, l3;
        !           314:        long soffset;
        !           315:        register op;
        !           316:        struct nl *p;
        !           317:        int *rr, goc, i;
        !           318: 
        !           319:        p = NIL;
        !           320:        goc = gocnt;
        !           321:        if (r == NIL)
        !           322:                goto aloha;
        !           323:        putline();
        !           324:        /*
        !           325:         * Start with assignment
        !           326:         * of initial value to for variable
        !           327:         */
        !           328:        t1 = asgnop1(r[2], NIL);
        !           329:        if (t1 == NIL) {
        !           330:                rvalue(r[3], NIL);
        !           331:                statement(r[4]);
        !           332:                goto aloha;
        !           333:        }
        !           334:        rr = r[2];              /* Assignment */
        !           335:        rr = rr[2];             /* Lhs variable */
        !           336:        if (rr[3] != NIL) {
        !           337:                error("For variable must be unqualified");
        !           338:                rvalue(r[3], NIL);
        !           339:                statement(r[4]);
        !           340:                goto aloha;
        !           341:        }
        !           342:        p = lookup(rr[2]);
        !           343:        p->value[NL_FORV] = 1;
        !           344:        if (isnta(t1, "bcis")) {
        !           345:                error("For variables cannot be %ss", nameof(t1));
        !           346:                statement(r[4]);
        !           347:                goto aloha;
        !           348:        }
        !           349:        /*
        !           350:         * Allocate automatic
        !           351:         * space for limit variable
        !           352:         */
        !           353:        sizes[cbn].om_off -= 4;
        !           354: #      ifdef PPC
        !           355:            putlbracket();
        !           356: #      endif
        !           357:        if (sizes[cbn].om_off < sizes[cbn].om_max)
        !           358:                sizes[cbn].om_max = sizes[cbn].om_off;
        !           359:        i = sizes[cbn].om_off;
        !           360:        /*
        !           361:         * Initialize the limit variable
        !           362:         */
        !           363:        put2(O_LV | cbn<<9, i);
        !           364:        t2 = rvalue(r[3], NIL);
        !           365:        if (incompat(t2, t1, r[3])) {
        !           366:                cerror("Limit type clashed with index type in 'for' statement");
        !           367:                statement(r[4]);
        !           368:                goto aloha;
        !           369:        }
        !           370:        put1(width(t2) <= 2 ? O_AS24 : O_AS4);
        !           371: #      ifdef PPC
        !           372:            putexpr();
        !           373: #      endif
        !           374:        /*
        !           375:         * See if we can skip the loop altogether
        !           376:         */
        !           377:        rr = r[2];
        !           378:        if (rr != NIL)
        !           379:                rvalue(rr[2], NIL);
        !           380:        put2(O_RV4 | cbn<<9, i);
        !           381:        gen(NIL, r[0] == T_FORU ? T_LE : T_GE, width(t1), 4);
        !           382:        /*
        !           383:         * L1 will be patched to skip the body of the loop.
        !           384:         * L2 marks the top of the loop when we go around.
        !           385:         */
        !           386:        put2(O_IF, (l1 = getlab()));
        !           387:        putlab(l2 = getlab());
        !           388:        putcnt();
        !           389:        statement(r[4]);
        !           390:        /*
        !           391:         * now we see if we get to go again
        !           392:         */
        !           393:        if (opt('t') == 0) {
        !           394:                /*
        !           395:                 * Easy if we dont have to test
        !           396:                 */
        !           397:                put2(O_RV4 | cbn<<9, i);
        !           398:                if (rr != NIL)
        !           399:                        lvalue(rr[2], MOD);
        !           400:                put2((r[0] == T_FORU ? O_FOR1U : O_FOR1D) + (width(t1) >> 1), l2);
        !           401:        } else {
        !           402:                line = r[1];
        !           403:                putline();
        !           404:                if (rr != NIL)
        !           405:                        rvalue(rr[2], NIL);
        !           406:                put2(O_RV4 | cbn << 9, i);
        !           407:                gen(NIL, (r[0] == T_FORU ? T_LT : T_GT), width(t1), 4);
        !           408:                l3 = put2(O_IF, getlab());
        !           409:                lvalue((int *) rr[2], MOD);
        !           410:                rvalue(rr[2], NIL);
        !           411:                put2(O_CON2, 1);
        !           412:                t2 = gen(NIL, r[0] == T_FORU ? T_ADD: T_SUB, width(t1), 2);
        !           413:                rangechk(t1, t2);       /* The point of all this */
        !           414:                gen(O_AS2, O_AS2, width(t1), width(t2));
        !           415:                put2(O_TRA, l2);
        !           416:                patch(l3);
        !           417:        }
        !           418:        sizes[cbn].om_off += 4;
        !           419: #      ifdef PPC
        !           420:            putlbracket();
        !           421: #      endif
        !           422:        patch(l1);
        !           423: aloha:
        !           424:        noreach = 0;
        !           425:        if (p != NIL)
        !           426:                p->value[NL_FORV] = 0;
        !           427:        if (goc != gocnt)
        !           428:                putcnt();
        !           429: }
        !           430: 
        !           431: /*
        !           432:  * if expr then stat [ else stat ]
        !           433:  */
        !           434: ifop(r)
        !           435:        int *r;
        !           436: {
        !           437:        register struct nl *p;
        !           438:        register l1, l2;
        !           439:        int nr, goc;
        !           440: 
        !           441:        goc = gocnt;
        !           442:        if (r == NIL)
        !           443:                return;
        !           444:        putline();
        !           445:        p = rvalue(r[2], NIL);
        !           446:        if (p == NIL) {
        !           447:                statement(r[3]);
        !           448:                noreach = 0;
        !           449:                statement(r[4]);
        !           450:                noreach = 0;
        !           451:                return;
        !           452:        }
        !           453:        if (isnta(p, "b")) {
        !           454:                error("Type of expression in if statement must be Boolean, not %s", nameof(p));
        !           455:                statement(r[3]);
        !           456:                noreach = 0;
        !           457:                statement(r[4]);
        !           458:                noreach = 0;
        !           459:                return;
        !           460:        }
        !           461:        l1 = put2(O_IF, getlab());
        !           462:        putcnt();
        !           463:        statement(r[3]);
        !           464:        nr = noreach;
        !           465:        if (r[4] != NIL) {
        !           466:                /*
        !           467:                 * else stat
        !           468:                 */
        !           469:                --level;
        !           470:                ungoto();
        !           471:                ++level;
        !           472:                l2 = put2(O_TRA, getlab());
        !           473:                patch(l1);
        !           474:                noreach = 0;
        !           475:                statement(r[4]);
        !           476:                noreach &= nr;
        !           477:                l1 = l2;
        !           478:        } else
        !           479:                noreach = 0;
        !           480:        patch(l1);
        !           481:        if (goc != gocnt)
        !           482:                putcnt();
        !           483: }
        !           484: 
        !           485: /*
        !           486:  * while expr do stat
        !           487:  */
        !           488: whilop(r)
        !           489:        int *r;
        !           490: {
        !           491:        register struct nl *p;
        !           492:        register l1, l2;
        !           493:        int goc;
        !           494: 
        !           495:        goc = gocnt;
        !           496:        if (r == NIL)
        !           497:                return;
        !           498:        putlab(l1 = getlab());
        !           499:        putline();
        !           500:        p = rvalue(r[2], NIL);
        !           501:        if (p == NIL) {
        !           502:                statement(r[3]);
        !           503:                noreach = 0;
        !           504:                return;
        !           505:        }
        !           506:        if (isnta(p, "b")) {
        !           507:                error("Type of expression in while statement must be Boolean, not %s", nameof(p));
        !           508:                statement(r[3]);
        !           509:                noreach = 0;
        !           510:                return;
        !           511:        }
        !           512:        put2(O_IF, (l2 = getlab()));
        !           513:        putcnt();
        !           514:        statement(r[3]);
        !           515:        put2(O_TRA, l1);
        !           516:        patch(l2);
        !           517:        if (goc != gocnt)
        !           518:                putcnt();
        !           519: }
        !           520: 
        !           521: /*
        !           522:  * repeat stat* until expr
        !           523:  */
        !           524: repop(r)
        !           525:        int *r;
        !           526: {
        !           527:        register struct nl *p;
        !           528:        register l;
        !           529:        int goc;
        !           530: 
        !           531:        goc = gocnt;
        !           532:        if (r == NIL)
        !           533:                return;
        !           534:        l = putlab(getlab());
        !           535:        putcnt();
        !           536:        statlist(r[2]);
        !           537:        line = r[1];
        !           538:        p = rvalue(r[3], NIL);
        !           539:        if (p == NIL)
        !           540:                return;
        !           541:        if (isnta(p,"b")) {
        !           542:                error("Until expression type must be Boolean, not %s, in repeat statement", nameof(p));
        !           543:                return;
        !           544:        }
        !           545:        put2(O_IF, l);
        !           546:        if (goc != gocnt)
        !           547:                putcnt();
        !           548: }
        !           549: 
        !           550: /*
        !           551:  * assert expr
        !           552:  */
        !           553: asrtop(r)
        !           554:        register int *r;
        !           555: {
        !           556:        register struct nl *q;
        !           557: 
        !           558:        if (opt('s')) {
        !           559:                standard();
        !           560:                error("Assert statement is non-standard");
        !           561:        }
        !           562:        if (!opt('t'))
        !           563:                return;
        !           564:        r = r[2];
        !           565:        q = rvalue((int *) r, NLNIL);
        !           566:        if (q == NIL)
        !           567:                return;
        !           568:        if (isnta(q, "b"))
        !           569:                error("Assert expression must be Boolean, not %ss", nameof(q));
        !           570:        put1(O_ASRT);
        !           571: }

unix.superglobalmegacorp.com

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