|
|
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.