Annotation of 43BSDTahoe/ucb/pascal/src/stat.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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