|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char sccsid[] = "@(#)exec.c 5.5 (Berkeley) 1/7/86";
9: #endif not lint
10:
11: /*
12: * exec.c
13: *
14: * Routines for handling the semantics of control structures.
15: * F77 compiler, pass 1.
16: *
17: * University of Utah CS Dept modification history:
18: *
19: * $Log: exec.c,v $
20: * Revision 5.6 85/12/20 19:42:46 donn
21: * Change style of error reporting in last fix.
22: *
23: * Revision 5.5 85/12/20 18:54:10 donn
24: * Complain about calls to things which aren't subroutines.
25: *
26: * Revision 5.4 85/12/18 19:57:58 donn
27: * Assignment statements are executable statements -- advance the magic
28: * parser state to forbid DATA statements and statement functions.
29: *
30: * Revision 5.3 85/11/25 00:23:49 donn
31: * 4.3 beta
32: *
33: * Revision 5.2 85/08/10 04:07:36 donn
34: * Changed an error message to correct spelling and be more accurate.
35: * From Jerry Berkman.
36: *
37: * Revision 2.3 85/03/18 08:03:31 donn
38: * Hacks for conversions from type address to numeric type -- prevent addresses
39: * from being stored in shorts and prevent warnings about implicit conversions.
40: *
41: * Revision 2.2 84/09/03 23:18:30 donn
42: * When a DO loop had the same variable as its loop variable and its limit,
43: * the limit temporary was assigned to AFTER the original value of the variable
44: * was destroyed by assigning the initial value to the loop variable. I
45: * swapped the operands of a comparison and changed the direction of the
46: * operator... This only affected programs when optimizing. (This may not
47: * be enough if something alters the order of evaluation of side effects
48: * later on... sigh.)
49: *
50: * Revision 2.1 84/07/19 12:02:53 donn
51: * Changed comment headers for UofU.
52: *
53: * Revision 1.3 84/07/12 18:35:12 donn
54: * Added change to enddo() to detect open 'if' blocks at the ends of loops.
55: *
56: * Revision 1.2 84/06/08 11:22:53 donn
57: * Fixed bug in exdo() -- if a loop parameter contained an instance of the loop
58: * variable and the optimizer was off, the loop variable got converted to
59: * register before the parameters were processed and so the loop parameters
60: * were initialized from garbage in the register instead of the memory version
61: * of the loop variable.
62: *
63: */
64:
65: #include "defs.h"
66: #include "optim.h"
67:
68:
69: /* Logical IF codes
70: */
71:
72:
73: exif(p)
74: expptr p;
75: {
76: register int k;
77: pushctl(CTLIF);
78: ctlstack->elselabel = newlabel();
79:
80: if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL)
81: {
82: if(k != TYERROR)
83: err("non-logical expression in IF statement");
84: frexpr(p);
85: }
86: else if (optimflag)
87: optbuff (SKIFN, p, ctlstack->elselabel, 0);
88: else
89: putif (p, ctlstack->elselabel);
90: }
91:
92:
93:
94: exelif(p)
95: expptr p;
96: {
97: int k,oldelse;
98:
99: if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL)
100: {
101: if(k != TYERROR)
102: err("non-logical expression in IF statement");
103: frexpr(p);
104: }
105: else {
106: if(ctlstack->ctltype == CTLIF)
107: {
108: if(ctlstack->endlabel == 0) ctlstack->endlabel = newlabel();
109: oldelse=ctlstack->elselabel;
110: ctlstack->elselabel = newlabel();
111: if (optimflag)
112: {
113: optbuff (SKGOTO, 0, ctlstack->endlabel, 0);
114: optbuff (SKLABEL, 0, oldelse, 0);
115: optbuff (SKIFN, p, ctlstack->elselabel, 0);
116: }
117: else
118: {
119: putgoto (ctlstack->endlabel);
120: putlabel (oldelse);
121: putif (p, ctlstack->elselabel);
122: }
123: }
124: else execerr("elseif out of place", CNULL);
125: }
126: }
127:
128:
129:
130:
131:
132: exelse()
133: {
134: if(ctlstack->ctltype==CTLIF)
135: {
136: if(ctlstack->endlabel == 0)
137: ctlstack->endlabel = newlabel();
138: ctlstack->ctltype = CTLELSE;
139: if (optimflag)
140: {
141: optbuff (SKGOTO, 0, ctlstack->endlabel, 0);
142: optbuff (SKLABEL, 0, ctlstack->elselabel, 0);
143: }
144: else
145: {
146: putgoto (ctlstack->endlabel);
147: putlabel (ctlstack->elselabel);
148: }
149: }
150:
151: else execerr("else out of place", CNULL);
152: }
153:
154:
155: exendif()
156: {
157: if (ctlstack->ctltype == CTLIF)
158: {
159: if (optimflag)
160: {
161: optbuff (SKLABEL, 0, ctlstack->elselabel, 0);
162: if (ctlstack->endlabel)
163: optbuff (SKLABEL, 0, ctlstack->endlabel, 0);
164: }
165: else
166: {
167: putlabel (ctlstack->elselabel);
168: if (ctlstack->endlabel)
169: putlabel (ctlstack->endlabel);
170: }
171: popctl ();
172: }
173: else if (ctlstack->ctltype == CTLELSE)
174: {
175: if (optimflag)
176: optbuff (SKLABEL, 0, ctlstack->endlabel, 0);
177: else
178: putlabel (ctlstack->endlabel);
179: popctl ();
180: }
181: else
182: execerr("endif out of place", CNULL);
183: }
184:
185:
186:
187: LOCAL pushctl(code)
188: int code;
189: {
190: register int i;
191:
192: /* fprintf(diagfile,"old blklevel %d \n",blklevel); dmpframe(ctlstack); */
193: if(++ctlstack >= lastctl)
194: many("loops or if-then-elses", 'c');
195: ctlstack->ctltype = code;
196: for(i = 0 ; i < 4 ; ++i)
197: ctlstack->ctlabels[i] = 0;
198: ++blklevel;
199: }
200:
201:
202: LOCAL popctl()
203: {
204: if( ctlstack-- < ctls )
205: fatal("control stack empty");
206: --blklevel;
207: }
208:
209:
210:
211: LOCAL poplab()
212: {
213: register struct Labelblock *lp;
214:
215: for(lp = labeltab ; lp < highlabtab ; ++lp)
216: if(lp->labdefined)
217: {
218: /* mark all labels in inner blocks unreachable */
219: if(lp->blklevel > blklevel)
220: lp->labinacc = YES;
221: }
222: else if(lp->blklevel > blklevel)
223: {
224: /* move all labels referred to in inner blocks out a level */
225: lp->blklevel = blklevel;
226: }
227: }
228:
229:
230:
231: /* BRANCHING CODE
232: */
233:
234: exgoto(lab)
235: struct Labelblock *lab;
236: {
237: if (optimflag)
238: optbuff (SKGOTO, 0, lab->labelno, 0);
239: else
240: putgoto (lab->labelno);
241: }
242:
243:
244:
245:
246:
247:
248:
249: exequals(lp, rp)
250: register struct Primblock *lp;
251: register expptr rp;
252: {
253: register Namep np;
254:
255: if(lp->tag != TPRIM)
256: {
257: err("assignment to a non-variable");
258: frexpr(lp);
259: frexpr(rp);
260: }
261: else if(lp->namep->vclass!=CLVAR && lp->argsp)
262: {
263: if(parstate >= INEXEC)
264: err("undimensioned array or statement function out of order");
265: else
266: mkstfunct(lp, rp);
267: }
268: else
269: {
270: np = (Namep) lp->namep;
271: if (np->vclass == CLPROC && np->vprocclass == PTHISPROC
272: && proctype == TYSUBR)
273: {
274: err("assignment to a subroutine name");
275: return;
276: }
277: if(parstate < INDATA)
278: enddcl();
279: parstate = INEXEC;
280: if (optimflag)
281: optbuff (SKEQ, mkexpr(OPASSIGN, mklhs(lp), fixtype(rp)), 0, 0);
282: else
283: puteq (mklhs(lp), fixtype(rp));
284: }
285: }
286:
287:
288:
289: mkstfunct(lp, rp)
290: struct Primblock *lp;
291: expptr rp;
292: {
293: register struct Primblock *p;
294: register Namep np;
295: chainp args;
296:
297: if(parstate < INDATA)
298: {
299: enddcl();
300: parstate = INDATA;
301: }
302:
303: np = lp->namep;
304: if(np->vclass == CLUNKNOWN)
305: np->vclass = CLPROC;
306: else
307: {
308: dclerr("redeclaration of statement function", np);
309: return;
310: }
311: np->vprocclass = PSTFUNCT;
312: np->vstg = STGSTFUNCT;
313: impldcl(np);
314: args = (lp->argsp ? lp->argsp->listp : CHNULL);
315: np->varxptr.vstfdesc = mkchain(args , rp );
316:
317: for( ; args ; args = args->nextp)
318: if( args->datap->tag!=TPRIM ||
319: (p = (struct Primblock *) (args->datap) )->argsp ||
320: p->fcharp || p->lcharp )
321: err("non-variable argument in statement function definition");
322: else
323: {
324: args->datap = (tagptr) (p->namep);
325: vardcl(p->namep);
326: free(p);
327: }
328: }
329:
330:
331:
332: excall(name, args, nstars, labels)
333: Namep name;
334: struct Listblock *args;
335: int nstars;
336: struct Labelblock *labels[ ];
337: {
338: register expptr p;
339:
340: if (name->vdcldone)
341: if (name->vclass != CLPROC && name->vclass != CLENTRY)
342: {
343: dclerr("call to non-subroutine", name);
344: return;
345: }
346: else if (name->vtype != TYSUBR)
347: {
348: dclerr("subroutine invocation of function", name);
349: return;
350: }
351: settype(name, TYSUBR, ENULL);
352: p = mkfunct( mkprim(name, args, CHNULL) );
353: p->exprblock.vtype = p->exprblock.leftp->headblock.vtype = TYINT;
354: if (nstars > 0)
355: if (optimflag)
356: optbuff (SKCMGOTO, p, nstars, labels);
357: else
358: putcmgo (p, nstars, labels);
359: else
360: if (optimflag)
361: optbuff (SKCALL, p, 0, 0);
362: else
363: putexpr (p);
364: }
365:
366:
367:
368: exstop(stop, p)
369: int stop;
370: register expptr p;
371: {
372: char *q;
373: int n;
374: expptr mkstrcon();
375:
376: if(p)
377: {
378: if( ! ISCONST(p) )
379: {
380: execerr("pause/stop argument must be constant", CNULL);
381: frexpr(p);
382: p = mkstrcon(0, CNULL);
383: }
384: else if( ISINT(p->constblock.vtype) )
385: {
386: q = convic(p->constblock.const.ci);
387: n = strlen(q);
388: if(n > 0)
389: {
390: p->constblock.const.ccp = copyn(n, q);
391: p->constblock.vtype = TYCHAR;
392: p->constblock.vleng = (expptr) ICON(n);
393: }
394: else
395: p = (expptr) mkstrcon(0, CNULL);
396: }
397: else if(p->constblock.vtype != TYCHAR)
398: {
399: execerr("pause/stop argument must be integer or string", CNULL);
400: p = (expptr) mkstrcon(0, CNULL);
401: }
402: }
403: else p = (expptr) mkstrcon(0, CNULL);
404:
405: if (optimflag)
406: optbuff ((stop ? SKSTOP : SKPAUSE), p, 0, 0);
407: else
408: putexpr (call1(TYSUBR, (stop ? "s_stop" : "s_paus"), p));
409: }
410:
411:
412: /* UCB DO LOOP CODE */
413:
414: #define DOINIT par[0]
415: #define DOLIMIT par[1]
416: #define DOINCR par[2]
417:
418: #define CONSTINIT const[0]
419: #define CONSTLIMIT const[1]
420: #define CONSTINCR const[2]
421:
422: #define VARSTEP 0
423: #define POSSTEP 1
424: #define NEGSTEP 2
425:
426:
427: exdo(range, spec)
428: int range;
429: chainp spec;
430:
431: {
432: register expptr p, q;
433: expptr q1;
434: register Namep np;
435: chainp cp;
436: register int i;
437: int dotype, incsign;
438: Addrp dovarp, dostgp;
439: expptr par[3];
440: expptr const[3];
441: Slotp doslot;
442:
443: pushctl(CTLDO);
444: dorange = ctlstack->dolabel = range;
445: np = (Namep) (spec->datap);
446: ctlstack->donamep = NULL;
447: if(np->vdovar)
448: {
449: errstr("nested loops with variable %s", varstr(VL,np->varname));
450: return;
451: }
452:
453: dovarp = mkplace(np);
454: dotype = dovarp->vtype;
455:
456: if( ! ONEOF(dotype, MSKINT|MSKREAL) )
457: {
458: err("bad type on DO variable");
459: return;
460: }
461:
462:
463: for(i=0 , cp = spec->nextp ; cp!=NULL && i<3 ; cp = cp->nextp)
464: {
465: p = fixtype((expptr) cpexpr((tagptr) q = cp->datap));
466: if(!ONEOF(p->headblock.vtype, MSKINT|MSKREAL) )
467: {
468: err("bad type on DO parameter");
469: return;
470: }
471:
472:
473: if (ISCONST(q))
474: const[i] = mkconv(dotype, q);
475: else
476: {
477: frexpr(q);
478: const[i] = NULL;
479: }
480:
481: par[i++] = mkconv(dotype, p);
482: }
483:
484: frchain(&spec);
485: switch(i)
486: {
487: case 0:
488: case 1:
489: err("too few DO parameters");
490: return;
491:
492: case 2:
493: DOINCR = (expptr) ICON(1);
494: CONSTINCR = ICON(1);
495:
496: case 3:
497: break;
498:
499: default:
500: err("too many DO parameters");
501: return;
502: }
503:
504: ctlstack->donamep = np;
505:
506: np->vdovar = YES;
507: if( !optimflag && enregister(np) )
508: {
509: /* stgp points to a storage version, varp to a register version */
510: dostgp = dovarp;
511: dovarp = mkplace(np);
512: }
513: else
514: dostgp = NULL;
515:
516: for (i = 0; i < 4; i++)
517: ctlstack->ctlabels[i] = newlabel();
518:
519: if( CONSTLIMIT )
520: ctlstack->domax = DOLIMIT;
521: else
522: ctlstack->domax = (expptr) mktemp(dotype, PNULL);
523:
524: if( CONSTINCR )
525: {
526: ctlstack->dostep = DOINCR;
527: if( (incsign = conssgn(CONSTINCR)) == 0)
528: err("zero DO increment");
529: ctlstack->dostepsign = (incsign > 0 ? POSSTEP : NEGSTEP);
530: }
531: else
532: {
533: ctlstack->dostep = (expptr) mktemp(dotype, PNULL);
534: ctlstack->dostepsign = VARSTEP;
535: }
536:
537: if (optimflag)
538: doslot = optbuff (SKDOHEAD,0,0,ctlstack);
539:
540: if( CONSTLIMIT && CONSTINIT && ctlstack->dostepsign!=VARSTEP)
541: {
542: if (optimflag)
543: optbuff (SKEQ,mkexpr(OPASSIGN,cpexpr(dovarp),cpexpr(DOINIT)),
544: 0,0);
545: else
546: puteq (cpexpr(dovarp), cpexpr(DOINIT));
547: if( ! onetripflag )
548: {
549: q = mkexpr(OPMINUS, cpexpr(CONSTLIMIT), cpexpr(CONSTINIT));
550: if((incsign * conssgn(q)) == -1)
551: {
552: warn("DO range never executed");
553: if (optimflag)
554: optbuff (SKGOTO,0,ctlstack->endlabel,0);
555: else
556: putgoto (ctlstack->endlabel);
557: }
558: frexpr(q);
559: }
560: }
561:
562:
563: else if (ctlstack->dostepsign != VARSTEP && !onetripflag)
564: {
565: if (CONSTLIMIT)
566: q = (expptr) cpexpr(ctlstack->domax);
567: else
568: q = mkexpr(OPASSIGN, cpexpr(ctlstack->domax), DOLIMIT);
569: q1 = mkexpr(OPASSIGN, cpexpr(dovarp), DOINIT);
570: q = mkexpr( (ctlstack->dostepsign == POSSTEP ? OPGE : OPLE),
571: q, q1);
572: if (optimflag)
573: optbuff (SKIFN,q, ctlstack->endlabel,0);
574: else
575: putif (q, ctlstack->endlabel);
576: }
577: else
578: {
579: if (!CONSTLIMIT)
580: if (optimflag)
581: optbuff (SKEQ,
582: mkexpr(OPASSIGN,cpexpr(ctlstack->domax),DOLIMIT),0,0);
583: else
584: puteq (cpexpr(ctlstack->domax), DOLIMIT);
585: q = DOINIT;
586: if (!onetripflag)
587: q = mkexpr(OPMINUS, q,
588: mkexpr(OPASSIGN, cpexpr(ctlstack->dostep),
589: DOINCR) );
590: if (optimflag)
591: optbuff (SKEQ,mkexpr(OPASSIGN,cpexpr(dovarp), q),0,0);
592: else
593: puteq (cpexpr(dovarp), q);
594: if (onetripflag && ctlstack->dostepsign == VARSTEP)
595: if (optimflag)
596: optbuff (SKEQ,
597: mkexpr(OPASSIGN,cpexpr(ctlstack->dostep),DOINCR),0,0);
598: else
599: puteq (cpexpr(ctlstack->dostep), DOINCR);
600: }
601:
602: if (ctlstack->dostepsign == VARSTEP)
603: {
604: expptr incr,test;
605: if (onetripflag)
606: if (optimflag)
607: optbuff (SKGOTO,0,ctlstack->dobodylabel,0);
608: else
609: putgoto (ctlstack->dobodylabel);
610: else
611: if (optimflag)
612: optbuff (SKIFN,mkexpr(OPGE, cpexpr(ctlstack->dostep), ICON(0)),
613: ctlstack->doneglabel,0);
614: else
615: putif (mkexpr(OPGE, cpexpr(ctlstack->dostep), ICON(0)),
616: ctlstack->doneglabel);
617: if (optimflag)
618: optbuff (SKLABEL,0,ctlstack->doposlabel,0);
619: else
620: putlabel (ctlstack->doposlabel);
621: incr = mkexpr(OPPLUSEQ, cpexpr(dovarp), cpexpr(ctlstack->dostep));
622: test = mkexpr(OPLE, incr, cpexpr(ctlstack->domax));
623: if (optimflag)
624: optbuff (SKIFN,test, ctlstack->endlabel,0);
625: else
626: putif (test, ctlstack->endlabel);
627: }
628:
629: if (optimflag)
630: optbuff (SKLABEL,0,ctlstack->dobodylabel,0);
631: else
632: putlabel (ctlstack->dobodylabel);
633: if (dostgp)
634: {
635: if (optimflag)
636: optbuff (SKEQ,mkexpr(OPASSIGN,dostgp, dovarp),0,0);
637: else
638: puteq (dostgp, dovarp);
639: }
640: else
641: frexpr(dovarp);
642: if (optimflag)
643: doslot->nullslot = optbuff (SKNULL,0,0,0);
644:
645: frexpr(CONSTINIT);
646: frexpr(CONSTLIMIT);
647: frexpr(CONSTINCR);
648: }
649:
650:
651: enddo(here)
652: int here;
653:
654: {
655: register struct Ctlframe *q;
656: Namep np;
657: Addrp ap, rv;
658: expptr t;
659: register int i;
660: Slotp doslot;
661:
662: while (here == dorange)
663: {
664: while (ctlstack->ctltype == CTLIF || ctlstack->ctltype == CTLELSE)
665: {
666: execerr("missing endif", CNULL);
667: exendif();
668: }
669:
670: if (np = ctlstack->donamep)
671: {
672: rv = mkplace (np);
673:
674: t = mkexpr(OPPLUSEQ, cpexpr(rv), cpexpr(ctlstack->dostep) );
675:
676: if (optimflag)
677: doslot = optbuff (SKENDDO,0,0,ctlstack);
678:
679: if (ctlstack->dostepsign == VARSTEP)
680: if (optimflag)
681: {
682: optbuff (SKIFN,
683: mkexpr(OPLE, cpexpr(ctlstack->dostep), ICON(0)),
684: ctlstack->doposlabel,0);
685: optbuff (SKLABEL,0,ctlstack->doneglabel,0);
686: optbuff (SKIFN,mkexpr(OPLT, t, ctlstack->domax),
687: ctlstack->dobodylabel,0);
688: }
689: else
690: {
691: putif (mkexpr(OPLE, cpexpr(ctlstack->dostep), ICON(0)),
692: ctlstack->doposlabel);
693: putlabel (ctlstack->doneglabel);
694: putif (mkexpr(OPLT, t, ctlstack->domax),
695: ctlstack->dobodylabel);
696: }
697: else
698: {
699: int op;
700: op = (ctlstack->dostepsign == POSSTEP ? OPGT : OPLT);
701: if (optimflag)
702: optbuff (SKIFN, mkexpr(op,t,ctlstack->domax),
703: ctlstack->dobodylabel,0);
704: else
705: putif (mkexpr(op, t, ctlstack->domax),
706: ctlstack->dobodylabel);
707: }
708: if (optimflag)
709: optbuff (SKLABEL,0,ctlstack->endlabel,0);
710: else
711: putlabel (ctlstack->endlabel);
712:
713: if (ap = memversion(np))
714: {
715: if (optimflag)
716: optbuff (SKEQ,mkexpr(OPASSIGN,ap, rv),0,0);
717: else
718: puteq (ap, rv);
719: }
720: else
721: frexpr(rv);
722: for (i = 0; i < 4; i++)
723: ctlstack->ctlabels[i] = 0;
724: if (!optimflag)
725: deregister(ctlstack->donamep);
726: ctlstack->donamep->vdovar = NO;
727: if (optimflag)
728: doslot->nullslot = optbuff (SKNULL,0,0,0);
729: }
730:
731: popctl();
732: poplab();
733:
734: dorange = 0;
735: for (q = ctlstack; q >= ctls; --q)
736: if (q->ctltype == CTLDO)
737: {
738: dorange = q->dolabel;
739: break;
740: }
741: }
742: }
743:
744:
745: exassign(vname, labelval)
746: Namep vname;
747: struct Labelblock *labelval;
748: {
749: Addrp p;
750: expptr mkaddcon();
751:
752: p = mkplace(vname);
753: #if SZADDR > SZSHORT
754: if( p->vtype == TYSHORT )
755: err("insufficient precision in ASSIGN variable");
756: else
757: #endif
758: if( ! ONEOF(p->vtype, MSKINT|MSKADDR) )
759: err("noninteger assign variable");
760: else
761: {
762: if (optimflag)
763: optbuff (SKASSIGN, p, labelval->labelno, 0);
764: else
765: puteq (p, intrconv(p->vtype, mkaddcon(labelval->labelno)));
766: }
767: }
768:
769:
770:
771: exarif(expr, neglab, zerlab, poslab)
772: expptr expr;
773: struct Labelblock *neglab, *zerlab, *poslab;
774: {
775: register int lm, lz, lp;
776: struct Labelblock *labels[3];
777:
778: lm = neglab->labelno;
779: lz = zerlab->labelno;
780: lp = poslab->labelno;
781: expr = fixtype(expr);
782:
783: if( ! ONEOF(expr->headblock.vtype, MSKINT|MSKREAL) )
784: {
785: err("invalid type of arithmetic if expression");
786: frexpr(expr);
787: }
788: else
789: {
790: if(lm == lz)
791: exar2(OPLE, expr, lm, lp);
792: else if(lm == lp)
793: exar2(OPNE, expr, lm, lz);
794: else if(lz == lp)
795: exar2(OPGE, expr, lz, lm);
796: else
797: if (optimflag)
798: {
799: labels[0] = neglab;
800: labels[1] = zerlab;
801: labels[2] = poslab;
802: optbuff (SKARIF, expr, 0, labels);
803: }
804: else
805: prarif(expr, lm, lz, lp);
806: }
807: }
808:
809:
810:
811: LOCAL exar2 (op, e, l1, l2)
812: int op;
813: expptr e;
814: int l1,l2;
815: {
816: if (optimflag)
817: {
818: optbuff (SKIFN, mkexpr(op, e, ICON(0)), l2, 0);
819: optbuff (SKGOTO, 0, l1, 0);
820: }
821: else
822: {
823: putif (mkexpr(op, e, ICON(0)), l2);
824: putgoto (l1);
825: }
826: }
827:
828:
829: exreturn(p)
830: register expptr p;
831: {
832: if(procclass != CLPROC)
833: warn("RETURN statement in main or block data");
834: if(p && (proctype!=TYSUBR || procclass!=CLPROC) )
835: {
836: err("alternate return in nonsubroutine");
837: p = 0;
838: }
839:
840: if(p)
841: if (optimflag)
842: optbuff (SKRETURN, p, retlabel, 0);
843: else
844: {
845: putforce (TYINT, p);
846: putgoto (retlabel);
847: }
848: else
849: if (optimflag)
850: optbuff (SKRETURN, p,
851: (proctype==TYSUBR ? ret0label : retlabel), 0);
852: else
853: putgoto (proctype==TYSUBR ? ret0label : retlabel);
854: }
855:
856:
857:
858: exasgoto(labvar)
859: struct Hashentry *labvar;
860: {
861: register Addrp p;
862:
863: p = mkplace(labvar);
864: if( ! ISINT(p->vtype) )
865: err("assigned goto variable must be integer");
866: else
867: if (optimflag)
868: optbuff (SKASGOTO, p, 0, 0);
869: else
870: putbranch (p);
871: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.