Commit | Line | Data |
---|---|---|
64836102 C |
1 | #include "defs" |
2 | ||
3 | exlab(n) | |
4 | register int n; | |
5 | { | |
6 | if(n==0 && thisexec->labelno && !(thisexec->labused)) | |
7 | { | |
8 | thisexec->labused = 1; | |
9 | n = thisexec->labelno; | |
10 | } | |
11 | ||
12 | if(!prevbg || n!=0) /* avoid empty statement */ | |
13 | { | |
14 | if(comments && !afterif) putcomment(); | |
15 | putic(ICBEGIN, n); | |
16 | putic(ICINDENT, ctllevel); | |
17 | if(n != 0) | |
18 | if(stnos[n] != 0) | |
19 | fatal("statement number changed"); | |
20 | else stnos[n] = ( nxtstno += tailor.deltastno) ; | |
21 | TEST fprintf(diagfile, "LABEL %d\n", n); | |
22 | thisexec->nftnst++; | |
23 | afterif = 0; | |
24 | } | |
25 | } | |
26 | ||
27 | ||
28 | exgoto(n) | |
29 | int n; | |
30 | { | |
31 | exlab(0); | |
32 | exgo1(n); | |
33 | } | |
34 | ||
35 | exgoind(n) | |
36 | int n; | |
37 | { | |
38 | exlab(0); | |
39 | putic(ICKEYWORD,FGOTO); | |
40 | putic(ICINDPTR,n); | |
41 | TEST fprintf(diagfile, "goto indirect %o\n", n); | |
42 | } | |
43 | ||
44 | ||
45 | ||
46 | exgo1(n) | |
47 | int n; | |
48 | { | |
49 | putic(ICKEYWORD,FGOTO); | |
50 | putic(ICLABEL,n); | |
51 | TEST fprintf(diagfile, "goto %d\n", n); | |
52 | } | |
53 | ||
54 | ||
55 | excompgoto(labs,index) | |
56 | ptr labs; | |
57 | register ptr index; | |
58 | { | |
59 | register int first; | |
60 | register ptr p; | |
61 | ||
62 | index = simple(LVAL,index); | |
63 | if(tailor.ftn77) | |
64 | exlab(0); | |
65 | else | |
66 | { | |
67 | int ncases = 0; | |
68 | for(p = labs ; p ; p = p->nextp) | |
69 | ++ncases; | |
70 | exif1( mknode(TLOGOP, OPAND, | |
71 | mknode(TRELOP,OPGT, cpexpr(index), mkint(0)), | |
72 | mknode(TRELOP,OPLE, cpexpr(index), mkint(ncases)) )); | |
73 | } | |
74 | ||
75 | putic(ICKEYWORD, FGOTO); | |
76 | putic(ICOP,OPLPAR); | |
77 | ||
78 | first = 1; | |
79 | for(p = labs ; p ; p = p->nextp) | |
80 | { | |
81 | if(first) first = 0; | |
82 | else putic(ICOP,OPCOMMA); | |
83 | putic(ICLABEL,p->datap); | |
84 | } | |
85 | putic(ICOP,OPRPAR); | |
86 | frchain(&labs); | |
87 | ||
88 | putic(ICOP,OPCOMMA); | |
89 | prexpr(index); | |
90 | frexpr(index); | |
91 | TEST fprintf(diagfile, "computed goto\n"); | |
92 | } | |
93 | ||
94 | ||
95 | ||
96 | ||
97 | excall(p) | |
98 | register ptr p; | |
99 | { | |
100 | register ptr q1, q2, q3; | |
101 | ptr mkholl(), exioop(); | |
102 | ||
103 | if(p->tag==TNAME || p->tag==TFTNBLOCK) | |
104 | p = mkcall(p, PNULL); | |
105 | ||
106 | if(p->tag == TERROR) | |
107 | { | |
108 | frexpr(p); | |
109 | return; | |
110 | } | |
111 | if(p->tag != TCALL) | |
112 | badtag("excall", p->tag); | |
113 | ||
114 | q1 = p->leftp; | |
115 | q2 = (q1->tag==TFTNBLOCK ? q1 : q1->sthead->varp); | |
116 | if(q2->vtype!=TYUNDEFINED && q2->vtype!=TYSUBR) | |
117 | { | |
118 | dclerr("attempt to use a variable as a subroutine", p->sthead->namep); | |
119 | frexpr(p); | |
120 | return; | |
121 | } | |
122 | q1->vtype = q2->vtype = TYSUBR; | |
123 | if(q1->vdcldone==0) | |
124 | dclit(q1); | |
125 | ||
126 | if(q1->tag == TNAME) | |
127 | { | |
128 | if( equals(q2->sthead->namep, "stop") ) | |
129 | { | |
130 | exlab(0); | |
131 | putic(ICKEYWORD, FSTOP); | |
132 | TEST fprintf(diagfile,"stop "); | |
133 | if( (q1 = p->rightp) && (q1 = q1->leftp) ) | |
134 | prexpr( simple(RVAL, q1->datap) ); | |
135 | goto done; | |
136 | } | |
137 | if( ioop(q2->sthead->namep) ) | |
138 | { | |
139 | exioop(p,NO); | |
140 | goto done; | |
141 | } | |
142 | } | |
143 | ||
144 | p = simple(RVAL,p); | |
145 | exlab(0); | |
146 | putic(ICKEYWORD,FCALL); | |
147 | TEST fprintf(diagfile, "call "); | |
148 | /* replace character constant arguments with holleriths */ | |
149 | if( (q1=p->rightp) && tailor.hollincall) | |
150 | for(q1 = q1->leftp ; q1 ; q1 = q1->nextp) | |
151 | if( (q2 = q1->datap)->tag==TCONST | |
152 | && q2->vtype==TYCHAR) | |
153 | { | |
154 | q2->vtype = TYHOLLERITH; | |
155 | frexpr(q2->vtypep); | |
156 | q2->vtypep = 0; | |
157 | q2->leftp = mkholl(q3 = q2->leftp); | |
158 | cfree(q3); | |
159 | } | |
160 | prexpr( p ); | |
161 | ||
162 | done: frexpr(p); | |
163 | } | |
164 | ||
165 | ||
166 | ||
167 | ||
168 | ptr mkholl(p) | |
169 | register char *p; | |
170 | { | |
171 | register char *q, *t, *s; | |
172 | int n; | |
173 | ||
174 | n = strlen(p); | |
175 | q = convic(n); | |
176 | s = t = calloc(n + 2 + strlen(q) , 1); | |
177 | while(*q) | |
178 | *t++ = *q++; | |
179 | *t++ = 'h'; | |
180 | while(*t++ = *p++ ) | |
181 | ; | |
182 | return(s); | |
183 | } | |
184 | ||
185 | ||
186 | ptr ifthen() | |
187 | { | |
188 | ptr p; | |
189 | ptr addexec(); | |
190 | ||
191 | p = addexec(); | |
192 | thisexec->brnchend = 0; | |
193 | if(thisexec->nftnst == 0) | |
194 | { | |
195 | exlab(0); | |
196 | putic(ICKEYWORD,FCONTINUE); | |
197 | thisexec->nftnst = 1; | |
198 | } | |
199 | if(thisexec->nftnst>1 || thisexec->labeled || thisexec->uniffable ) | |
200 | { | |
201 | if(thisctl->breaklab == 0) | |
202 | thisctl->breaklab = nextlab(); | |
203 | indifs[thisctl->indifn] = thisctl->breaklab; | |
204 | } | |
205 | else thisctl->breaklab = 0; | |
206 | return(p); | |
207 | } | |
208 | ||
209 | ||
210 | ||
211 | exasgn(l,o,r) | |
212 | ptr l; | |
213 | int o; | |
214 | ptr r; | |
215 | { | |
216 | exlab(0); | |
217 | if(l->vdcldone == 0) | |
218 | dclit(l); | |
219 | frexpr( simple(LVAL , mknode(TASGNOP,o,l,r)) ); | |
220 | } | |
221 | ||
222 | exretn(p) | |
223 | ptr p; | |
224 | { | |
225 | if(p) | |
226 | { | |
227 | if(procname && procname->vtype && procname->vtype!=TYCHAR && | |
228 | (procname->vtype!=TYLCOMPLEX || tailor.lngcxtype!=NULL) ) | |
229 | { | |
230 | if(p->tag!=TNAME || p->sthead!=procname->sthead) | |
231 | exasgn( cpexpr(procname) , OPASGN, p); | |
232 | } | |
233 | else execerr("can only return values in a function", PNULL); | |
234 | } | |
235 | else if(procname && procname->vtype) | |
236 | warn("function return without data value"); | |
237 | exlab(0); | |
238 | putic(ICKEYWORD, FRETURN); | |
239 | ||
240 | TEST {fprintf(diagfile, "exec: return( " ); prexpr(p); fprintf(diagfile, ")\n" ); } | |
241 | } | |
242 | ||
243 | ||
244 | exnull() | |
245 | { | |
246 | if(thisexec->labelno && !(thisexec->labused) ) | |
247 | { | |
248 | exlab(0); | |
249 | putic(ICKEYWORD,FCONTINUE); | |
250 | } | |
251 | } | |
252 | ||
253 | ||
254 | ||
255 | ||
256 | exbrk(opnext,levskip,btype) | |
257 | int opnext; | |
258 | ptr levskip; | |
259 | int btype; | |
260 | { | |
261 | ||
262 | if(opnext && (btype==STSWITCH || btype==STPROC)) | |
263 | execerr("illegal next", PNULL); | |
264 | else if(!opnext && btype==STPROC) | |
265 | exretn(PNULL); | |
266 | else brknxtlab(opnext,levskip,btype); | |
267 | TEST fprintf(diagfile, "exec: %s\n", (opnext ? "next" : "exit")); | |
268 | ||
269 | } | |
270 | ||
271 | ||
272 | ||
273 | exif(e) | |
274 | register ptr e; | |
275 | { | |
276 | int tag; | |
277 | ||
278 | if( (tag = e->tag)==TERROR || e->vtype!=TYLOG) | |
279 | { | |
280 | frexpr(e); | |
281 | e = mkconst(TYLOG, ".true."); | |
282 | if(tag != TERROR) | |
283 | execerr("non-logical conditional expression in if", PNULL); | |
284 | } | |
285 | TEST fprintf(diagfile, "exif called\n"); | |
286 | e = simple(RVAL,e); | |
287 | exlab(0); | |
288 | putic(ICKEYWORD,FIF2); | |
289 | indifs[thisctl->indifn = nextindif()] = 0; | |
290 | putic(ICINDPTR, thisctl->indifn); | |
291 | putic(ICOP,OPLPAR); | |
292 | prexpr(e); | |
293 | putic(ICOP,OPRPAR); | |
294 | putic(ICMARK,0); | |
295 | putic(ICOP,OPLPAR); | |
296 | prexpr(e = simple(RVAL, mknode(TNOTOP,OPNOT,e,PNULL))); | |
297 | putic(ICOP,OPRPAR); | |
298 | putic(ICMARK,0); | |
299 | afterif = 1; | |
300 | frexpr(e); | |
301 | } | |
302 | ||
303 | ||
304 | exifgo(e,l) | |
305 | ptr e; | |
306 | int l; | |
307 | { | |
308 | exlab(0); | |
309 | exif1(e); | |
310 | exgo1(l); | |
311 | } | |
312 | ||
313 | ||
314 | exif1(e) | |
315 | register ptr e; | |
316 | { | |
317 | e = simple(RVAL,e); | |
318 | exlab(0); | |
319 | putic(ICKEYWORD,FIF1); | |
320 | putic(ICOP,OPLPAR); | |
321 | TEST fprintf(diagfile, "if1 "); | |
322 | prexpr( e ); | |
323 | frexpr(e); | |
324 | putic(ICOP,OPRPAR); | |
325 | putic(ICBLANK, 1); | |
326 | } | |
327 | ||
328 | ||
329 | ||
330 | ||
331 | ||
332 | ||
333 | ||
334 | brkcase() | |
335 | { | |
336 | ptr bgnexec(); | |
337 | ||
338 | if(ncases==0 /* && thisexec->prevexec->brnchend==0 */ ) | |
339 | { | |
340 | exbrk(0, PNULL, 0); | |
341 | addexec(); | |
342 | bgnexec(); | |
343 | } | |
344 | ncases = 1; | |
345 | } | |
346 | ||
347 | ||
348 | brknxtlab(opnext, levp, btype) | |
349 | int opnext; | |
350 | ptr levp; | |
351 | int btype; | |
352 | { | |
353 | register ptr p; | |
354 | int levskip; | |
355 | ||
356 | levskip = ( levp ? convci(levp->leftp) : 1); | |
357 | if(levskip <= 0) | |
358 | { | |
359 | execerr("illegal break count %d", levskip); | |
360 | return; | |
361 | } | |
362 | ||
363 | for(p = thisctl ; p!=0 ; p = p->prevctl) | |
364 | if( (btype==0 || p->subtype==btype) && | |
365 | p->subtype!=STIF && p->subtype!=STPROC && | |
366 | (!opnext || p->subtype!=STSWITCH) ) | |
367 | if(--levskip == 0) break; | |
368 | ||
369 | if(p == 0) | |
370 | { | |
371 | execerr("invalid break/next", PNULL); | |
372 | return; | |
373 | } | |
374 | ||
375 | if(p->subtype==STREPEAT && opnext) | |
376 | exgoind(p->indifn); | |
377 | else if(opnext) | |
378 | exgoto(p->nextlab); | |
379 | else { | |
380 | if(p->breaklab == 0) | |
381 | p->breaklab = nextlab(); | |
382 | exgoto(p->breaklab); | |
383 | } | |
384 | } | |
385 | ||
386 | ||
387 | ||
388 | ptr doloop(p1,p2,p3) | |
389 | ptr p1; | |
390 | ptr p2; | |
391 | ptr p3; | |
392 | { | |
393 | register ptr p, q; | |
394 | register int i; | |
395 | int val[3]; | |
396 | ||
397 | p = ALLOC(doblock); | |
398 | p->tag = TDOBLOCK; | |
399 | ||
400 | if(p1->tag!=TASGNOP || p1->subtype!=OPASGN || p1->leftp->tag!=TNAME) | |
401 | { | |
402 | p->dovar = gent(TYINT, PNULL); | |
403 | p->dopar[0] = p1; | |
404 | } | |
405 | else { | |
406 | p->dovar = p1->leftp; | |
407 | p->dopar[0] = p1->rightp; | |
408 | frexpblock(p1); | |
409 | } | |
410 | if(p2 == 0) | |
411 | { | |
412 | p->dopar[1] = p->dopar[0]; | |
413 | p->dopar[0] = mkint(1); | |
414 | } | |
415 | else p->dopar[1] = p2; | |
416 | p->dopar[2] = p3; | |
417 | ||
418 | for(i = 0; i<3 ; ++i) | |
419 | { | |
420 | if(q = p->dopar[i]) | |
421 | { | |
422 | if( (q->tag==TNAME || q->tag==TTEMP) && | |
423 | (q->vsubs || q->voffset) ) | |
424 | p->dopar[i] = simple(RVAL,mknode(TASGNOP,0, | |
425 | gent(TYINT,PNULL), q)); | |
426 | else | |
427 | p->dopar[i] = simple(LVAL, coerce(TYINT, q) ); | |
428 | ||
429 | if(isicon(p->dopar[i], &val[i])) | |
430 | { | |
431 | if(val[i] <= 0) | |
432 | execerr("do parameter out of range", PNULL); | |
433 | } | |
434 | else val[i] = -1; | |
435 | } | |
436 | } | |
437 | ||
438 | if(val[0]>0 && val[1]>0 && val[0]>val[1]) | |
439 | execerr("do parameters out of order", PNULL); | |
440 | return(p); | |
441 | } |