|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.