Annotation of 3BSD/cmd/f77/exec.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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