Annotation of 43BSDTahoe/usr.bin/f77/f77.vax/f77pass1/exec.c, revision 1.1.1.1

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.6 (Berkeley) 1/3/88";
                      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.constant.ci);
                    387:                n = strlen(q);
                    388:                if(n > 0)
                    389:                        {
                    390:                        p->constblock.constant.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  constant[0]
                    419: #define CONSTLIMIT constant[1]
                    420: #define CONSTINCR  constant[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 constant[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:        constant[i] = mkconv(dotype, q);
                    475:       else
                    476:        {
                    477:          frexpr(q);
                    478:          constant[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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.