Annotation of researchv10no/cmd/f2c/exec.c, revision 1.1

1.1     ! root        1: /****************************************************************
        !             2: Copyright 1990, 1993 by AT&T Bell Laboratories and Bellcore.
        !             3: 
        !             4: Permission to use, copy, modify, and distribute this software
        !             5: and its documentation for any purpose and without fee is hereby
        !             6: granted, provided that the above copyright notice appear in all
        !             7: copies and that both that the copyright notice and this
        !             8: permission notice and warranty disclaimer appear in supporting
        !             9: documentation, and that the names of AT&T Bell Laboratories or
        !            10: Bellcore or any of their entities not be used in advertising or
        !            11: publicity pertaining to distribution of the software without
        !            12: specific, written prior permission.
        !            13: 
        !            14: AT&T and Bellcore disclaim all warranties with regard to this
        !            15: software, including all implied warranties of merchantability
        !            16: and fitness.  In no event shall AT&T or Bellcore be liable for
        !            17: any special, indirect or consequential damages or any damages
        !            18: whatsoever resulting from loss of use, data or profits, whether
        !            19: in an action of contract, negligence or other tortious action,
        !            20: arising out of or in connection with the use or performance of
        !            21: this software.
        !            22: ****************************************************************/
        !            23: 
        !            24: #include "defs.h"
        !            25: #include "p1defs.h"
        !            26: #include "names.h"
        !            27: 
        !            28: LOCAL void exar2(), popctl(), pushctl();
        !            29: 
        !            30: /*   Logical IF codes
        !            31: */
        !            32: 
        !            33: 
        !            34: exif(p)
        !            35: expptr p;
        !            36: {
        !            37:     pushctl(CTLIF);
        !            38:     putif(p, 0);       /* 0 => if, not elseif */
        !            39: }
        !            40: 
        !            41: 
        !            42: 
        !            43: exelif(p)
        !            44: expptr p;
        !            45: {
        !            46:     if (ctlstack->ctltype == CTLIF || ctlstack->ctltype == CTLIFX)
        !            47:        putif(p, 1);    /* 1 ==> elseif */
        !            48:     else
        !            49:        execerr("elseif out of place", CNULL);
        !            50: }
        !            51: 
        !            52: 
        !            53: 
        !            54: 
        !            55: 
        !            56: exelse()
        !            57: {
        !            58:        register struct Ctlframe *c;
        !            59: 
        !            60:        for(c = ctlstack; c->ctltype == CTLIFX; --c);
        !            61:        if(c->ctltype == CTLIF) {
        !            62:                p1_else ();
        !            63:                c->ctltype = CTLELSE;
        !            64:                }
        !            65:        else
        !            66:                execerr("else out of place", CNULL);
        !            67:        }
        !            68: 
        !            69: 
        !            70: exendif()
        !            71: {
        !            72:        while(ctlstack->ctltype == CTLIFX) {
        !            73:                popctl();
        !            74:                p1else_end();
        !            75:                }
        !            76:        if(ctlstack->ctltype == CTLIF) {
        !            77:                popctl();
        !            78:                p1_endif ();
        !            79:                }
        !            80:        else if(ctlstack->ctltype == CTLELSE) {
        !            81:                popctl();
        !            82:                p1else_end ();
        !            83:                }
        !            84:        else
        !            85:                execerr("endif out of place", CNULL);
        !            86:        }
        !            87: 
        !            88: 
        !            89: new_endif()
        !            90: {
        !            91:        if (ctlstack->ctltype == CTLIF || ctlstack->ctltype == CTLIFX)
        !            92:                pushctl(CTLIFX);
        !            93:        else
        !            94:                err("new_endif bug");
        !            95:        }
        !            96: 
        !            97: /* pushctl -- Start a new control construct, initialize the labels (to
        !            98:    zero) */
        !            99: 
        !           100:  LOCAL void
        !           101: pushctl(code)
        !           102:  int code;
        !           103: {
        !           104:        register int i;
        !           105: 
        !           106:        if(++ctlstack >= lastctl)
        !           107:                many("loops or if-then-elses", 'c', maxctl);
        !           108:        ctlstack->ctltype = code;
        !           109:        for(i = 0 ; i < 4 ; ++i)
        !           110:                ctlstack->ctlabels[i] = 0;
        !           111:        ctlstack->dowhile = 0;
        !           112:        ++blklevel;
        !           113: }
        !           114: 
        !           115: 
        !           116:  LOCAL void
        !           117: popctl()
        !           118: {
        !           119:        if( ctlstack-- < ctls )
        !           120:                Fatal("control stack empty");
        !           121:        --blklevel;
        !           122: }
        !           123: 
        !           124: 
        !           125: 
        !           126: /* poplab -- update the flags in   labeltab   */
        !           127: 
        !           128: LOCAL poplab()
        !           129: {
        !           130:        register struct Labelblock  *lp;
        !           131: 
        !           132:        for(lp = labeltab ; lp < highlabtab ; ++lp)
        !           133:                if(lp->labdefined)
        !           134:                {
        !           135:                        /* mark all labels in inner blocks unreachable */
        !           136:                        if(lp->blklevel > blklevel)
        !           137:                                lp->labinacc = YES;
        !           138:                }
        !           139:                else if(lp->blklevel > blklevel)
        !           140:                {
        !           141:                        /* move all labels referred to in inner blocks out a level */
        !           142:                        lp->blklevel = blklevel;
        !           143:                }
        !           144: }
        !           145: 
        !           146: 
        !           147: /*  BRANCHING CODE
        !           148: */
        !           149: 
        !           150: exgoto(lab)
        !           151: struct Labelblock *lab;
        !           152: {
        !           153:        lab->labused = 1;
        !           154:        p1_goto (lab -> stateno);
        !           155: }
        !           156: 
        !           157: 
        !           158: 
        !           159: 
        !           160: 
        !           161: 
        !           162: 
        !           163: exequals(lp, rp)
        !           164: register struct Primblock *lp;
        !           165: register expptr rp;
        !           166: {
        !           167:        if(lp->tag != TPRIM)
        !           168:        {
        !           169:                err("assignment to a non-variable");
        !           170:                frexpr((expptr)lp);
        !           171:                frexpr(rp);
        !           172:        }
        !           173:        else if(lp->namep->vclass!=CLVAR && lp->argsp)
        !           174:        {
        !           175:                if(parstate >= INEXEC)
        !           176:                        err("statement function amid executables");
        !           177:                mkstfunct(lp, rp);
        !           178:        }
        !           179:        else
        !           180:        {
        !           181:                expptr new_lp, new_rp;
        !           182: 
        !           183:                if(parstate < INDATA)
        !           184:                        enddcl();
        !           185:                new_lp = mklhs (lp, keepsubs);
        !           186:                new_rp = fixtype (rp);
        !           187:                puteq(new_lp, new_rp);
        !           188:        }
        !           189: }
        !           190: 
        !           191: 
        !           192: 
        !           193: /* Make Statement Function */
        !           194: 
        !           195: long laststfcn = -1, thisstno;
        !           196: int doing_stmtfcn;
        !           197: 
        !           198: mkstfunct(lp, rp)
        !           199: struct Primblock *lp;
        !           200: expptr rp;
        !           201: {
        !           202:        register struct Primblock *p;
        !           203:        register Namep np;
        !           204:        chainp args;
        !           205: 
        !           206:        laststfcn = thisstno;
        !           207:        np = lp->namep;
        !           208:        if(np->vclass == CLUNKNOWN)
        !           209:                np->vclass = CLPROC;
        !           210:        else
        !           211:        {
        !           212:                dclerr("redeclaration of statement function", np);
        !           213:                return;
        !           214:        }
        !           215:        np->vprocclass = PSTFUNCT;
        !           216:        np->vstg = STGSTFUNCT;
        !           217: 
        !           218: /* Set the type of the function */
        !           219: 
        !           220:        impldcl(np);
        !           221:        if (np->vtype == TYCHAR && !np->vleng)
        !           222:                err("character statement function with length (*)");
        !           223:        args = (lp->argsp ? lp->argsp->listp : CHNULL);
        !           224:        np->varxptr.vstfdesc = mkchain((char *)args, (chainp)rp);
        !           225: 
        !           226:        for(doing_stmtfcn = 1 ; args ; args = args->nextp)
        !           227: 
        !           228: /* It is an error for the formal parameters to have arguments or
        !           229:    subscripts */
        !           230: 
        !           231:                if( ((tagptr)(args->datap))->tag!=TPRIM ||
        !           232:                    (p = (struct Primblock *)(args->datap) )->argsp ||
        !           233:                    p->fcharp || p->lcharp )
        !           234:                        err("non-variable argument in statement function definition");
        !           235:                else
        !           236:                {
        !           237: 
        !           238: /* Replace the name on the left-hand side */
        !           239: 
        !           240:                        args->datap = (char *)p->namep;
        !           241:                        vardcl(p -> namep);
        !           242:                        free((char *)p);
        !           243:                }
        !           244:        doing_stmtfcn = 0;
        !           245: }
        !           246: 
        !           247:  static void
        !           248: mixed_type(np)
        !           249:  Namep np;
        !           250: {
        !           251:        char buf[128];
        !           252:        sprintf(buf, "%s function %.90s invoked as subroutine",
        !           253:                ftn_types[np->vtype], np->fvarname);
        !           254:        warn(buf);
        !           255:        }
        !           256: 
        !           257: 
        !           258: excall(name, args, nstars, labels)
        !           259: Namep name;
        !           260: struct Listblock *args;
        !           261: int nstars;
        !           262: struct Labelblock *labels[ ];
        !           263: {
        !           264:        register expptr p;
        !           265: 
        !           266:        if (name->vtype != TYSUBR) {
        !           267:                if (name->vinfproc && !name->vcalled) {
        !           268:                        name->vtype = TYSUBR;
        !           269:                        frexpr(name->vleng);
        !           270:                        name->vleng = 0;
        !           271:                        }
        !           272:                else if (!name->vimpltype && name->vtype != TYUNKNOWN)
        !           273:                        mixed_type(name);
        !           274:                else
        !           275:                        settype(name, TYSUBR, (ftnint)0);
        !           276:                }
        !           277:        p = mkfunct( mkprim(name, args, CHNULL) );
        !           278: 
        !           279: /* Subroutines and their identifiers acquire the type INT */
        !           280: 
        !           281:        p->exprblock.vtype = p->exprblock.leftp->headblock.vtype = TYINT;
        !           282: 
        !           283: /* Handle the alternate return mechanism */
        !           284: 
        !           285:        if(nstars > 0)
        !           286:                putcmgo(putx(fixtype(p)), nstars, labels);
        !           287:        else
        !           288:                putexpr(p);
        !           289: }
        !           290: 
        !           291: 
        !           292: 
        !           293: exstop(stop, p)
        !           294: int stop;
        !           295: register expptr p;
        !           296: {
        !           297:        char *str;
        !           298:        int n;
        !           299:        expptr mkstrcon();
        !           300: 
        !           301:        if(p)
        !           302:        {
        !           303:                if( ! ISCONST(p) )
        !           304:                {
        !           305:                        execerr("pause/stop argument must be constant", CNULL);
        !           306:                        frexpr(p);
        !           307:                        p = mkstrcon(0, CNULL);
        !           308:                }
        !           309:                else if( ISINT(p->constblock.vtype) )
        !           310:                {
        !           311:                        str = convic(p->constblock.Const.ci);
        !           312:                        n = strlen(str);
        !           313:                        if(n > 0)
        !           314:                        {
        !           315:                                p->constblock.Const.ccp = copyn(n, str);
        !           316:                                p->constblock.Const.ccp1.blanks = 0;
        !           317:                                p->constblock.vtype = TYCHAR;
        !           318:                                p->constblock.vleng = (expptr) ICON(n);
        !           319:                        }
        !           320:                        else
        !           321:                                p = (expptr) mkstrcon(0, CNULL);
        !           322:                }
        !           323:                else if(p->constblock.vtype != TYCHAR)
        !           324:                {
        !           325:                        execerr("pause/stop argument must be integer or string", CNULL);
        !           326:                        p = (expptr) mkstrcon(0, CNULL);
        !           327:                }
        !           328:        }
        !           329:        else    p = (expptr) mkstrcon(0, CNULL);
        !           330: 
        !           331:     {
        !           332:        expptr subr_call;
        !           333: 
        !           334:        subr_call = call1(TYSUBR, (stop ? "s_stop" : "s_paus"), p);
        !           335:        putexpr( subr_call );
        !           336:     }
        !           337: }
        !           338: 
        !           339: /* DO LOOP CODE */
        !           340: 
        !           341: #define DOINIT par[0]
        !           342: #define DOLIMIT        par[1]
        !           343: #define DOINCR par[2]
        !           344: 
        !           345: 
        !           346: /* Macros for   ctlstack -> dostepsign   */
        !           347: 
        !           348: #define VARSTEP        0
        !           349: #define POSSTEP        1
        !           350: #define NEGSTEP        2
        !           351: 
        !           352: 
        !           353: /* exdo -- generate DO loop code.  In the case of a variable increment,
        !           354:    positive increment tests are placed above the body, negative increment
        !           355:    tests are placed below (see   enddo()   ) */
        !           356: 
        !           357: exdo(range, loopname, spec)
        !           358: int range;                     /* end label */
        !           359: Namep loopname;
        !           360: chainp spec;                   /* input spec must have at least 2 exprs */
        !           361: {
        !           362:        register expptr p;
        !           363:        register Namep np;
        !           364:        chainp cp;              /* loops over the fields in   spec */
        !           365:        register int i;
        !           366:        int dotype;             /* type of the index variable */
        !           367:        int incsign;            /* sign of the increment, if it's constant
        !           368:                                   */
        !           369:        Addrp dovarp;           /* loop index variable */
        !           370:        expptr doinit;          /* constant or register for init param */
        !           371:        expptr par[3];          /* local specification parameters */
        !           372: 
        !           373:        expptr init, test, inc; /* Expressions in the resulting FOR loop */
        !           374: 
        !           375: 
        !           376:        test = ENULL;
        !           377: 
        !           378:        pushctl(CTLDO);
        !           379:        dorange = ctlstack->dolabel = range;
        !           380:        ctlstack->loopname = loopname;
        !           381: 
        !           382: /* Declare the loop index */
        !           383: 
        !           384:        np = (Namep)spec->datap;
        !           385:        ctlstack->donamep = NULL;
        !           386:        if (!np) { /* do while */
        !           387:                ctlstack->dowhile = 1;
        !           388: #if 0
        !           389:                if (loopname) {
        !           390:                        if (loopname->vtype == TYUNKNOWN) {
        !           391:                                loopname->vdcldone = 1;
        !           392:                                loopname->vclass = CLLABEL;
        !           393:                                loopname->vprocclass = PLABEL;
        !           394:                                loopname->vtype = TYLABEL;
        !           395:                                }
        !           396:                        if (loopname->vtype == TYLABEL)
        !           397:                                if (loopname->vdovar)
        !           398:                                        dclerr("already in use as a loop name",
        !           399:                                                loopname);
        !           400:                                else
        !           401:                                        loopname->vdovar = 1;
        !           402:                        else
        !           403:                                dclerr("already declared; cannot be a loop name",
        !           404:                                        loopname);
        !           405:                        }
        !           406: #endif
        !           407:                putwhile((expptr)spec->nextp);
        !           408:                NOEXT("do while");
        !           409:                spec->nextp = 0;
        !           410:                frchain(&spec);
        !           411:                return;
        !           412:                }
        !           413:        if(np->vdovar)
        !           414:        {
        !           415:                errstr("nested loops with variable %s", np->fvarname);
        !           416:                ctlstack->donamep = NULL;
        !           417:                return;
        !           418:        }
        !           419: 
        !           420: /* Create a memory-resident version of the index variable */
        !           421: 
        !           422:        dovarp = mkplace(np);
        !           423:        if( ! ONEOF(dovarp->vtype, MSKINT|MSKREAL) )
        !           424:        {
        !           425:                err("bad type on do variable");
        !           426:                return;
        !           427:        }
        !           428:        ctlstack->donamep = np;
        !           429: 
        !           430:        np->vdovar = YES;
        !           431: 
        !           432: /* Now   dovarp   points to the index to be used within the loop,   dostgp
        !           433:    points to the one which may need to be stored */
        !           434: 
        !           435:        dotype = dovarp->vtype;
        !           436: 
        !           437: /* Count the input specifications and type-check each one independently;
        !           438:    this just eliminates non-numeric values from the specification */
        !           439: 
        !           440:        for(i=0 , cp = spec->nextp ; cp!=NULL && i<3 ; cp = cp->nextp)
        !           441:        {
        !           442:                p = par[i++] = fixtype((tagptr)cp->datap);
        !           443:                if( ! ONEOF(p->headblock.vtype, MSKINT|MSKREAL) )
        !           444:                {
        !           445:                        err("bad type on DO parameter");
        !           446:                        return;
        !           447:                }
        !           448:        }
        !           449: 
        !           450:        frchain(&spec);
        !           451:        switch(i)
        !           452:        {
        !           453:        case 0:
        !           454:        case 1:
        !           455:                err("too few DO parameters");
        !           456:                return;
        !           457: 
        !           458:        default:
        !           459:                err("too many DO parameters");
        !           460:                return;
        !           461: 
        !           462:        case 2:
        !           463:                DOINCR = (expptr) ICON(1);
        !           464: 
        !           465:        case 3:
        !           466:                break;
        !           467:        }
        !           468: 
        !           469: 
        !           470: /* Now all of the local specification fields are set, but their types are
        !           471:    not yet consistent */
        !           472: 
        !           473: /* Declare the loop initialization value, casting it properly and declaring a
        !           474:    register if need be */
        !           475: 
        !           476:        if (ISCONST (DOINIT) || !onetripflag)
        !           477: /* putx added 6-29-89 (mwm), not sure if fixtype is required, but I doubt it
        !           478:    since mkconv is called just before */
        !           479:                doinit = putx (mkconv (dotype, DOINIT));
        !           480:        else {
        !           481:            doinit = (expptr) mktmp(dotype, ENULL);
        !           482:            puteq (cpexpr (doinit), DOINIT);
        !           483:        } /* else */
        !           484: 
        !           485: /* Declare the loop ending value, casting it to the type of the index
        !           486:    variable */
        !           487: 
        !           488:        if( ISCONST(DOLIMIT) )
        !           489:                ctlstack->domax = mkconv(dotype, DOLIMIT);
        !           490:        else {
        !           491:                ctlstack->domax = (expptr) mktmp0(dotype, ENULL);
        !           492:                puteq (cpexpr (ctlstack -> domax), DOLIMIT);
        !           493:        } /* else */
        !           494: 
        !           495: /* Declare the loop increment value, casting it to the type of the index
        !           496:    variable */
        !           497: 
        !           498:        if( ISCONST(DOINCR) )
        !           499:        {
        !           500:                ctlstack->dostep = mkconv(dotype, DOINCR);
        !           501:                if( (incsign = conssgn(ctlstack->dostep)) == 0)
        !           502:                        err("zero DO increment");
        !           503:                ctlstack->dostepsign = (incsign > 0 ? POSSTEP : NEGSTEP);
        !           504:        }
        !           505:        else
        !           506:        {
        !           507:                ctlstack->dostep = (expptr) mktmp0(dotype, ENULL);
        !           508:                ctlstack->dostepsign = VARSTEP;
        !           509:                puteq (cpexpr (ctlstack -> dostep), DOINCR);
        !           510:        }
        !           511: 
        !           512: /* All data is now properly typed and in the   ctlstack,   except for the
        !           513:    initial value.  Assignments of temps have been generated already */
        !           514: 
        !           515:        switch (ctlstack -> dostepsign) {
        !           516:            case VARSTEP:
        !           517:                test = mkexpr (OPQUEST, mkexpr (OPLT,
        !           518:                        cpexpr (ctlstack -> dostep), ICON(0)),
        !           519:                        mkexpr (OPCOLON,
        !           520:                            mkexpr (OPGE, cpexpr((expptr)dovarp),
        !           521:                                    cpexpr (ctlstack -> domax)),
        !           522:                            mkexpr (OPLE, cpexpr((expptr)dovarp),
        !           523:                                    cpexpr (ctlstack -> domax))));
        !           524:                break;
        !           525:            case POSSTEP:
        !           526:                test = mkexpr (OPLE, cpexpr((expptr)dovarp),
        !           527:                        cpexpr (ctlstack -> domax));
        !           528:                break;
        !           529:            case NEGSTEP:
        !           530:                test = mkexpr (OPGE, cpexpr((expptr)dovarp),
        !           531:                        cpexpr (ctlstack -> domax));
        !           532:                break;
        !           533:            default:
        !           534:                erri ("exdo:  bad dostepsign '%d'", ctlstack -> dostepsign);
        !           535:                break;
        !           536:        } /* switch (ctlstack -> dostepsign) */
        !           537: 
        !           538:        if (onetripflag)
        !           539:            test = mkexpr (OPOR, test,
        !           540:                    mkexpr (OPEQ, cpexpr((expptr)dovarp), cpexpr (doinit)));
        !           541:        init = mkexpr (OPASSIGN, cpexpr((expptr)dovarp), doinit);
        !           542:        inc = mkexpr (OPPLUSEQ, (expptr)dovarp, cpexpr (ctlstack -> dostep));
        !           543: 
        !           544:        if (!onetripflag && ISCONST (ctlstack -> domax) && ISCONST (doinit)
        !           545:                && ctlstack -> dostepsign != VARSTEP) {
        !           546:            expptr tester;
        !           547: 
        !           548:            tester = mkexpr (OPMINUS, cpexpr (doinit),
        !           549:                    cpexpr (ctlstack -> domax));
        !           550:            if (incsign == conssgn (tester))
        !           551:                warn ("DO range never executed");
        !           552:            frexpr (tester);
        !           553:        } /* if !onetripflag && */
        !           554: 
        !           555:        p1_for (init, test, inc);
        !           556: }
        !           557: 
        !           558: exenddo(np)
        !           559:  Namep np;
        !           560: {
        !           561:        Namep np1;
        !           562:        int here;
        !           563:        struct Ctlframe *cf;
        !           564: 
        !           565:        if( ctlstack < ctls )
        !           566:                Fatal("control stack empty");
        !           567:        here = ctlstack->dolabel;
        !           568:        if (ctlstack->ctltype != CTLDO
        !           569:        || here >= 0 && (!thislabel || thislabel->labelno != here)) {
        !           570:                err("misplaced ENDDO");
        !           571:                return;
        !           572:                }
        !           573:        if (np != ctlstack->loopname) {
        !           574:                if (np1 = ctlstack->loopname)
        !           575:                        errstr("expected \"enddo %s\"", np1->fvarname);
        !           576:                else
        !           577:                        err("expected unnamed ENDDO");
        !           578:                for(cf = ctls; cf < ctlstack; cf++)
        !           579:                        if (cf->ctltype == CTLDO && cf->loopname == np) {
        !           580:                                here = cf->dolabel;
        !           581:                                break;
        !           582:                                }
        !           583:                }
        !           584:        enddo(here);
        !           585:        }
        !           586: 
        !           587: 
        !           588: enddo(here)
        !           589: int here;
        !           590: {
        !           591:        register struct Ctlframe *q;
        !           592:        Namep np;                       /* name of the current DO index */
        !           593:        Addrp ap;
        !           594:        register int i;
        !           595:        register expptr e;
        !           596: 
        !           597: /* Many DO's can end at the same statement, so keep looping over all
        !           598:    nested indicies */
        !           599: 
        !           600:        while(here == dorange)
        !           601:        {
        !           602:                if(np = ctlstack->donamep)
        !           603:                        {
        !           604:                        p1for_end ();
        !           605: 
        !           606: /* Now we're done with all of the tests, and the loop has terminated.
        !           607:    Store the index value back in long-term memory */
        !           608: 
        !           609:                        if(ap = memversion(np))
        !           610:                                puteq((expptr)ap, (expptr)mkplace(np));
        !           611:                        for(i = 0 ; i < 4 ; ++i)
        !           612:                                ctlstack->ctlabels[i] = 0;
        !           613:                        deregister(ctlstack->donamep);
        !           614:                        ctlstack->donamep->vdovar = NO;
        !           615:                        e = ctlstack->dostep;
        !           616:                        if (e->tag == TADDR && e->addrblock.istemp)
        !           617:                                frtemp((Addrp)e);
        !           618:                        else
        !           619:                                frexpr(e);
        !           620:                        e = ctlstack->domax;
        !           621:                        if (e->tag == TADDR && e->addrblock.istemp)
        !           622:                                frtemp((Addrp)e);
        !           623:                        else
        !           624:                                frexpr(e);
        !           625:                        }
        !           626:                else if (ctlstack->dowhile)
        !           627:                        p1for_end ();
        !           628: 
        !           629: /* Set   dorange   to the closing label of the next most enclosing DO loop
        !           630:    */
        !           631: 
        !           632:                popctl();
        !           633:                poplab();
        !           634:                dorange = 0;
        !           635:                for(q = ctlstack ; q>=ctls ; --q)
        !           636:                        if(q->ctltype == CTLDO)
        !           637:                        {
        !           638:                                dorange = q->dolabel;
        !           639:                                break;
        !           640:                        }
        !           641:        }
        !           642: }
        !           643: 
        !           644: exassign(vname, labelval)
        !           645:  register Namep vname;
        !           646: struct Labelblock *labelval;
        !           647: {
        !           648:        Addrp p;
        !           649:        expptr mkaddcon();
        !           650:        register Addrp q;
        !           651:        char *fs;
        !           652:        register chainp cp, cpprev;
        !           653:        register ftnint k, stno;
        !           654: 
        !           655:        p = mkplace(vname);
        !           656:        if( ! ONEOF(p->vtype, MSKINT|MSKADDR) ) {
        !           657:                err("noninteger assign variable");
        !           658:                return;
        !           659:                }
        !           660: 
        !           661:        /* If the label hasn't been defined, then we do things twice:
        !           662:         * once for an executable stmt label, once for a format
        !           663:         */
        !           664: 
        !           665:        /* code for executable label... */
        !           666: 
        !           667: /* Now store the assigned value in a list associated with this variable.
        !           668:    This will be used later to generate a switch() statement in the C output */
        !           669: 
        !           670:        fs = labelval->fmtstring;
        !           671:        if (!labelval->labdefined || !fs) {
        !           672: 
        !           673:                if (vname -> vis_assigned == 0) {
        !           674:                        vname -> varxptr.assigned_values = CHNULL;
        !           675:                        vname -> vis_assigned = 1;
        !           676:                        }
        !           677: 
        !           678:                /* don't duplicate labels... */
        !           679: 
        !           680:                stno = labelval->stateno;
        !           681:                cpprev = 0;
        !           682:                for(k = 0, cp = vname->varxptr.assigned_values;
        !           683:                                cp; cpprev = cp, cp = cp->nextp, k++)
        !           684:                        if ((ftnint)cp->datap == stno)
        !           685:                                break;
        !           686:                if (!cp) {
        !           687:                        cp = mkchain((char *)stno, CHNULL);
        !           688:                        if (cpprev)
        !           689:                                cpprev->nextp = cp;
        !           690:                        else
        !           691:                                vname->varxptr.assigned_values = cp;
        !           692:                        labelval->labused = 1;
        !           693:                        }
        !           694:                putout(mkexpr(OPASSIGN, (expptr)p, mkintcon(k)));
        !           695:                }
        !           696: 
        !           697:        /* Code for FORMAT label... */
        !           698: 
        !           699:        if (!labelval->labdefined || fs) {
        !           700:                extern void fmtname();
        !           701: 
        !           702:                labelval->fmtlabused = 1;
        !           703:                p = ALLOC(Addrblock);
        !           704:                p->tag = TADDR;
        !           705:                p->vtype = TYCHAR;
        !           706:                p->vstg = STGAUTO;
        !           707:                p->memoffset = ICON(0);
        !           708:                fmtname(vname, p);
        !           709:                q = ALLOC(Addrblock);
        !           710:                q->tag = TADDR;
        !           711:                q->vtype = TYCHAR;
        !           712:                q->vstg = STGAUTO;
        !           713:                q->ntempelt = 1;
        !           714:                q->memoffset = ICON(0);
        !           715:                q->uname_tag = UNAM_IDENT;
        !           716:                sprintf(q->user.ident, "fmt_%ld", labelval->stateno);
        !           717:                putout(mkexpr(OPASSIGN, (expptr)p, (expptr)q));
        !           718:                }
        !           719: 
        !           720: } /* exassign */
        !           721: 
        !           722: 
        !           723: 
        !           724: exarif(expr, neglab, zerlab, poslab)
        !           725: expptr expr;
        !           726: struct Labelblock *neglab, *zerlab, *poslab;
        !           727: {
        !           728:     register int lm, lz, lp;
        !           729: 
        !           730:     lm = neglab->stateno;
        !           731:     lz = zerlab->stateno;
        !           732:     lp = poslab->stateno;
        !           733:     expr = fixtype(expr);
        !           734: 
        !           735:     if( ! ONEOF(expr->headblock.vtype, MSKINT|MSKREAL) )
        !           736:     {
        !           737:         err("invalid type of arithmetic if expression");
        !           738:         frexpr(expr);
        !           739:     }
        !           740:     else
        !           741:     {
        !           742:         if (lm == lz && lz == lp)
        !           743:             exgoto (neglab);
        !           744:         else if(lm == lz)
        !           745:             exar2(OPLE, expr, neglab, poslab);
        !           746:         else if(lm == lp)
        !           747:             exar2(OPNE, expr, neglab, zerlab);
        !           748:         else if(lz == lp)
        !           749:             exar2(OPGE, expr, zerlab, neglab);
        !           750:         else {
        !           751:             expptr t;
        !           752: 
        !           753:            if (!addressable (expr)) {
        !           754:                t = (expptr) mktmp(expr -> headblock.vtype, ENULL);
        !           755:                expr = mkexpr (OPASSIGN, cpexpr (t), expr);
        !           756:            } else
        !           757:                t = (expptr) cpexpr (expr);
        !           758: 
        !           759:            p1_if(putx(fixtype(mkexpr (OPLT, expr, ICON (0)))));
        !           760:            exgoto(neglab);
        !           761:            p1_elif (mkexpr (OPEQ, t, ICON (0)));
        !           762:            exgoto(zerlab);
        !           763:            p1_else ();
        !           764:            exgoto(poslab);
        !           765:            p1else_end ();
        !           766:         } /* else */
        !           767:     }
        !           768: }
        !           769: 
        !           770: 
        !           771: 
        !           772: /* exar2 -- Do arithmetic IF for only 2 distinct labels;   if !(e.op.0)
        !           773:    goto l2 else goto l1.  If this seems backwards, that's because it is,
        !           774:    in order to make the 1 pass algorithm work. */
        !           775: 
        !           776:  LOCAL void
        !           777: exar2(op, e, l1, l2)
        !           778:  int op;
        !           779:  expptr e;
        !           780:  struct Labelblock *l1, *l2;
        !           781: {
        !           782:        expptr comp;
        !           783: 
        !           784:        comp = mkexpr (op, e, ICON (0));
        !           785:        p1_if(putx(fixtype(comp)));
        !           786:        exgoto(l1);
        !           787:        p1_else ();
        !           788:        exgoto(l2);
        !           789:        p1else_end ();
        !           790: }
        !           791: 
        !           792: 
        !           793: /* exreturn -- return the value in   p  from a SUBROUTINE call -- used to
        !           794:    implement the alternate return mechanism */
        !           795: 
        !           796: exreturn(p)
        !           797: register expptr p;
        !           798: {
        !           799:        if(procclass != CLPROC)
        !           800:                warn("RETURN statement in main or block data");
        !           801:        if(p && (proctype!=TYSUBR || procclass!=CLPROC) )
        !           802:        {
        !           803:                err("alternate return in nonsubroutine");
        !           804:                p = 0;
        !           805:        }
        !           806: 
        !           807:        if (p || proctype == TYSUBR) {
        !           808:                if (p == ENULL) p = ICON (0);
        !           809:                p = mkconv (TYLONG, fixtype (p));
        !           810:                p1_subr_ret (p);
        !           811:        } /* if p || proctype == TYSUBR */
        !           812:        else
        !           813:            p1_subr_ret((expptr)retslot);
        !           814: }
        !           815: 
        !           816: 
        !           817: exasgoto(labvar)
        !           818: Namep labvar;
        !           819: {
        !           820:        register Addrp p;
        !           821:        void p1_asgoto();
        !           822: 
        !           823:        p = mkplace(labvar);
        !           824:        if( ! ISINT(p->vtype) )
        !           825:                err("assigned goto variable must be integer");
        !           826:        else {
        !           827:                p1_asgoto (p);
        !           828:        } /* else */
        !           829: }

unix.superglobalmegacorp.com

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