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

1.1     ! root        1: #include "defs"
        !             2: 
        !             3: LOCAL int exar2(), popctl(), pushctl();
        !             4: 
        !             5: /*   Logical IF codes
        !             6: */
        !             7: 
        !             8: 
        !             9: exif(p)
        !            10: expptr p;
        !            11: {
        !            12:        pushctl(CTLIF);
        !            13:        ctlstack->elselabel = newlabel();
        !            14:        putif(p, ctlstack->elselabel);
        !            15: }
        !            16: 
        !            17: 
        !            18: 
        !            19: exelif(p)
        !            20: expptr p;
        !            21: {
        !            22:        if(ctlstack->ctltype == CTLIF)
        !            23:        {
        !            24:                if(ctlstack->endlabel == 0)
        !            25:                        ctlstack->endlabel = newlabel();
        !            26:                putgoto(ctlstack->endlabel);
        !            27:                putlabel(ctlstack->elselabel);
        !            28:                ctlstack->elselabel = newlabel();
        !            29:                putif(p, ctlstack->elselabel);
        !            30:        }
        !            31: 
        !            32:        else    execerr("elseif out of place", CNULL);
        !            33: }
        !            34: 
        !            35: 
        !            36: 
        !            37: 
        !            38: 
        !            39: exelse()
        !            40: {
        !            41:        if(ctlstack->ctltype==CTLIF)
        !            42:        {
        !            43:                if(ctlstack->endlabel == 0)
        !            44:                        ctlstack->endlabel = newlabel();
        !            45:                putgoto( ctlstack->endlabel );
        !            46:                putlabel(ctlstack->elselabel);
        !            47:                ctlstack->ctltype = CTLELSE;
        !            48:        }
        !            49: 
        !            50:        else    execerr("else out of place", CNULL);
        !            51: }
        !            52: 
        !            53: 
        !            54: exendif()
        !            55: {
        !            56:        if(ctlstack->ctltype == CTLIF)
        !            57:        {
        !            58:                putlabel(ctlstack->elselabel);
        !            59:                if(ctlstack->endlabel)
        !            60:                        putlabel(ctlstack->endlabel);
        !            61:                popctl();
        !            62:        }
        !            63:        else if(ctlstack->ctltype == CTLELSE)
        !            64:        {
        !            65:                putlabel(ctlstack->endlabel);
        !            66:                popctl();
        !            67:        }
        !            68: 
        !            69:        else
        !            70:                execerr("endif out of place", CNULL);
        !            71: }
        !            72: 
        !            73: 
        !            74: 
        !            75: LOCAL pushctl(code)
        !            76: int code;
        !            77: {
        !            78:        register int i;
        !            79: 
        !            80:        if(++ctlstack >= lastctl)
        !            81:                many("loops or if-then-elses", 'c', maxctl);
        !            82:        ctlstack->ctltype = code;
        !            83:        for(i = 0 ; i < 4 ; ++i)
        !            84:                ctlstack->ctlabels[i] = 0;
        !            85:        ++blklevel;
        !            86: }
        !            87: 
        !            88: 
        !            89: LOCAL popctl()
        !            90: {
        !            91:        if( ctlstack-- < ctls )
        !            92:                fatal("control stack empty");
        !            93:        --blklevel;
        !            94: }
        !            95: 
        !            96: 
        !            97: 
        !            98: LOCAL poplab()
        !            99: {
        !           100:        register struct Labelblock  *lp;
        !           101: 
        !           102:        for(lp = labeltab ; lp < highlabtab ; ++lp)
        !           103:                if(lp->labdefined)
        !           104:                {
        !           105:                        /* mark all labels in inner blocks unreachable */
        !           106:                        if(lp->blklevel > blklevel)
        !           107:                                lp->labinacc = YES;
        !           108:                }
        !           109:                else if(lp->blklevel > blklevel)
        !           110:                {
        !           111:                        /* move all labels referred to in inner blocks out a level */
        !           112:                        lp->blklevel = blklevel;
        !           113:                }
        !           114: }
        !           115: 
        !           116: 
        !           117: 
        !           118: /*  BRANCHING CODE
        !           119: */
        !           120: 
        !           121: exgoto(lab)
        !           122: struct Labelblock *lab;
        !           123: {
        !           124:        putgoto(lab->labelno);
        !           125: }
        !           126: 
        !           127: 
        !           128: 
        !           129: 
        !           130: 
        !           131: 
        !           132: 
        !           133: exequals(lp, rp)
        !           134: register struct Primblock *lp;
        !           135: register expptr rp;
        !           136: {
        !           137:        if(lp->tag != TPRIM)
        !           138:        {
        !           139:                err("assignment to a non-variable");
        !           140:                frexpr(lp);
        !           141:                frexpr(rp);
        !           142:        }
        !           143:        else if(lp->namep->vclass!=CLVAR && lp->argsp)
        !           144:        {
        !           145:                if(parstate >= INEXEC)
        !           146:                        err("statement function amid executables");
        !           147:                else
        !           148:                        mkstfunct(lp, rp);
        !           149:        }
        !           150:        else
        !           151:        {
        !           152:                if(parstate < INDATA)
        !           153:                        enddcl();
        !           154:                puteq(mklhs(lp), fixtype(rp));
        !           155:        }
        !           156: }
        !           157: 
        !           158: 
        !           159: long laststfcn = -1, thisstno;
        !           160: 
        !           161: mkstfunct(lp, rp)
        !           162: struct Primblock *lp;
        !           163: expptr rp;
        !           164: {
        !           165:        register struct Primblock *p;
        !           166:        register Namep np;
        !           167:        chainp args;
        !           168: 
        !           169:        laststfcn = thisstno;
        !           170:        np = lp->namep;
        !           171:        if(np->vclass == CLUNKNOWN)
        !           172:                np->vclass = CLPROC;
        !           173:        else
        !           174:        {
        !           175:                dclerr("redeclaration of statement function", np);
        !           176:                return;
        !           177:        }
        !           178:        np->vprocclass = PSTFUNCT;
        !           179:        np->vstg = STGSTFUNCT;
        !           180:        impldcl(np);
        !           181:        args = (lp->argsp ? lp->argsp->listp : CHNULL);
        !           182:        np->varxptr.vstfdesc = mkchain(args , rp );
        !           183: 
        !           184:        for( ; args ; args = args->nextp)
        !           185:                if( args->datap->tag!=TPRIM ||
        !           186:                    (p = (struct Primblock *) (args->datap) )->argsp ||
        !           187:                    p->fcharp || p->lcharp )
        !           188:                        err("non-variable argument in statement function definition");
        !           189:                else
        !           190:                {
        !           191:                        args->datap = (tagptr) (p->namep);
        !           192:                        vardcl(p->namep);
        !           193:                        free(p);
        !           194:                }
        !           195: }
        !           196: 
        !           197: 
        !           198: 
        !           199: excall(name, args, nstars, labels)
        !           200: Namep name;
        !           201: struct Listblock *args;
        !           202: int nstars;
        !           203: struct Labelblock *labels[ ];
        !           204: {
        !           205:        register expptr p;
        !           206: 
        !           207:        settype(name, TYSUBR, ENULL);
        !           208:        p = mkfunct( mkprim(name, args, CHNULL) );
        !           209:        p->exprblock.vtype = p->exprblock.leftp->headblock.vtype = TYINT;
        !           210:        if(nstars > 0)
        !           211:                putcmgo(p, nstars, labels);
        !           212:        else putexpr(p);
        !           213: }
        !           214: 
        !           215: 
        !           216: 
        !           217: exstop(stop, p)
        !           218: int stop;
        !           219: register expptr p;
        !           220: {
        !           221:        char *q;
        !           222:        int n;
        !           223:        expptr mkstrcon();
        !           224: 
        !           225:        if(p)
        !           226:        {
        !           227:                if( ! ISCONST(p) )
        !           228:                {
        !           229:                        execerr("pause/stop argument must be constant", CNULL);
        !           230:                        frexpr(p);
        !           231:                        p = mkstrcon(0, CNULL);
        !           232:                }
        !           233:                else if( ISINT(p->constblock.vtype) )
        !           234:                {
        !           235:                        q = convic(p->constblock.Const.ci);
        !           236:                        n = strlen(q);
        !           237:                        if(n > 0)
        !           238:                        {
        !           239:                                p->constblock.Const.ccp = copyn(n, q);
        !           240:                                p->constblock.vtype = TYCHAR;
        !           241:                                p->constblock.vleng = (expptr) ICON(n);
        !           242:                        }
        !           243:                        else
        !           244:                                p = (expptr) mkstrcon(0, CNULL);
        !           245:                }
        !           246:                else if(p->constblock.vtype != TYCHAR)
        !           247:                {
        !           248:                        execerr("pause/stop argument must be integer or string", CNULL);
        !           249:                        p = (expptr) mkstrcon(0, CNULL);
        !           250:                }
        !           251:        }
        !           252:        else    p = (expptr) mkstrcon(0, CNULL);
        !           253: 
        !           254:        putexpr( call1(TYSUBR, (stop ? "s_stop" : "s_paus"), p) );
        !           255: }
        !           256: 
        !           257: /* DO LOOP CODE */
        !           258: 
        !           259: #define DOINIT par[0]
        !           260: #define DOLIMIT        par[1]
        !           261: #define DOINCR par[2]
        !           262: 
        !           263: #define VARSTEP        0
        !           264: #define POSSTEP        1
        !           265: #define NEGSTEP        2
        !           266: 
        !           267: 
        !           268: exdo(range, spec)
        !           269: int range;
        !           270: chainp spec;
        !           271: {
        !           272:        register expptr p, q;
        !           273:        expptr q1;
        !           274:        register Namep np;
        !           275:        chainp cp;
        !           276:        register int i;
        !           277:        int dotype, incsign;
        !           278:        Addrp dovarp, dostgp;
        !           279:        expptr par[3];
        !           280: 
        !           281:        pushctl(CTLDO);
        !           282:        dorange = ctlstack->dolabel = range;
        !           283:        np = (Namep) (spec->datap);
        !           284:        ctlstack->donamep = NULL;
        !           285:        if(np->vdovar)
        !           286:        {
        !           287:                errstr("nested loops with variable %s", varstr(VL,np->varname));
        !           288:                ctlstack->donamep = NULL;
        !           289:                return;
        !           290:        }
        !           291: 
        !           292:        dovarp = mkplace(np);
        !           293:        if( ! ONEOF(dovarp->vtype, MSKINT|MSKREAL) )
        !           294:        {
        !           295:                err("bad type on do variable");
        !           296:                return;
        !           297:        }
        !           298:        ctlstack->donamep = np;
        !           299: 
        !           300:        np->vdovar = YES;
        !           301:        if( enregister(np) )
        !           302:        {
        !           303:                /* stgp points to a storage version, varp to a register version */
        !           304:                dostgp = dovarp;
        !           305:                dovarp = mkplace(np);
        !           306:        }
        !           307:        else
        !           308:                dostgp = NULL;
        !           309:        dotype = dovarp->vtype;
        !           310: 
        !           311:        for(i=0 , cp = spec->nextp ; cp!=NULL && i<3 ; cp = cp->nextp)
        !           312:        {
        !           313:                p = par[i++] = fixtype(cp->datap);
        !           314:                if( ! ONEOF(p->headblock.vtype, MSKINT|MSKREAL) )
        !           315:                {
        !           316:                        err("bad type on DO parameter");
        !           317:                        return;
        !           318:                }
        !           319:        }
        !           320: 
        !           321:        frchain(&spec);
        !           322:        switch(i)
        !           323:        {
        !           324:        case 0:
        !           325:        case 1:
        !           326:                err("too few DO parameters");
        !           327:                return;
        !           328: 
        !           329:        default:
        !           330:                err("too many DO parameters");
        !           331:                return;
        !           332: 
        !           333:        case 2:
        !           334:                DOINCR = (expptr) ICON(1);
        !           335: 
        !           336:        case 3:
        !           337:                break;
        !           338:        }
        !           339: 
        !           340:        ctlstack->endlabel = newlabel();
        !           341:        ctlstack->dobodylabel = newlabel();
        !           342: 
        !           343:        if( ISCONST(DOLIMIT) )
        !           344:                ctlstack->domax = mkconv(dotype, DOLIMIT);
        !           345:        else
        !           346:                ctlstack->domax = (expptr) mktemp(dotype, PNULL);
        !           347: 
        !           348:        if( ISCONST(DOINCR) )
        !           349:        {
        !           350:                ctlstack->dostep = mkconv(dotype, DOINCR);
        !           351:                if( (incsign = conssgn(ctlstack->dostep)) == 0)
        !           352:                        err("zero DO increment");
        !           353:                ctlstack->dostepsign = (incsign > 0 ? POSSTEP : NEGSTEP);
        !           354:        }
        !           355:        else
        !           356:        {
        !           357:                ctlstack->dostep = (expptr) mktemp(dotype, PNULL);
        !           358:                ctlstack->dostepsign = VARSTEP;
        !           359:                ctlstack->doposlabel = newlabel();
        !           360:                ctlstack->doneglabel = newlabel();
        !           361:        }
        !           362: 
        !           363:        if( ISCONST(ctlstack->domax) && ISCONST(DOINIT) && ctlstack->dostepsign!=VARSTEP)
        !           364:        {
        !           365:                puteq(cpexpr(dovarp), cpexpr(DOINIT));
        !           366:                if( onetripflag )
        !           367:                        frexpr(DOINIT);
        !           368:                else
        !           369:                {
        !           370:                        q = mkexpr(OPMINUS, cpexpr(DOINIT),
        !           371:                                cpexpr(ctlstack->domax));
        !           372:                        if(incsign == (i = conssgn(q)) || !i && bugwarn & 2)
        !           373:                        {
        !           374:                                warn("DO range never executed");
        !           375:                                putgoto(ctlstack->endlabel);
        !           376:                        }
        !           377:                        else if (!i && bugwarn)
        !           378:                                warnb("old f77 never executed the DO range");
        !           379:                        frexpr(q);
        !           380:                }
        !           381:        }
        !           382:        else if(ctlstack->dostepsign!=VARSTEP && !onetripflag)
        !           383:        {
        !           384:                if( ISCONST(ctlstack->domax) )
        !           385:                        q = (expptr) cpexpr(ctlstack->domax);
        !           386:                else
        !           387:                        q = mkexpr(OPASSIGN, cpexpr(ctlstack->domax), DOLIMIT);
        !           388: 
        !           389:                q1 = mkexpr(OPASSIGN, cpexpr(dovarp), DOINIT);
        !           390:                q = mkexpr( (ctlstack->dostepsign==POSSTEP ? OPLE : OPGE), q1, q);
        !           391:                putif(q, ctlstack->endlabel);
        !           392:        }
        !           393:        else
        !           394:        {
        !           395:                if(! ISCONST(ctlstack->domax) )
        !           396:                        puteq( cpexpr(ctlstack->domax), DOLIMIT);
        !           397:                q = DOINIT;
        !           398:                if( ! onetripflag )
        !           399:                        q = mkexpr(OPMINUS, q,
        !           400:                            mkexpr(OPASSIGN, cpexpr(ctlstack->dostep), DOINCR) );
        !           401:                puteq( cpexpr(dovarp), q);
        !           402:                if(onetripflag && ctlstack->dostepsign==VARSTEP)
        !           403:                        puteq( cpexpr(ctlstack->dostep), DOINCR);
        !           404:        }
        !           405: 
        !           406:        if(ctlstack->dostepsign == VARSTEP)
        !           407:        {
        !           408:                if(onetripflag)
        !           409:                        putgoto(ctlstack->dobodylabel);
        !           410:                else
        !           411:                        putif( mkexpr(OPGE, cpexpr(ctlstack->dostep), ICON(0)),
        !           412:                            ctlstack->doneglabel );
        !           413:                putlabel(ctlstack->doposlabel);
        !           414:                putif( mkexpr(OPLE,
        !           415:                    mkexpr(OPPLUSEQ, cpexpr(dovarp), cpexpr(ctlstack->dostep)),
        !           416:                    cpexpr(ctlstack->domax) ),
        !           417:                    ctlstack->endlabel);
        !           418:        }
        !           419:        putlabel(ctlstack->dobodylabel);
        !           420:        if(dostgp)
        !           421:                puteq(dostgp, cpexpr(dovarp));
        !           422:        frexpr(dovarp);
        !           423: }
        !           424: 
        !           425: 
        !           426: 
        !           427: enddo(here)
        !           428: int here;
        !           429: {
        !           430:        register struct Ctlframe *q;
        !           431:        register expptr t;
        !           432:        Namep np;
        !           433:        Addrp ap;
        !           434:        register int i;
        !           435: 
        !           436:        while(here == dorange)
        !           437:        {
        !           438:                if(np = ctlstack->donamep)
        !           439:                {
        !           440:                        t = mkexpr(OPPLUSEQ, mkplace(ctlstack->donamep),
        !           441:                            cpexpr(ctlstack->dostep) );
        !           442: 
        !           443:                        if(ctlstack->dostepsign == VARSTEP)
        !           444:                        {
        !           445:                                putif( mkexpr(OPLE, cpexpr(ctlstack->dostep), ICON(0)), ctlstack->doposlabel);
        !           446:                                putlabel(ctlstack->doneglabel);
        !           447:                                putif( mkexpr(OPLT, t, ctlstack->domax), ctlstack->dobodylabel);
        !           448:                        }
        !           449:                        else
        !           450:                                putif( mkexpr( (ctlstack->dostepsign==POSSTEP ? OPGT : OPLT),
        !           451:                                    t, ctlstack->domax),
        !           452:                                    ctlstack->dobodylabel);
        !           453:                        putlabel(ctlstack->endlabel);
        !           454:                        if(ap = memversion(np))
        !           455:                                puteq(ap, mkplace(np));
        !           456:                        for(i = 0 ; i < 4 ; ++i)
        !           457:                                ctlstack->ctlabels[i] = 0;
        !           458:                        deregister(ctlstack->donamep);
        !           459:                        ctlstack->donamep->vdovar = NO;
        !           460:                        frexpr(ctlstack->dostep);
        !           461:                }
        !           462: 
        !           463:                popctl();
        !           464:                poplab();
        !           465:                dorange = 0;
        !           466:                for(q = ctlstack ; q>=ctls ; --q)
        !           467:                        if(q->ctltype == CTLDO)
        !           468:                        {
        !           469:                                dorange = q->dolabel;
        !           470:                                break;
        !           471:                        }
        !           472:        }
        !           473: }
        !           474: 
        !           475:  chainp Lblfudgelist;
        !           476: 
        !           477:  expptr
        !           478: labelfudge(t, newno)
        !           479:  register int t;
        !           480: {
        !           481:        register chainp cp;
        !           482:        register Addrp A;
        !           483: 
        !           484:        for(cp = Lblfudgelist; cp; cp = cp->nextp->nextp) 
        !           485:                if ((int)cp->datap == t)
        !           486:                        break;
        !           487:        if (cp) {
        !           488:                A = (Addrp)cp->nextp->datap;
        !           489:                if (newno)
        !           490:                        cp->datap = (tagptr)newno;
        !           491:                }
        !           492:        else {
        !           493:                if (newno)
        !           494:                        return 0;
        !           495:                A = ALLOC(Addrblock);
        !           496:                A->tag = TADDR;
        !           497:                A->vtype = TYLONG;
        !           498:                A->vclass = CLVAR;
        !           499:                A->vstg = STGINIT;
        !           500:                A->memno = ++lastvarno;
        !           501:                A->memoffset = ICON(0);
        !           502:                Lblfudgelist = mkchain((tagptr)t,
        !           503:                        mkchain((tagptr)A, Lblfudgelist));
        !           504:                }
        !           505:        return (expptr)cpexpr((tagptr)A);
        !           506:        }
        !           507: 
        !           508: exassign(vname, labelval)
        !           509: Namep vname;
        !           510: struct Labelblock *labelval;
        !           511: {
        !           512:        Addrp p;
        !           513:        expptr mkaddcon();
        !           514: 
        !           515:        p = mkplace(vname);
        !           516:        if( ! ONEOF(p->vtype, MSKINT|MSKADDR) )
        !           517:                err("noninteger assign variable");
        !           518:        else
        !           519:                puteq(p, labelval->labtype == LABUNKNOWN
        !           520:                        ? labelfudge(labelval->labelno,0)
        !           521:                        : mkaddcon(labelval->labelno) );
        !           522: }
        !           523: 
        !           524: 
        !           525: 
        !           526: exarif(expr, neglab, zerlab, poslab)
        !           527: expptr expr;
        !           528: struct Labelblock *neglab, *zerlab, *poslab;
        !           529: {
        !           530:        register int lm, lz, lp;
        !           531: 
        !           532:        lm = neglab->labelno;
        !           533:        lz = zerlab->labelno;
        !           534:        lp = poslab->labelno;
        !           535:        expr = fixtype(expr);
        !           536: 
        !           537:        if( ! ONEOF(expr->headblock.vtype, MSKINT|MSKREAL) )
        !           538:        {
        !           539:                err("invalid type of arithmetic if expression");
        !           540:                frexpr(expr);
        !           541:        }
        !           542:        else
        !           543:        {
        !           544:                if(lm == lz)
        !           545:                        exar2(OPLE, expr, lm, lp);
        !           546:                else if(lm == lp)
        !           547:                        exar2(OPNE, expr, lm, lz);
        !           548:                else if(lz == lp)
        !           549:                        exar2(OPGE, expr, lz, lm);
        !           550:                else
        !           551:                        prarif(expr, lm, lz, lp);
        !           552:        }
        !           553: }
        !           554: 
        !           555: 
        !           556: 
        !           557: LOCAL exar2(op, e, l1, l2)
        !           558: int op;
        !           559: expptr e;
        !           560: int l1, l2;
        !           561: {
        !           562:        putif( mkexpr(op, e, ICON(0)), l2);
        !           563:        putgoto(l1);
        !           564: }
        !           565: 
        !           566: 
        !           567: exreturn(p)
        !           568: register expptr p;
        !           569: {
        !           570:        if(procclass != CLPROC)
        !           571:                warn("RETURN statement in main or block data");
        !           572:        if(p && (proctype!=TYSUBR || procclass!=CLPROC) )
        !           573:        {
        !           574:                err("alternate return in nonsubroutine");
        !           575:                p = 0;
        !           576:        }
        !           577: 
        !           578:        if(p)
        !           579:        {
        !           580:                putforce(TYINT, p);
        !           581:                putgoto(retlabel);
        !           582:        }
        !           583:        else
        !           584:                putgoto(proctype==TYSUBR ? ret0label : retlabel);
        !           585: }
        !           586: 
        !           587: 
        !           588: 
        !           589: exasgoto(labvar)
        !           590: struct Hashentry *labvar;
        !           591: {
        !           592:        register Addrp p;
        !           593: 
        !           594:        p = mkplace(labvar);
        !           595:        if( ! ISINT(p->vtype) )
        !           596:                err("assigned goto variable must be integer");
        !           597:        else
        !           598:                putbranch(p);
        !           599: }

unix.superglobalmegacorp.com

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