Annotation of 40BSD/cmd/pc0/pcforop.c, revision 1.1.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.