Annotation of researchv10no/cmd/f77/exec.c, revision 1.1.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.