122809Smckusick /* 222809Smckusick * Copyright (c) 1980 Regents of the University of California. 322809Smckusick * All rights reserved. The Berkeley software License Agreement 422809Smckusick * specifies the terms and conditions for redistribution. 522809Smckusick */ 622809Smckusick 722809Smckusick #ifndef lint 8*25735Sdonn static char sccsid[] = "@(#)exec.c 5.5 (Berkeley) 01/07/86"; 922809Smckusick #endif not lint 1022809Smckusick 1122809Smckusick /* 1222809Smckusick * exec.c 1322809Smckusick * 1422809Smckusick * Routines for handling the semantics of control structures. 1522809Smckusick * F77 compiler, pass 1. 1622809Smckusick * 1722809Smckusick * University of Utah CS Dept modification history: 1822809Smckusick * 1924476Sdonn * $Log: exec.c,v $ 20*25735Sdonn * Revision 5.6 85/12/20 19:42:46 donn 21*25735Sdonn * Change style of error reporting in last fix. 22*25735Sdonn * 23*25735Sdonn * Revision 5.5 85/12/20 18:54:10 donn 24*25735Sdonn * Complain about calls to things which aren't subroutines. 25*25735Sdonn * 26*25735Sdonn * Revision 5.4 85/12/18 19:57:58 donn 27*25735Sdonn * Assignment statements are executable statements -- advance the magic 28*25735Sdonn * parser state to forbid DATA statements and statement functions. 29*25735Sdonn * 30*25735Sdonn * Revision 5.3 85/11/25 00:23:49 donn 31*25735Sdonn * 4.3 beta 32*25735Sdonn * 3324476Sdonn * Revision 5.2 85/08/10 04:07:36 donn 3424476Sdonn * Changed an error message to correct spelling and be more accurate. 3524476Sdonn * From Jerry Berkman. 3624476Sdonn * 3722809Smckusick * Revision 2.3 85/03/18 08:03:31 donn 3822809Smckusick * Hacks for conversions from type address to numeric type -- prevent addresses 3922809Smckusick * from being stored in shorts and prevent warnings about implicit conversions. 4022809Smckusick * 4122809Smckusick * Revision 2.2 84/09/03 23:18:30 donn 4222809Smckusick * When a DO loop had the same variable as its loop variable and its limit, 4322809Smckusick * the limit temporary was assigned to AFTER the original value of the variable 4422809Smckusick * was destroyed by assigning the initial value to the loop variable. I 4522809Smckusick * swapped the operands of a comparison and changed the direction of the 4622809Smckusick * operator... This only affected programs when optimizing. (This may not 4722809Smckusick * be enough if something alters the order of evaluation of side effects 4822809Smckusick * later on... sigh.) 4922809Smckusick * 5022809Smckusick * Revision 2.1 84/07/19 12:02:53 donn 5122809Smckusick * Changed comment headers for UofU. 5222809Smckusick * 5322809Smckusick * Revision 1.3 84/07/12 18:35:12 donn 5422809Smckusick * Added change to enddo() to detect open 'if' blocks at the ends of loops. 5522809Smckusick * 5622809Smckusick * Revision 1.2 84/06/08 11:22:53 donn 5722809Smckusick * Fixed bug in exdo() -- if a loop parameter contained an instance of the loop 5822809Smckusick * variable and the optimizer was off, the loop variable got converted to 5922809Smckusick * register before the parameters were processed and so the loop parameters 6022809Smckusick * were initialized from garbage in the register instead of the memory version 6122809Smckusick * of the loop variable. 6222809Smckusick * 6322809Smckusick */ 6422809Smckusick 6522809Smckusick #include "defs.h" 6622809Smckusick #include "optim.h" 6722809Smckusick 6822809Smckusick 6922809Smckusick /* Logical IF codes 7022809Smckusick */ 7122809Smckusick 7222809Smckusick 7322809Smckusick exif(p) 7422809Smckusick expptr p; 7522809Smckusick { 7622809Smckusick register int k; 7722809Smckusick pushctl(CTLIF); 7822809Smckusick ctlstack->elselabel = newlabel(); 7922809Smckusick 8022809Smckusick if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL) 8122809Smckusick { 8222809Smckusick if(k != TYERROR) 8322809Smckusick err("non-logical expression in IF statement"); 8422809Smckusick frexpr(p); 8522809Smckusick } 8622809Smckusick else if (optimflag) 8722809Smckusick optbuff (SKIFN, p, ctlstack->elselabel, 0); 8822809Smckusick else 8922809Smckusick putif (p, ctlstack->elselabel); 9022809Smckusick } 9122809Smckusick 9222809Smckusick 9322809Smckusick 9422809Smckusick exelif(p) 9522809Smckusick expptr p; 9622809Smckusick { 9722809Smckusick int k,oldelse; 9822809Smckusick 9922809Smckusick if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL) 10022809Smckusick { 10122809Smckusick if(k != TYERROR) 10222809Smckusick err("non-logical expression in IF statement"); 10322809Smckusick frexpr(p); 10422809Smckusick } 10522809Smckusick else { 10622809Smckusick if(ctlstack->ctltype == CTLIF) 10722809Smckusick { 10822809Smckusick if(ctlstack->endlabel == 0) ctlstack->endlabel = newlabel(); 10922809Smckusick oldelse=ctlstack->elselabel; 11022809Smckusick ctlstack->elselabel = newlabel(); 11122809Smckusick if (optimflag) 11222809Smckusick { 11322809Smckusick optbuff (SKGOTO, 0, ctlstack->endlabel, 0); 11422809Smckusick optbuff (SKLABEL, 0, oldelse, 0); 11522809Smckusick optbuff (SKIFN, p, ctlstack->elselabel, 0); 11622809Smckusick } 11722809Smckusick else 11822809Smckusick { 11922809Smckusick putgoto (ctlstack->endlabel); 12022809Smckusick putlabel (oldelse); 12122809Smckusick putif (p, ctlstack->elselabel); 12222809Smckusick } 12322809Smckusick } 12422809Smckusick else execerr("elseif out of place", CNULL); 12522809Smckusick } 12622809Smckusick } 12722809Smckusick 12822809Smckusick 12922809Smckusick 13022809Smckusick 13122809Smckusick 13222809Smckusick exelse() 13322809Smckusick { 13422809Smckusick if(ctlstack->ctltype==CTLIF) 13522809Smckusick { 13622809Smckusick if(ctlstack->endlabel == 0) 13722809Smckusick ctlstack->endlabel = newlabel(); 13822809Smckusick ctlstack->ctltype = CTLELSE; 13922809Smckusick if (optimflag) 14022809Smckusick { 14122809Smckusick optbuff (SKGOTO, 0, ctlstack->endlabel, 0); 14222809Smckusick optbuff (SKLABEL, 0, ctlstack->elselabel, 0); 14322809Smckusick } 14422809Smckusick else 14522809Smckusick { 14622809Smckusick putgoto (ctlstack->endlabel); 14722809Smckusick putlabel (ctlstack->elselabel); 14822809Smckusick } 14922809Smckusick } 15022809Smckusick 15122809Smckusick else execerr("else out of place", CNULL); 15222809Smckusick } 15322809Smckusick 15422809Smckusick 15522809Smckusick exendif() 15622809Smckusick { 15722809Smckusick if (ctlstack->ctltype == CTLIF) 15822809Smckusick { 15922809Smckusick if (optimflag) 16022809Smckusick { 16122809Smckusick optbuff (SKLABEL, 0, ctlstack->elselabel, 0); 16222809Smckusick if (ctlstack->endlabel) 16322809Smckusick optbuff (SKLABEL, 0, ctlstack->endlabel, 0); 16422809Smckusick } 16522809Smckusick else 16622809Smckusick { 16722809Smckusick putlabel (ctlstack->elselabel); 16822809Smckusick if (ctlstack->endlabel) 16922809Smckusick putlabel (ctlstack->endlabel); 17022809Smckusick } 17122809Smckusick popctl (); 17222809Smckusick } 17322809Smckusick else if (ctlstack->ctltype == CTLELSE) 17422809Smckusick { 17522809Smckusick if (optimflag) 17622809Smckusick optbuff (SKLABEL, 0, ctlstack->endlabel, 0); 17722809Smckusick else 17822809Smckusick putlabel (ctlstack->endlabel); 17922809Smckusick popctl (); 18022809Smckusick } 18122809Smckusick else 18222809Smckusick execerr("endif out of place", CNULL); 18322809Smckusick } 18422809Smckusick 18522809Smckusick 18622809Smckusick 18722809Smckusick LOCAL pushctl(code) 18822809Smckusick int code; 18922809Smckusick { 19022809Smckusick register int i; 19122809Smckusick 19222809Smckusick /* fprintf(diagfile,"old blklevel %d \n",blklevel); dmpframe(ctlstack); */ 19322809Smckusick if(++ctlstack >= lastctl) 19422809Smckusick many("loops or if-then-elses", 'c'); 19522809Smckusick ctlstack->ctltype = code; 19622809Smckusick for(i = 0 ; i < 4 ; ++i) 19722809Smckusick ctlstack->ctlabels[i] = 0; 19822809Smckusick ++blklevel; 19922809Smckusick } 20022809Smckusick 20122809Smckusick 20222809Smckusick LOCAL popctl() 20322809Smckusick { 20422809Smckusick if( ctlstack-- < ctls ) 20522809Smckusick fatal("control stack empty"); 20622809Smckusick --blklevel; 20722809Smckusick } 20822809Smckusick 20922809Smckusick 21022809Smckusick 21122809Smckusick LOCAL poplab() 21222809Smckusick { 21322809Smckusick register struct Labelblock *lp; 21422809Smckusick 21522809Smckusick for(lp = labeltab ; lp < highlabtab ; ++lp) 21622809Smckusick if(lp->labdefined) 21722809Smckusick { 21822809Smckusick /* mark all labels in inner blocks unreachable */ 21922809Smckusick if(lp->blklevel > blklevel) 22022809Smckusick lp->labinacc = YES; 22122809Smckusick } 22222809Smckusick else if(lp->blklevel > blklevel) 22322809Smckusick { 22422809Smckusick /* move all labels referred to in inner blocks out a level */ 22522809Smckusick lp->blklevel = blklevel; 22622809Smckusick } 22722809Smckusick } 22822809Smckusick 22922809Smckusick 23022809Smckusick 23122809Smckusick /* BRANCHING CODE 23222809Smckusick */ 23322809Smckusick 23422809Smckusick exgoto(lab) 23522809Smckusick struct Labelblock *lab; 23622809Smckusick { 23722809Smckusick if (optimflag) 23822809Smckusick optbuff (SKGOTO, 0, lab->labelno, 0); 23922809Smckusick else 24022809Smckusick putgoto (lab->labelno); 24122809Smckusick } 24222809Smckusick 24322809Smckusick 24422809Smckusick 24522809Smckusick 24622809Smckusick 24722809Smckusick 24822809Smckusick 24922809Smckusick exequals(lp, rp) 25022809Smckusick register struct Primblock *lp; 25122809Smckusick register expptr rp; 25222809Smckusick { 25322809Smckusick register Namep np; 25422809Smckusick 25522809Smckusick if(lp->tag != TPRIM) 25622809Smckusick { 25722809Smckusick err("assignment to a non-variable"); 25822809Smckusick frexpr(lp); 25922809Smckusick frexpr(rp); 26022809Smckusick } 26122809Smckusick else if(lp->namep->vclass!=CLVAR && lp->argsp) 26222809Smckusick { 26322809Smckusick if(parstate >= INEXEC) 26424476Sdonn err("undimensioned array or statement function out of order"); 26522809Smckusick else 26622809Smckusick mkstfunct(lp, rp); 26722809Smckusick } 26822809Smckusick else 26922809Smckusick { 27022809Smckusick np = (Namep) lp->namep; 27122809Smckusick if (np->vclass == CLPROC && np->vprocclass == PTHISPROC 27222809Smckusick && proctype == TYSUBR) 27322809Smckusick { 27422809Smckusick err("assignment to a subroutine name"); 27522809Smckusick return; 27622809Smckusick } 27722809Smckusick if(parstate < INDATA) 27822809Smckusick enddcl(); 279*25735Sdonn parstate = INEXEC; 28022809Smckusick if (optimflag) 28122809Smckusick optbuff (SKEQ, mkexpr(OPASSIGN, mklhs(lp), fixtype(rp)), 0, 0); 28222809Smckusick else 28322809Smckusick puteq (mklhs(lp), fixtype(rp)); 28422809Smckusick } 28522809Smckusick } 28622809Smckusick 28722809Smckusick 28822809Smckusick 28922809Smckusick mkstfunct(lp, rp) 29022809Smckusick struct Primblock *lp; 29122809Smckusick expptr rp; 29222809Smckusick { 29322809Smckusick register struct Primblock *p; 29422809Smckusick register Namep np; 29522809Smckusick chainp args; 29622809Smckusick 29722809Smckusick if(parstate < INDATA) 29822809Smckusick { 29922809Smckusick enddcl(); 30022809Smckusick parstate = INDATA; 30122809Smckusick } 30222809Smckusick 30322809Smckusick np = lp->namep; 30422809Smckusick if(np->vclass == CLUNKNOWN) 30522809Smckusick np->vclass = CLPROC; 30622809Smckusick else 30722809Smckusick { 30822809Smckusick dclerr("redeclaration of statement function", np); 30922809Smckusick return; 31022809Smckusick } 31122809Smckusick np->vprocclass = PSTFUNCT; 31222809Smckusick np->vstg = STGSTFUNCT; 31322809Smckusick impldcl(np); 31422809Smckusick args = (lp->argsp ? lp->argsp->listp : CHNULL); 31522809Smckusick np->varxptr.vstfdesc = mkchain(args , rp ); 31622809Smckusick 31722809Smckusick for( ; args ; args = args->nextp) 31822809Smckusick if( args->datap->tag!=TPRIM || 31922809Smckusick (p = (struct Primblock *) (args->datap) )->argsp || 32022809Smckusick p->fcharp || p->lcharp ) 32122809Smckusick err("non-variable argument in statement function definition"); 32222809Smckusick else 32322809Smckusick { 32422809Smckusick args->datap = (tagptr) (p->namep); 32522809Smckusick vardcl(p->namep); 32622809Smckusick free(p); 32722809Smckusick } 32822809Smckusick } 32922809Smckusick 33022809Smckusick 33122809Smckusick 33222809Smckusick excall(name, args, nstars, labels) 33322809Smckusick Namep name; 33422809Smckusick struct Listblock *args; 33522809Smckusick int nstars; 33622809Smckusick struct Labelblock *labels[ ]; 33722809Smckusick { 33822809Smckusick register expptr p; 33922809Smckusick 340*25735Sdonn if (name->vdcldone) 341*25735Sdonn if (name->vclass != CLPROC && name->vclass != CLENTRY) 342*25735Sdonn { 343*25735Sdonn dclerr("call to non-subroutine", name); 344*25735Sdonn return; 345*25735Sdonn } 346*25735Sdonn else if (name->vtype != TYSUBR) 347*25735Sdonn { 348*25735Sdonn dclerr("subroutine invocation of function", name); 349*25735Sdonn return; 350*25735Sdonn } 35122809Smckusick settype(name, TYSUBR, ENULL); 35222809Smckusick p = mkfunct( mkprim(name, args, CHNULL) ); 35322809Smckusick p->exprblock.vtype = p->exprblock.leftp->headblock.vtype = TYINT; 35422809Smckusick if (nstars > 0) 35522809Smckusick if (optimflag) 35622809Smckusick optbuff (SKCMGOTO, p, nstars, labels); 35722809Smckusick else 35822809Smckusick putcmgo (p, nstars, labels); 35922809Smckusick else 36022809Smckusick if (optimflag) 36122809Smckusick optbuff (SKCALL, p, 0, 0); 36222809Smckusick else 36322809Smckusick putexpr (p); 36422809Smckusick } 36522809Smckusick 36622809Smckusick 36722809Smckusick 36822809Smckusick exstop(stop, p) 36922809Smckusick int stop; 37022809Smckusick register expptr p; 37122809Smckusick { 37222809Smckusick char *q; 37322809Smckusick int n; 37422809Smckusick expptr mkstrcon(); 37522809Smckusick 37622809Smckusick if(p) 37722809Smckusick { 37822809Smckusick if( ! ISCONST(p) ) 37922809Smckusick { 38022809Smckusick execerr("pause/stop argument must be constant", CNULL); 38122809Smckusick frexpr(p); 38222809Smckusick p = mkstrcon(0, CNULL); 38322809Smckusick } 38422809Smckusick else if( ISINT(p->constblock.vtype) ) 38522809Smckusick { 38622809Smckusick q = convic(p->constblock.const.ci); 38722809Smckusick n = strlen(q); 38822809Smckusick if(n > 0) 38922809Smckusick { 39022809Smckusick p->constblock.const.ccp = copyn(n, q); 39122809Smckusick p->constblock.vtype = TYCHAR; 39222809Smckusick p->constblock.vleng = (expptr) ICON(n); 39322809Smckusick } 39422809Smckusick else 39522809Smckusick p = (expptr) mkstrcon(0, CNULL); 39622809Smckusick } 39722809Smckusick else if(p->constblock.vtype != TYCHAR) 39822809Smckusick { 39922809Smckusick execerr("pause/stop argument must be integer or string", CNULL); 40022809Smckusick p = (expptr) mkstrcon(0, CNULL); 40122809Smckusick } 40222809Smckusick } 40322809Smckusick else p = (expptr) mkstrcon(0, CNULL); 40422809Smckusick 40522809Smckusick if (optimflag) 40622809Smckusick optbuff ((stop ? SKSTOP : SKPAUSE), p, 0, 0); 40722809Smckusick else 40822809Smckusick putexpr (call1(TYSUBR, (stop ? "s_stop" : "s_paus"), p)); 40922809Smckusick } 41022809Smckusick 41122809Smckusick 41222809Smckusick /* UCB DO LOOP CODE */ 41322809Smckusick 41422809Smckusick #define DOINIT par[0] 41522809Smckusick #define DOLIMIT par[1] 41622809Smckusick #define DOINCR par[2] 41722809Smckusick 41822809Smckusick #define CONSTINIT const[0] 41922809Smckusick #define CONSTLIMIT const[1] 42022809Smckusick #define CONSTINCR const[2] 42122809Smckusick 42222809Smckusick #define VARSTEP 0 42322809Smckusick #define POSSTEP 1 42422809Smckusick #define NEGSTEP 2 42522809Smckusick 42622809Smckusick 42722809Smckusick exdo(range, spec) 42822809Smckusick int range; 42922809Smckusick chainp spec; 43022809Smckusick 43122809Smckusick { 43222809Smckusick register expptr p, q; 43322809Smckusick expptr q1; 43422809Smckusick register Namep np; 43522809Smckusick chainp cp; 43622809Smckusick register int i; 43722809Smckusick int dotype, incsign; 43822809Smckusick Addrp dovarp, dostgp; 43922809Smckusick expptr par[3]; 44022809Smckusick expptr const[3]; 44122809Smckusick Slotp doslot; 44222809Smckusick 44322809Smckusick pushctl(CTLDO); 44422809Smckusick dorange = ctlstack->dolabel = range; 44522809Smckusick np = (Namep) (spec->datap); 44622809Smckusick ctlstack->donamep = NULL; 44722809Smckusick if(np->vdovar) 44822809Smckusick { 44922809Smckusick errstr("nested loops with variable %s", varstr(VL,np->varname)); 45022809Smckusick return; 45122809Smckusick } 45222809Smckusick 45322809Smckusick dovarp = mkplace(np); 45422809Smckusick dotype = dovarp->vtype; 45522809Smckusick 45622809Smckusick if( ! ONEOF(dotype, MSKINT|MSKREAL) ) 45722809Smckusick { 45822809Smckusick err("bad type on DO variable"); 45922809Smckusick return; 46022809Smckusick } 46122809Smckusick 46222809Smckusick 46322809Smckusick for(i=0 , cp = spec->nextp ; cp!=NULL && i<3 ; cp = cp->nextp) 46422809Smckusick { 46522809Smckusick p = fixtype((expptr) cpexpr((tagptr) q = cp->datap)); 46622809Smckusick if(!ONEOF(p->headblock.vtype, MSKINT|MSKREAL) ) 46722809Smckusick { 46822809Smckusick err("bad type on DO parameter"); 46922809Smckusick return; 47022809Smckusick } 47122809Smckusick 47222809Smckusick 47322809Smckusick if (ISCONST(q)) 47422809Smckusick const[i] = mkconv(dotype, q); 47522809Smckusick else 47622809Smckusick { 47722809Smckusick frexpr(q); 47822809Smckusick const[i] = NULL; 47922809Smckusick } 48022809Smckusick 48122809Smckusick par[i++] = mkconv(dotype, p); 48222809Smckusick } 48322809Smckusick 48422809Smckusick frchain(&spec); 48522809Smckusick switch(i) 48622809Smckusick { 48722809Smckusick case 0: 48822809Smckusick case 1: 48922809Smckusick err("too few DO parameters"); 49022809Smckusick return; 49122809Smckusick 49222809Smckusick case 2: 49322809Smckusick DOINCR = (expptr) ICON(1); 49422809Smckusick CONSTINCR = ICON(1); 49522809Smckusick 49622809Smckusick case 3: 49722809Smckusick break; 49822809Smckusick 49922809Smckusick default: 50022809Smckusick err("too many DO parameters"); 50122809Smckusick return; 50222809Smckusick } 50322809Smckusick 50422809Smckusick ctlstack->donamep = np; 50522809Smckusick 50622809Smckusick np->vdovar = YES; 50722809Smckusick if( !optimflag && enregister(np) ) 50822809Smckusick { 50922809Smckusick /* stgp points to a storage version, varp to a register version */ 51022809Smckusick dostgp = dovarp; 51122809Smckusick dovarp = mkplace(np); 51222809Smckusick } 51322809Smckusick else 51422809Smckusick dostgp = NULL; 51522809Smckusick 51622809Smckusick for (i = 0; i < 4; i++) 51722809Smckusick ctlstack->ctlabels[i] = newlabel(); 51822809Smckusick 51922809Smckusick if( CONSTLIMIT ) 52022809Smckusick ctlstack->domax = DOLIMIT; 52122809Smckusick else 52222809Smckusick ctlstack->domax = (expptr) mktemp(dotype, PNULL); 52322809Smckusick 52422809Smckusick if( CONSTINCR ) 52522809Smckusick { 52622809Smckusick ctlstack->dostep = DOINCR; 52722809Smckusick if( (incsign = conssgn(CONSTINCR)) == 0) 52822809Smckusick err("zero DO increment"); 52922809Smckusick ctlstack->dostepsign = (incsign > 0 ? POSSTEP : NEGSTEP); 53022809Smckusick } 53122809Smckusick else 53222809Smckusick { 53322809Smckusick ctlstack->dostep = (expptr) mktemp(dotype, PNULL); 53422809Smckusick ctlstack->dostepsign = VARSTEP; 53522809Smckusick } 53622809Smckusick 53722809Smckusick if (optimflag) 53822809Smckusick doslot = optbuff (SKDOHEAD,0,0,ctlstack); 53922809Smckusick 54022809Smckusick if( CONSTLIMIT && CONSTINIT && ctlstack->dostepsign!=VARSTEP) 54122809Smckusick { 54222809Smckusick if (optimflag) 54322809Smckusick optbuff (SKEQ,mkexpr(OPASSIGN,cpexpr(dovarp),cpexpr(DOINIT)), 54422809Smckusick 0,0); 54522809Smckusick else 54622809Smckusick puteq (cpexpr(dovarp), cpexpr(DOINIT)); 54722809Smckusick if( ! onetripflag ) 54822809Smckusick { 54922809Smckusick q = mkexpr(OPMINUS, cpexpr(CONSTLIMIT), cpexpr(CONSTINIT)); 55022809Smckusick if((incsign * conssgn(q)) == -1) 55122809Smckusick { 55222809Smckusick warn("DO range never executed"); 55322809Smckusick if (optimflag) 55422809Smckusick optbuff (SKGOTO,0,ctlstack->endlabel,0); 55522809Smckusick else 55622809Smckusick putgoto (ctlstack->endlabel); 55722809Smckusick } 55822809Smckusick frexpr(q); 55922809Smckusick } 56022809Smckusick } 56122809Smckusick 56222809Smckusick 56322809Smckusick else if (ctlstack->dostepsign != VARSTEP && !onetripflag) 56422809Smckusick { 56522809Smckusick if (CONSTLIMIT) 56622809Smckusick q = (expptr) cpexpr(ctlstack->domax); 56722809Smckusick else 56822809Smckusick q = mkexpr(OPASSIGN, cpexpr(ctlstack->domax), DOLIMIT); 56922809Smckusick q1 = mkexpr(OPASSIGN, cpexpr(dovarp), DOINIT); 57022809Smckusick q = mkexpr( (ctlstack->dostepsign == POSSTEP ? OPGE : OPLE), 57122809Smckusick q, q1); 57222809Smckusick if (optimflag) 57322809Smckusick optbuff (SKIFN,q, ctlstack->endlabel,0); 57422809Smckusick else 57522809Smckusick putif (q, ctlstack->endlabel); 57622809Smckusick } 57722809Smckusick else 57822809Smckusick { 57922809Smckusick if (!CONSTLIMIT) 58022809Smckusick if (optimflag) 58122809Smckusick optbuff (SKEQ, 58222809Smckusick mkexpr(OPASSIGN,cpexpr(ctlstack->domax),DOLIMIT),0,0); 58322809Smckusick else 58422809Smckusick puteq (cpexpr(ctlstack->domax), DOLIMIT); 58522809Smckusick q = DOINIT; 58622809Smckusick if (!onetripflag) 58722809Smckusick q = mkexpr(OPMINUS, q, 58822809Smckusick mkexpr(OPASSIGN, cpexpr(ctlstack->dostep), 58922809Smckusick DOINCR) ); 59022809Smckusick if (optimflag) 59122809Smckusick optbuff (SKEQ,mkexpr(OPASSIGN,cpexpr(dovarp), q),0,0); 59222809Smckusick else 59322809Smckusick puteq (cpexpr(dovarp), q); 59422809Smckusick if (onetripflag && ctlstack->dostepsign == VARSTEP) 59522809Smckusick if (optimflag) 59622809Smckusick optbuff (SKEQ, 59722809Smckusick mkexpr(OPASSIGN,cpexpr(ctlstack->dostep),DOINCR),0,0); 59822809Smckusick else 59922809Smckusick puteq (cpexpr(ctlstack->dostep), DOINCR); 60022809Smckusick } 60122809Smckusick 60222809Smckusick if (ctlstack->dostepsign == VARSTEP) 60322809Smckusick { 60422809Smckusick expptr incr,test; 60522809Smckusick if (onetripflag) 60622809Smckusick if (optimflag) 60722809Smckusick optbuff (SKGOTO,0,ctlstack->dobodylabel,0); 60822809Smckusick else 60922809Smckusick putgoto (ctlstack->dobodylabel); 61022809Smckusick else 61122809Smckusick if (optimflag) 61222809Smckusick optbuff (SKIFN,mkexpr(OPGE, cpexpr(ctlstack->dostep), ICON(0)), 61322809Smckusick ctlstack->doneglabel,0); 61422809Smckusick else 61522809Smckusick putif (mkexpr(OPGE, cpexpr(ctlstack->dostep), ICON(0)), 61622809Smckusick ctlstack->doneglabel); 61722809Smckusick if (optimflag) 61822809Smckusick optbuff (SKLABEL,0,ctlstack->doposlabel,0); 61922809Smckusick else 62022809Smckusick putlabel (ctlstack->doposlabel); 62122809Smckusick incr = mkexpr(OPPLUSEQ, cpexpr(dovarp), cpexpr(ctlstack->dostep)); 62222809Smckusick test = mkexpr(OPLE, incr, cpexpr(ctlstack->domax)); 62322809Smckusick if (optimflag) 62422809Smckusick optbuff (SKIFN,test, ctlstack->endlabel,0); 62522809Smckusick else 62622809Smckusick putif (test, ctlstack->endlabel); 62722809Smckusick } 62822809Smckusick 62922809Smckusick if (optimflag) 63022809Smckusick optbuff (SKLABEL,0,ctlstack->dobodylabel,0); 63122809Smckusick else 63222809Smckusick putlabel (ctlstack->dobodylabel); 63322809Smckusick if (dostgp) 63422809Smckusick { 63522809Smckusick if (optimflag) 63622809Smckusick optbuff (SKEQ,mkexpr(OPASSIGN,dostgp, dovarp),0,0); 63722809Smckusick else 63822809Smckusick puteq (dostgp, dovarp); 63922809Smckusick } 64022809Smckusick else 64122809Smckusick frexpr(dovarp); 64222809Smckusick if (optimflag) 64322809Smckusick doslot->nullslot = optbuff (SKNULL,0,0,0); 64422809Smckusick 64522809Smckusick frexpr(CONSTINIT); 64622809Smckusick frexpr(CONSTLIMIT); 64722809Smckusick frexpr(CONSTINCR); 64822809Smckusick } 64922809Smckusick 65022809Smckusick 65122809Smckusick enddo(here) 65222809Smckusick int here; 65322809Smckusick 65422809Smckusick { 65522809Smckusick register struct Ctlframe *q; 65622809Smckusick Namep np; 65722809Smckusick Addrp ap, rv; 65822809Smckusick expptr t; 65922809Smckusick register int i; 66022809Smckusick Slotp doslot; 66122809Smckusick 66222809Smckusick while (here == dorange) 66322809Smckusick { 66422809Smckusick while (ctlstack->ctltype == CTLIF || ctlstack->ctltype == CTLELSE) 66522809Smckusick { 66622809Smckusick execerr("missing endif", CNULL); 66722809Smckusick exendif(); 66822809Smckusick } 66922809Smckusick 67022809Smckusick if (np = ctlstack->donamep) 67122809Smckusick { 67222809Smckusick rv = mkplace (np); 67322809Smckusick 67422809Smckusick t = mkexpr(OPPLUSEQ, cpexpr(rv), cpexpr(ctlstack->dostep) ); 67522809Smckusick 67622809Smckusick if (optimflag) 67722809Smckusick doslot = optbuff (SKENDDO,0,0,ctlstack); 67822809Smckusick 67922809Smckusick if (ctlstack->dostepsign == VARSTEP) 68022809Smckusick if (optimflag) 68122809Smckusick { 68222809Smckusick optbuff (SKIFN, 68322809Smckusick mkexpr(OPLE, cpexpr(ctlstack->dostep), ICON(0)), 68422809Smckusick ctlstack->doposlabel,0); 68522809Smckusick optbuff (SKLABEL,0,ctlstack->doneglabel,0); 68622809Smckusick optbuff (SKIFN,mkexpr(OPLT, t, ctlstack->domax), 68722809Smckusick ctlstack->dobodylabel,0); 68822809Smckusick } 68922809Smckusick else 69022809Smckusick { 69122809Smckusick putif (mkexpr(OPLE, cpexpr(ctlstack->dostep), ICON(0)), 69222809Smckusick ctlstack->doposlabel); 69322809Smckusick putlabel (ctlstack->doneglabel); 69422809Smckusick putif (mkexpr(OPLT, t, ctlstack->domax), 69522809Smckusick ctlstack->dobodylabel); 69622809Smckusick } 69722809Smckusick else 69822809Smckusick { 69922809Smckusick int op; 70022809Smckusick op = (ctlstack->dostepsign == POSSTEP ? OPGT : OPLT); 70122809Smckusick if (optimflag) 70222809Smckusick optbuff (SKIFN, mkexpr(op,t,ctlstack->domax), 70322809Smckusick ctlstack->dobodylabel,0); 70422809Smckusick else 70522809Smckusick putif (mkexpr(op, t, ctlstack->domax), 70622809Smckusick ctlstack->dobodylabel); 70722809Smckusick } 70822809Smckusick if (optimflag) 70922809Smckusick optbuff (SKLABEL,0,ctlstack->endlabel,0); 71022809Smckusick else 71122809Smckusick putlabel (ctlstack->endlabel); 71222809Smckusick 71322809Smckusick if (ap = memversion(np)) 71422809Smckusick { 71522809Smckusick if (optimflag) 71622809Smckusick optbuff (SKEQ,mkexpr(OPASSIGN,ap, rv),0,0); 71722809Smckusick else 71822809Smckusick puteq (ap, rv); 71922809Smckusick } 72022809Smckusick else 72122809Smckusick frexpr(rv); 72222809Smckusick for (i = 0; i < 4; i++) 72322809Smckusick ctlstack->ctlabels[i] = 0; 72422809Smckusick if (!optimflag) 72522809Smckusick deregister(ctlstack->donamep); 72622809Smckusick ctlstack->donamep->vdovar = NO; 72722809Smckusick if (optimflag) 72822809Smckusick doslot->nullslot = optbuff (SKNULL,0,0,0); 72922809Smckusick } 73022809Smckusick 73122809Smckusick popctl(); 73222809Smckusick poplab(); 73322809Smckusick 73422809Smckusick dorange = 0; 73522809Smckusick for (q = ctlstack; q >= ctls; --q) 73622809Smckusick if (q->ctltype == CTLDO) 73722809Smckusick { 73822809Smckusick dorange = q->dolabel; 73922809Smckusick break; 74022809Smckusick } 74122809Smckusick } 74222809Smckusick } 74322809Smckusick 74422809Smckusick 74522809Smckusick exassign(vname, labelval) 74622809Smckusick Namep vname; 74722809Smckusick struct Labelblock *labelval; 74822809Smckusick { 74922809Smckusick Addrp p; 75022809Smckusick expptr mkaddcon(); 75122809Smckusick 75222809Smckusick p = mkplace(vname); 75322809Smckusick #if SZADDR > SZSHORT 75422809Smckusick if( p->vtype == TYSHORT ) 75522809Smckusick err("insufficient precision in ASSIGN variable"); 75622809Smckusick else 75722809Smckusick #endif 75822809Smckusick if( ! ONEOF(p->vtype, MSKINT|MSKADDR) ) 75922809Smckusick err("noninteger assign variable"); 76022809Smckusick else 76122809Smckusick { 76222809Smckusick if (optimflag) 76322809Smckusick optbuff (SKASSIGN, p, labelval->labelno, 0); 76422809Smckusick else 76522809Smckusick puteq (p, intrconv(p->vtype, mkaddcon(labelval->labelno))); 76622809Smckusick } 76722809Smckusick } 76822809Smckusick 76922809Smckusick 77022809Smckusick 77122809Smckusick exarif(expr, neglab, zerlab, poslab) 77222809Smckusick expptr expr; 77322809Smckusick struct Labelblock *neglab, *zerlab, *poslab; 77422809Smckusick { 77522809Smckusick register int lm, lz, lp; 77622809Smckusick struct Labelblock *labels[3]; 77722809Smckusick 77822809Smckusick lm = neglab->labelno; 77922809Smckusick lz = zerlab->labelno; 78022809Smckusick lp = poslab->labelno; 78122809Smckusick expr = fixtype(expr); 78222809Smckusick 78322809Smckusick if( ! ONEOF(expr->headblock.vtype, MSKINT|MSKREAL) ) 78422809Smckusick { 78522809Smckusick err("invalid type of arithmetic if expression"); 78622809Smckusick frexpr(expr); 78722809Smckusick } 78822809Smckusick else 78922809Smckusick { 79022809Smckusick if(lm == lz) 79122809Smckusick exar2(OPLE, expr, lm, lp); 79222809Smckusick else if(lm == lp) 79322809Smckusick exar2(OPNE, expr, lm, lz); 79422809Smckusick else if(lz == lp) 79522809Smckusick exar2(OPGE, expr, lz, lm); 79622809Smckusick else 79722809Smckusick if (optimflag) 79822809Smckusick { 79922809Smckusick labels[0] = neglab; 80022809Smckusick labels[1] = zerlab; 80122809Smckusick labels[2] = poslab; 80222809Smckusick optbuff (SKARIF, expr, 0, labels); 80322809Smckusick } 80422809Smckusick else 80522809Smckusick prarif(expr, lm, lz, lp); 80622809Smckusick } 80722809Smckusick } 80822809Smckusick 80922809Smckusick 81022809Smckusick 81122809Smckusick LOCAL exar2 (op, e, l1, l2) 81222809Smckusick int op; 81322809Smckusick expptr e; 81422809Smckusick int l1,l2; 81522809Smckusick { 81622809Smckusick if (optimflag) 81722809Smckusick { 81822809Smckusick optbuff (SKIFN, mkexpr(op, e, ICON(0)), l2, 0); 81922809Smckusick optbuff (SKGOTO, 0, l1, 0); 82022809Smckusick } 82122809Smckusick else 82222809Smckusick { 82322809Smckusick putif (mkexpr(op, e, ICON(0)), l2); 82422809Smckusick putgoto (l1); 82522809Smckusick } 82622809Smckusick } 82722809Smckusick 82822809Smckusick 82922809Smckusick exreturn(p) 83022809Smckusick register expptr p; 83122809Smckusick { 83222809Smckusick if(procclass != CLPROC) 83322809Smckusick warn("RETURN statement in main or block data"); 83422809Smckusick if(p && (proctype!=TYSUBR || procclass!=CLPROC) ) 83522809Smckusick { 83622809Smckusick err("alternate return in nonsubroutine"); 83722809Smckusick p = 0; 83822809Smckusick } 83922809Smckusick 84022809Smckusick if(p) 84122809Smckusick if (optimflag) 84222809Smckusick optbuff (SKRETURN, p, retlabel, 0); 84322809Smckusick else 84422809Smckusick { 84522809Smckusick putforce (TYINT, p); 84622809Smckusick putgoto (retlabel); 84722809Smckusick } 84822809Smckusick else 84922809Smckusick if (optimflag) 85022809Smckusick optbuff (SKRETURN, p, 85122809Smckusick (proctype==TYSUBR ? ret0label : retlabel), 0); 85222809Smckusick else 85322809Smckusick putgoto (proctype==TYSUBR ? ret0label : retlabel); 85422809Smckusick } 85522809Smckusick 85622809Smckusick 85722809Smckusick 85822809Smckusick exasgoto(labvar) 85922809Smckusick struct Hashentry *labvar; 86022809Smckusick { 86122809Smckusick register Addrp p; 86222809Smckusick 86322809Smckusick p = mkplace(labvar); 86422809Smckusick if( ! ISINT(p->vtype) ) 86522809Smckusick err("assigned goto variable must be integer"); 86622809Smckusick else 86722809Smckusick if (optimflag) 86822809Smckusick optbuff (SKASGOTO, p, 0, 0); 86922809Smckusick else 87022809Smckusick putbranch (p); 87122809Smckusick } 872