BSD 4_3_Reno development
[unix-history] / usr / src / old / efl / exec.c
CommitLineData
64836102
C
1#include "defs"
2
3exlab(n)
4register int n;
5{
6if(n==0 && thisexec->labelno && !(thisexec->labused))
7 {
8 thisexec->labused = 1;
9 n = thisexec->labelno;
10 }
11
12if(!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
28exgoto(n)
29int n;
30{
31exlab(0);
32exgo1(n);
33}
34
35exgoind(n)
36int n;
37{
38exlab(0);
39putic(ICKEYWORD,FGOTO);
40putic(ICINDPTR,n);
41TEST fprintf(diagfile, "goto indirect %o\n", n);
42}
43
44
45
46exgo1(n)
47int n;
48{
49putic(ICKEYWORD,FGOTO);
50putic(ICLABEL,n);
51TEST fprintf(diagfile, "goto %d\n", n);
52}
53
54
55excompgoto(labs,index)
56ptr labs;
57register ptr index;
58{
59register int first;
60register ptr p;
61
62index = simple(LVAL,index);
63if(tailor.ftn77)
64 exlab(0);
65else
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
75putic(ICKEYWORD, FGOTO);
76putic(ICOP,OPLPAR);
77
78first = 1;
79for(p = labs ; p ; p = p->nextp)
80 {
81 if(first) first = 0;
82 else putic(ICOP,OPCOMMA);
83 putic(ICLABEL,p->datap);
84 }
85putic(ICOP,OPRPAR);
86frchain(&labs);
87
88putic(ICOP,OPCOMMA);
89prexpr(index);
90frexpr(index);
91TEST fprintf(diagfile, "computed goto\n");
92}
93
94
95
96
97excall(p)
98register ptr p;
99{
100register ptr q1, q2, q3;
101ptr mkholl(), exioop();
102
103if(p->tag==TNAME || p->tag==TFTNBLOCK)
104 p = mkcall(p, PNULL);
105
106if(p->tag == TERROR)
107 {
108 frexpr(p);
109 return;
110 }
111if(p->tag != TCALL)
112 badtag("excall", p->tag);
113
114q1 = p->leftp;
115q2 = (q1->tag==TFTNBLOCK ? q1 : q1->sthead->varp);
116if(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 }
122q1->vtype = q2->vtype = TYSUBR;
123if(q1->vdcldone==0)
124 dclit(q1);
125
126if(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
144p = simple(RVAL,p);
145exlab(0);
146putic(ICKEYWORD,FCALL);
147TEST fprintf(diagfile, "call ");
148/* replace character constant arguments with holleriths */
149if( (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 }
160prexpr( p );
161
162done: frexpr(p);
163}
164
165
166
167
168ptr mkholl(p)
169register char *p;
170{
171register char *q, *t, *s;
172int n;
173
174n = strlen(p);
175q = convic(n);
176s = t = calloc(n + 2 + strlen(q) , 1);
177while(*q)
178 *t++ = *q++;
179*t++ = 'h';
180while(*t++ = *p++ )
181 ;
182return(s);
183}
184
185
186ptr ifthen()
187{
188ptr p;
189ptr addexec();
190
191p = addexec();
192thisexec->brnchend = 0;
193if(thisexec->nftnst == 0)
194 {
195 exlab(0);
196 putic(ICKEYWORD,FCONTINUE);
197 thisexec->nftnst = 1;
198 }
199if(thisexec->nftnst>1 || thisexec->labeled || thisexec->uniffable )
200 {
201 if(thisctl->breaklab == 0)
202 thisctl->breaklab = nextlab();
203 indifs[thisctl->indifn] = thisctl->breaklab;
204 }
205else thisctl->breaklab = 0;
206return(p);
207}
208
209
210
211exasgn(l,o,r)
212ptr l;
213int o;
214ptr r;
215{
216exlab(0);
217if(l->vdcldone == 0)
218 dclit(l);
219frexpr( simple(LVAL , mknode(TASGNOP,o,l,r)) );
220}
221
222exretn(p)
223ptr p;
224{
225if(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 }
235else if(procname && procname->vtype)
236 warn("function return without data value");
237exlab(0);
238putic(ICKEYWORD, FRETURN);
239
240TEST {fprintf(diagfile, "exec: return( " ); prexpr(p); fprintf(diagfile, ")\n" ); }
241}
242
243
244exnull()
245{
246if(thisexec->labelno && !(thisexec->labused) )
247 {
248 exlab(0);
249 putic(ICKEYWORD,FCONTINUE);
250 }
251}
252
253
254
255
256exbrk(opnext,levskip,btype)
257int opnext;
258ptr levskip;
259int btype;
260{
261
262if(opnext && (btype==STSWITCH || btype==STPROC))
263 execerr("illegal next", PNULL);
264else if(!opnext && btype==STPROC)
265 exretn(PNULL);
266else brknxtlab(opnext,levskip,btype);
267TEST fprintf(diagfile, "exec: %s\n", (opnext ? "next" : "exit"));
268
269}
270
271
272
273exif(e)
274register ptr e;
275{
276int tag;
277
278if( (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 }
285TEST fprintf(diagfile, "exif called\n");
286e = simple(RVAL,e);
287exlab(0);
288putic(ICKEYWORD,FIF2);
289indifs[thisctl->indifn = nextindif()] = 0;
290putic(ICINDPTR, thisctl->indifn);
291putic(ICOP,OPLPAR);
292prexpr(e);
293putic(ICOP,OPRPAR);
294putic(ICMARK,0);
295putic(ICOP,OPLPAR);
296prexpr(e = simple(RVAL, mknode(TNOTOP,OPNOT,e,PNULL)));
297putic(ICOP,OPRPAR);
298putic(ICMARK,0);
299afterif = 1;
300frexpr(e);
301}
302
303
304exifgo(e,l)
305ptr e;
306int l;
307{
308exlab(0);
309exif1(e);
310exgo1(l);
311}
312
313
314exif1(e)
315register ptr e;
316{
317e = simple(RVAL,e);
318exlab(0);
319putic(ICKEYWORD,FIF1);
320putic(ICOP,OPLPAR);
321TEST fprintf(diagfile, "if1 ");
322prexpr( e );
323frexpr(e);
324putic(ICOP,OPRPAR);
325putic(ICBLANK, 1);
326}
327
328
329
330
331
332
333
334brkcase()
335{
336ptr bgnexec();
337
338if(ncases==0 /* && thisexec->prevexec->brnchend==0 */ )
339 {
340 exbrk(0, PNULL, 0);
341 addexec();
342 bgnexec();
343 }
344ncases = 1;
345}
346
347
348brknxtlab(opnext, levp, btype)
349int opnext;
350ptr levp;
351int btype;
352{
353register ptr p;
354int levskip;
355
356levskip = ( levp ? convci(levp->leftp) : 1);
357if(levskip <= 0)
358 {
359 execerr("illegal break count %d", levskip);
360 return;
361 }
362
363for(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
369if(p == 0)
370 {
371 execerr("invalid break/next", PNULL);
372 return;
373 }
374
375if(p->subtype==STREPEAT && opnext)
376 exgoind(p->indifn);
377else if(opnext)
378 exgoto(p->nextlab);
379else {
380 if(p->breaklab == 0)
381 p->breaklab = nextlab();
382 exgoto(p->breaklab);
383 }
384}
385
386
387
388ptr doloop(p1,p2,p3)
389ptr p1;
390ptr p2;
391ptr p3;
392{
393register ptr p, q;
394register int i;
395int val[3];
396
397p = ALLOC(doblock);
398p->tag = TDOBLOCK;
399
400if(p1->tag!=TASGNOP || p1->subtype!=OPASGN || p1->leftp->tag!=TNAME)
401 {
402 p->dovar = gent(TYINT, PNULL);
403 p->dopar[0] = p1;
404 }
405else {
406 p->dovar = p1->leftp;
407 p->dopar[0] = p1->rightp;
408 frexpblock(p1);
409 }
410if(p2 == 0)
411 {
412 p->dopar[1] = p->dopar[0];
413 p->dopar[0] = mkint(1);
414 }
415else p->dopar[1] = p2;
416p->dopar[2] = p3;
417
418for(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
438if(val[0]>0 && val[1]>0 && val[0]>val[1])
439 execerr("do parameters out of order", PNULL);
440return(p);
441}