Annotation of 41BSD/cmd/pc0/pcforop.c, revision 1.1

1.1     ! root        1: /* Copyright (c) 1979 Regents of the University of California */
        !             2: 
        !             3: static char sccsid[] = "@(#)pcforop.c 1.1 8/27/80";
        !             4: 
        !             5: #include       "whoami.h"
        !             6: #ifdef PC
        !             7:     /*
        !             8:      * and the rest of the file
        !             9:      */
        !            10: #include       "0.h"
        !            11: #include       "opcode.h"
        !            12: #include       "tree.h"
        !            13: #include       "pc.h"
        !            14: #include       "pcops.h"
        !            15:     /*
        !            16:      * forop for pc:
        !            17:      *     this evaluates the initial and termination expressions,
        !            18:      *     checks them to see if the loop executes at all, and then
        !            19:      *     does the assignment and the loop.
        !            20:      * arg here looks like:
        !            21:      * arg[0]  T_FORU or T_FORD
        !            22:      *    [1]  lineof "for"
        !            23:      *    [2]  [0]     T_ASGN
        !            24:      *         [1]     lineof ":="
        !            25:      *         [2]     [0]     T_VAR
        !            26:      *                 [1]     lineof id
        !            27:      *                 [2]     char * to id
        !            28:      *                 [3]     qualifications
        !            29:      *         [3]     initial expression
        !            30:      *   [3]   termination expression
        !            31:      *   [4]   statement
        !            32:      */
        !            33: pcforop( arg )
        !            34:     int        *arg;
        !            35:     {
        !            36:        int             *lhs;
        !            37:        struct nl       *forvar;
        !            38:        struct nl       *fortype;
        !            39:        int             forctype;
        !            40:        int             *init;
        !            41:        struct nl       *inittype;
        !            42:        int             initoff;
        !            43:        int             *term;
        !            44:        struct nl       *termtype;
        !            45:        int             termoff;
        !            46:        int             *stat;
        !            47:        int             goc;            /* saved gocnt */
        !            48:        int             again;          /* label at the top of the loop */
        !            49:        int             after;          /* label after the end of the loop */
        !            50: 
        !            51:        goc = gocnt;
        !            52:        forvar = NIL;
        !            53:        if ( arg == NIL ) {
        !            54:            goto byebye;
        !            55:        }
        !            56:        if ( arg[2] == NIL ) {
        !            57:            goto byebye;
        !            58:        }
        !            59:        line = arg[1];
        !            60:        putline();
        !            61:        lhs = ( (int *) arg[2] )[2];
        !            62:        init = ( (int *) arg[2] )[3];
        !            63:        term = arg[3];
        !            64:        stat = arg[4];
        !            65:        if ( lhs[3] != NIL ) {
        !            66:            error("For variable must be unqualified");
        !            67:            rvalue( init , NIL , RREQ );
        !            68:            rvalue( term , NIL , RREQ );
        !            69:            statement( stat );
        !            70:            goto byebye;
        !            71:        }
        !            72:            /*
        !            73:             * and this marks the variable as used!!!
        !            74:             */
        !            75:        forvar = lookup( lhs[2] );
        !            76:        if ( forvar == NIL ) {
        !            77:            rvalue( init , NIL , RREQ );
        !            78:            rvalue( term , NIL , RREQ );
        !            79:            statement( stat );
        !            80:            goto byebye;
        !            81:        }
        !            82:            /*
        !            83:             * find out the type of the loop variable
        !            84:             */
        !            85:        codeoff();
        !            86:        fortype = lvalue( lhs , MOD , RREQ );
        !            87:        codeon();
        !            88:            /*
        !            89:             * mark the forvar so we can't change it during the loop
        !            90:             */
        !            91:        forvar -> value[ NL_FORV ] = 1;
        !            92:        if ( fortype == NIL ) {
        !            93:            rvalue( init , NIL , RREQ );
        !            94:            rvalue( term , NIL , RREQ );
        !            95:            statement( stat );
        !            96:            goto byebye;
        !            97:        }
        !            98:        if ( isnta( fortype , "bcis" ) ) {
        !            99:            error("For variables cannot be %ss" , nameof( fortype ) );
        !           100:            rvalue( init , NIL , RREQ );
        !           101:            rvalue( term , NIL , RREQ );
        !           102:            statement( stat );
        !           103:            goto byebye;
        !           104:        }
        !           105:        forctype = p2type( fortype );
        !           106:            /*
        !           107:             * allocate space for the initial and termination expressions
        !           108:             */
        !           109:        sizes[cbn].om_off -= sizeof( long );
        !           110:        initoff = sizes[cbn].om_off;
        !           111:        sizes[cbn].om_off -= sizeof( long );
        !           112:        termoff = sizes[cbn].om_off;
        !           113:        putlbracket( ftnno , -sizes[cbn].om_off );
        !           114:        if ( sizes[cbn].om_off < sizes[cbn].om_max ) {
        !           115:            sizes[cbn].om_max = sizes[cbn].om_off;
        !           116:        }
        !           117:            /*
        !           118:             * compute and save the initial expression
        !           119:             */
        !           120:        putRV( 0 , cbn , initoff , forctype );
        !           121:        inittype = rvalue( init , fortype , RREQ );
        !           122:        if ( incompat( inittype , fortype , init ) ) {
        !           123:            cerror("Type of initial expression clashed with index type in 'for' statement");
        !           124:            rvalue( term , NIL , RREQ );
        !           125:            statement( stat );
        !           126:            goto byebye;
        !           127:        }
        !           128:        putop( P2ASSIGN , forctype );
        !           129:        putdot( filename , line );
        !           130:            /*
        !           131:             * compute and save the termination expression
        !           132:             */
        !           133:        putRV( 0 , cbn , termoff , forctype );
        !           134:        termtype = rvalue( term , fortype , RREQ );
        !           135:        if ( incompat( termtype , fortype , term ) ) {
        !           136:            cerror("Type of limit expression clashed with index type in 'for' statement");
        !           137:            statement( stat );
        !           138:            goto byebye;
        !           139:        }
        !           140:        putop( P2ASSIGN , forctype );
        !           141:        putdot( filename , line );
        !           142:            /*
        !           143:             * we can skip the loop altogether if !( init <= term )
        !           144:             */
        !           145:        after = getlab();
        !           146:        putRV( 0 , cbn , initoff , forctype );
        !           147:        putRV( 0 , cbn , termoff , forctype );
        !           148:        putop( ( arg[0] == T_FORU ? P2LE : P2GE ) , forctype );
        !           149:        putleaf( P2ICON , after , 0 , P2INT , 0 );
        !           150:        putop( P2CBRANCH , P2INT );
        !           151:        putdot( filename , line );
        !           152:            /*
        !           153:             * okay, then we have to execute the body,
        !           154:             * but first, assign the initial expression to the for variable.
        !           155:             * see the note in asgnop1 about why this is an rvalue.
        !           156:             */
        !           157:        rvalue( lhs , NIL , RREQ );
        !           158:        if ( opt( 't' ) ) {
        !           159:            precheck( fortype , "_RANG4" , "_RSNG4" );
        !           160:        }
        !           161:        putRV( 0 , cbn , initoff , forctype );
        !           162:        if ( opt( 't' ) ) {
        !           163:            postcheck( fortype );
        !           164:        }
        !           165:        putop( P2ASSIGN , forctype );
        !           166:        putdot( filename , line );
        !           167:            /*
        !           168:             * put down the label at the top of the loop
        !           169:             */
        !           170:        again = getlab();
        !           171:        putlab( again );
        !           172:        putcnt();
        !           173:            /*
        !           174:             * and don't forget ...
        !           175:             */
        !           176:        statement( arg[ 4 ] );
        !           177:            /*
        !           178:             * wasn't that fun?  do we get to do it again?
        !           179:             *  we don't do it again if ( !( forvar < limit ) )
        !           180:             *  pretend we were doing this at the top of the loop
        !           181:             */
        !           182:        line = arg[ 1 ];
        !           183:        if ( opt( 'p' ) ) {
        !           184:            if ( opt('t') ) {
        !           185:                putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
        !           186:                        , "_LINO" );
        !           187:                putop( P2UNARY P2CALL , P2INT );
        !           188:                putdot( filename , line );
        !           189:            } else {
        !           190:                putRV( STMTCOUNT , 0 , 0 , P2INT );
        !           191:                putleaf( P2ICON , 1 , 0 , P2INT , 0 );
        !           192:                putop( P2ASG P2PLUS , P2INT );
        !           193:                putdot( filename , line );
        !           194:            }
        !           195:        }
        !           196:        rvalue( lhs , NIL , RREQ );
        !           197:        putRV( 0 , cbn , termoff , forctype );
        !           198:        putop( ( arg[ 0 ] == T_FORU ? P2LT : P2GT ) , forctype );
        !           199:        putleaf( P2ICON , after , 0 , P2INT , 0 );
        !           200:        putop( P2CBRANCH , P2INT );
        !           201:        putdot( filename , line );
        !           202:            /*
        !           203:             * okay, so we have to do it again,
        !           204:             * but first, increment the for variable.
        !           205:             * there it is again, an rvalue on the lhs of an assignment.
        !           206:             */
        !           207:        rvalue( lhs , NIL , RREQ );
        !           208:        if ( opt( 't' ) ) {
        !           209:            precheck( fortype , "_RANG4" , "_RSNG4" );
        !           210:        }
        !           211:        rvalue( lhs , NIL , RREQ );
        !           212:        putleaf( P2ICON , 1 , 0 , forctype , 0 );
        !           213:        putop( ( arg[0] == T_FORU ? P2PLUS : P2MINUS ) , forctype );
        !           214:        if ( opt( 't' ) ) {
        !           215:            postcheck( fortype );
        !           216:        }
        !           217:        putop( P2ASSIGN , forctype );
        !           218:        putdot( filename , line );
        !           219:            /*
        !           220:             * and do it all again
        !           221:             */
        !           222:        putjbr( again );
        !           223:            /*
        !           224:             * deallocate the initial and limit variables
        !           225:             */
        !           226:        sizes[cbn].om_off += 2 * ( sizeof( long ) );
        !           227:        putlbracket( ftnno , -sizes[cbn].om_off );
        !           228:            /*
        !           229:             * and here we are
        !           230:             */
        !           231:        putlab( after );
        !           232: byebye:
        !           233:        noreach = 0;
        !           234:        if ( forvar != NIL ) {
        !           235:            forvar -> value[ NL_FORV ] = 0;
        !           236:        }
        !           237:        if ( goc != gocnt ) {
        !           238:            putcnt();
        !           239:        }
        !           240:     }
        !           241: #endif PC

unix.superglobalmegacorp.com

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