Annotation of 42BSD/old/f77/proc.c, revision 1.1.1.1

1.1       root        1: #include "defs"
                      2: #include "machdefs"
                      3: 
                      4: #ifdef SDB
                      5: #      include <a.out.h>
                      6: char *stabline();
                      7: #      ifndef N_SO
                      8: #              include <stab.h>
                      9: #      endif
                     10: #endif
                     11: 
                     12: /* start a new procedure */
                     13: 
                     14: newproc()
                     15: {
                     16: if(parstate != OUTSIDE)
                     17:        {
                     18:        execerr("missing end statement", CNULL);
                     19:        endproc();
                     20:        }
                     21: 
                     22: parstate = INSIDE;
                     23: procclass = CLMAIN;    /* default */
                     24: }
                     25: 
                     26: 
                     27: 
                     28: /* end of procedure. generate variables, epilogs, and prologs */
                     29: 
                     30: endproc()
                     31: {
                     32: struct Labelblock *lp;
                     33: 
                     34: if(parstate < INDATA)
                     35:        enddcl();
                     36: if(ctlstack >= ctls)
                     37:        err("DO loop or BLOCK IF not closed");
                     38: for(lp = labeltab ; lp < labtabend ; ++lp)
                     39:        if(lp->stateno!=0 && lp->labdefined==NO)
                     40:                errstr("missing statement number %s", convic(lp->stateno) );
                     41: 
                     42: epicode();
                     43: procode();
                     44: donmlist();
                     45: dobss();
                     46: prdbginfo();
                     47: 
                     48: #if FAMILY == PCC
                     49:        putbracket();
                     50: #endif
                     51: fixlwm();
                     52: procinit();    /* clean up for next procedure */
                     53: }
                     54: 
                     55: 
                     56: 
                     57: /* End of declaration section of procedure.  Allocate storage. */
                     58: 
                     59: enddcl()
                     60: {
                     61: register struct Entrypoint *ep;
                     62: 
                     63: parstate = INEXEC;
                     64: docommon();
                     65: doequiv();
                     66: docomleng();
                     67: for(ep = entries ; ep ; ep = ep->entnextp)
                     68:        doentry(ep);
                     69: }
                     70: 
                     71: /* ROUTINES CALLED WHEN ENCOUNTERING ENTRY POINTS */
                     72: 
                     73: /* Main program or Block data */
                     74: 
                     75: startproc(progname, class)
                     76: struct Extsym * progname;
                     77: int class;
                     78: {
                     79: register struct Entrypoint *p;
                     80: 
                     81: p = ALLOC(Entrypoint);
                     82: if(class == CLMAIN)
                     83:        puthead("MAIN__", CLMAIN);
                     84: else
                     85:        puthead(CNULL, CLBLOCK);
                     86: if(class == CLMAIN)
                     87:        newentry( mkname(5, "MAIN_") );
                     88: p->entryname = progname;
                     89: p->entrylabel = newlabel();
                     90: entries = p;
                     91: 
                     92: procclass = class;
                     93: retlabel = newlabel();
                     94: fprintf(diagfile, "   %s", (class==CLMAIN ? "MAIN" : "BLOCK DATA") );
                     95: if(progname)
                     96:        fprintf(diagfile, " %s", nounder(XL, procname = progname->extname) );
                     97: fprintf(diagfile, ":\n");
                     98: #ifdef SDB
                     99: if(sdbflag && class==CLMAIN)
                    100:        {
                    101:        char buff[10];
                    102:        sprintf(buff, "L%d", p->entrylabel);
                    103:        prstab("MAIN_", N_FUN, lineno, buff);
                    104:        p2pass( stabline("MAIN_", N_FNAME, 0, 0) );
                    105:        if(progname)
                    106:                {
                    107:                prstab(nounder(XL,progname->extname), N_ENTRY, lineno,buff);
                    108: /*             p2pass(stabline(nounder(XL,progname->extname),N_FNAME,0,0));    */
                    109:                }
                    110:        }
                    111: #endif
                    112: }
                    113: 
                    114: /* subroutine or function statement */
                    115: 
                    116: struct Extsym *newentry(v)
                    117: register Namep v;
                    118: {
                    119: register struct Extsym *p;
                    120: 
                    121: p = mkext( varunder(VL, v->varname) );
                    122: 
                    123: if(p==NULL || p->extinit || ! ONEOF(p->extstg, M(STGUNKNOWN)|M(STGEXT)) )
                    124:        {
                    125:        if(p == 0)
                    126:                dclerr("invalid entry name", v);
                    127:        else    dclerr("external name already used", v);
                    128:        return(0);
                    129:        }
                    130: v->vstg = STGAUTO;
                    131: v->vprocclass = PTHISPROC;
                    132: v->vclass = CLPROC;
                    133: p->extstg = STGEXT;
                    134: p->extinit = YES;
                    135: return(p);
                    136: }
                    137: 
                    138: 
                    139: entrypt(class, type, length, entry, args)
                    140: int class, type;
                    141: ftnint length;
                    142: struct Extsym *entry;
                    143: chainp args;
                    144: {
                    145: register Namep q;
                    146: register struct Entrypoint *p, *ep;
                    147: 
                    148: if(class != CLENTRY)
                    149:        puthead( varstr(XL, procname = entry->extname), class);
                    150: if(class == CLENTRY)
                    151:        fprintf(diagfile, "       entry ");
                    152: fprintf(diagfile, "   %s:\n", nounder(XL, entry->extname));
                    153: q = mkname(VL, nounder(XL,entry->extname) );
                    154: 
                    155: if( (type = lengtype(type, (int) length)) != TYCHAR)
                    156:        length = 0;
                    157: if(class == CLPROC)
                    158:        {
                    159:        procclass = CLPROC;
                    160:        proctype = type;
                    161:        procleng = length;
                    162: 
                    163:        retlabel = newlabel();
                    164:        if(type == TYSUBR)
                    165:                ret0label = newlabel();
                    166:        }
                    167: 
                    168: p = ALLOC(Entrypoint);
                    169: 
                    170: if(entries)    /* put new block at end of entries list */
                    171:        {
                    172:        for(ep = entries; ep->entnextp; ep = ep->entnextp)
                    173:                ;
                    174:        ep->entnextp = p;
                    175:        }
                    176: else
                    177:        entries = p;
                    178: 
                    179: p->entryname = entry;
                    180: p->arglist = args;
                    181: p->entrylabel = newlabel();
                    182: p->enamep = q;
                    183: 
                    184: #ifdef SDB
                    185: if(sdbflag)
                    186:        {
                    187:        char buff[10];
                    188:        sprintf(buff, "L%d", p->entrylabel);
                    189:        prstab(nounder(XL, entry->extname),
                    190:                (class==CLENTRY ? N_ENTRY : N_FUN),
                    191:                lineno, buff);
                    192:        if(class != CLENTRY)
                    193:        p2pass( stabline( nounder(XL,entry->extname), N_FNAME, 0, 0) );
                    194:        }
                    195: #endif
                    196: 
                    197: if(class == CLENTRY)
                    198:        {
                    199:        class = CLPROC;
                    200:        if(proctype == TYSUBR)
                    201:                type = TYSUBR;
                    202:        }
                    203: 
                    204: q->vclass = class;
                    205: q->vprocclass = PTHISPROC;
                    206: settype(q, type, (int) length);
                    207: /* hold all initial entry points till end of declarations */
                    208: if(parstate >= INDATA)
                    209:        doentry(p);
                    210: }
                    211: 
                    212: /* generate epilogs */
                    213: 
                    214: LOCAL epicode()
                    215: {
                    216: register int i;
                    217: 
                    218: if(procclass==CLPROC)
                    219:        {
                    220:        if(proctype==TYSUBR)
                    221:                {
                    222:                putlabel(ret0label);
                    223:                if(substars)
                    224:                        putforce(TYINT, ICON(0) );
                    225:                putlabel(retlabel);
                    226:                goret(TYSUBR);
                    227:                }
                    228:        else    {
                    229:                putlabel(retlabel);
                    230:                if(multitype)
                    231:                        {
                    232:                        typeaddr = autovar(1, TYADDR, PNULL);
                    233:                        putbranch( cpexpr(typeaddr) );
                    234:                        for(i = 0; i < NTYPES ; ++i)
                    235:                                if(rtvlabel[i] != 0)
                    236:                                        {
                    237:                                        putlabel(rtvlabel[i]);
                    238:                                        retval(i);
                    239:                                        }
                    240:                        }
                    241:                else
                    242:                        retval(proctype);
                    243:                }
                    244:        }
                    245: 
                    246: else if(procclass != CLBLOCK)
                    247:        {
                    248:        putlabel(retlabel);
                    249:        goret(TYSUBR);
                    250:        }
                    251: }
                    252: 
                    253: 
                    254: /* generate code to return value of type  t */
                    255: 
                    256: LOCAL retval(t)
                    257: register int t;
                    258: {
                    259: register Addrp p;
                    260: 
                    261: switch(t)
                    262:        {
                    263:        case TYCHAR:
                    264:        case TYCOMPLEX:
                    265:        case TYDCOMPLEX:
                    266:                break;
                    267: 
                    268:        case TYLOGICAL:
                    269:                t = tylogical;
                    270:        case TYADDR:
                    271:        case TYSHORT:
                    272:        case TYLONG:
                    273:                p = (Addrp) cpexpr(retslot);
                    274:                p->vtype = t;
                    275:                putforce(t, p);
                    276:                break;
                    277: 
                    278:        case TYREAL:
                    279:        case TYDREAL:
                    280:                p = (Addrp) cpexpr(retslot);
                    281:                p->vtype = t;
                    282:                putforce(t, p);
                    283:                break;
                    284: 
                    285:        default:
                    286:                badtype("retval", t);
                    287:        }
                    288: goret(t);
                    289: }
                    290: 
                    291: 
                    292: /* Allocate extra argument array if needed. Generate prologs. */
                    293: 
                    294: LOCAL procode()
                    295: {
                    296: register struct Entrypoint *p;
                    297: Addrp argvec;
                    298: 
                    299: #if TARGET==GCOS
                    300:        argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL);
                    301: #else
                    302:        if(lastargslot>0 && nentry>1)
                    303: #if TARGET == VAX
                    304:                argvec = autovar(1 + lastargslot/SZADDR, TYADDR, PNULL);
                    305: #else
                    306:                argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL);
                    307: #endif
                    308:        else
                    309:                argvec = NULL;
                    310: #endif
                    311: 
                    312: 
                    313: #if TARGET == PDP11
                    314:        /* for the optimizer */
                    315:        if(fudgelabel)
                    316:                putlabel(fudgelabel);
                    317: #endif
                    318: 
                    319: for(p = entries ; p ; p = p->entnextp)
                    320:        prolog(p, argvec);
                    321: 
                    322: #if FAMILY == PCC
                    323:        putrbrack(procno);
                    324: #endif
                    325: 
                    326: prendproc();
                    327: }
                    328: 
                    329: /*
                    330:    manipulate argument lists (allocate argument slot positions)
                    331:  * keep track of return types and labels
                    332:  */
                    333: 
                    334: LOCAL doentry(ep)
                    335: struct Entrypoint *ep;
                    336: {
                    337: register int type;
                    338: register Namep np;
                    339: chainp p;
                    340: register Namep q;
                    341: Addrp mkarg();
                    342: 
                    343: ++nentry;
                    344: if(procclass == CLMAIN)
                    345:        {
                    346:        putlabel(ep->entrylabel);
                    347:        return;
                    348:        }
                    349: else if(procclass == CLBLOCK)
                    350:        return;
                    351: 
                    352: impldcl( np = mkname(VL, nounder(XL, ep->entryname->extname) ) );
                    353: type = np->vtype;
                    354: if(proctype == TYUNKNOWN)
                    355:        if( (proctype = type) == TYCHAR)
                    356:                procleng = (np->vleng ? np->vleng->constblock.const.ci : (ftnint) (-1));
                    357: 
                    358: if(proctype == TYCHAR)
                    359:        {
                    360:        if(type != TYCHAR)
                    361:                err("noncharacter entry of character function");
                    362:        else if( (np->vleng ? np->vleng->constblock.const.ci : (ftnint) (-1)) != procleng)
                    363:                err("mismatched character entry lengths");
                    364:        }
                    365: else if(type == TYCHAR)
                    366:        err("character entry of noncharacter function");
                    367: else if(type != proctype)
                    368:        multitype = YES;
                    369: if(rtvlabel[type] == 0)
                    370:        rtvlabel[type] = newlabel();
                    371: ep->typelabel = rtvlabel[type];
                    372: 
                    373: if(type == TYCHAR)
                    374:        {
                    375:        if(chslot < 0)
                    376:                {
                    377:                chslot = nextarg(TYADDR);
                    378:                chlgslot = nextarg(TYLENG);
                    379:                }
                    380:        np->vstg = STGARG;
                    381:        np->vardesc.varno = chslot;
                    382:        if(procleng < 0)
                    383:                np->vleng = (expptr) mkarg(TYLENG, chlgslot);
                    384:        }
                    385: else if( ISCOMPLEX(type) )
                    386:        {
                    387:        np->vstg = STGARG;
                    388:        if(cxslot < 0)
                    389:                cxslot = nextarg(TYADDR);
                    390:        np->vardesc.varno = cxslot;
                    391:        }
                    392: else if(type != TYSUBR)
                    393:        {
                    394:        if(nentry == 1)
                    395:                retslot = autovar(1, TYDREAL, PNULL);
                    396:        np->vstg = STGAUTO;
                    397:        np->voffset = retslot->memoffset->constblock.const.ci;
                    398:        }
                    399: 
                    400: for(p = ep->arglist ; p ; p = p->nextp)
                    401:        if(! (( q = (Namep) (p->datap) )->vdcldone) )
                    402:                q->vardesc.varno = nextarg(TYADDR);
                    403: 
                    404: for(p = ep->arglist ; p ; p = p->nextp)
                    405:        if(! (( q = (Namep) (p->datap) )->vdcldone) )
                    406:                {
                    407:                impldcl(q);
                    408:                q->vdcldone = YES;
                    409: #ifdef SDB
                    410:                if(sdbflag)
                    411:                        prstab(varstr(VL,q->varname), N_PSYM,
                    412:                                stabtype(q),
                    413:                                convic(q->vardesc.varno + ARGOFFSET) );
                    414: #endif
                    415:                if(q->vtype == TYCHAR)
                    416:                        {
                    417:                        if(q->vleng == NULL)    /* character*(*) */
                    418:                                q->vleng = (expptr)
                    419:                                                mkarg(TYLENG, nextarg(TYLENG) );
                    420:                        else if(nentry == 1)
                    421:                                nextarg(TYLENG);
                    422:                        }
                    423:                else if(q->vclass==CLPROC && nentry==1)
                    424:                        nextarg(TYLENG) ;
                    425:                }
                    426: 
                    427: putlabel(ep->entrylabel);
                    428: }
                    429: 
                    430: 
                    431: 
                    432: LOCAL nextarg(type)
                    433: int type;
                    434: {
                    435: int k;
                    436: k = lastargslot;
                    437: lastargslot += typesize[type];
                    438: return(k);
                    439: }
                    440: 
                    441: /* generate variable references */
                    442: 
                    443: LOCAL dobss()
                    444: {
                    445: register struct Hashentry *p;
                    446: register Namep q;
                    447: register int i;
                    448: int align;
                    449: ftnint leng, iarrl;
                    450: char *memname();
                    451: int qstg, qclass, qtype;
                    452: 
                    453: pruse(asmfile, USEBSS);
                    454: 
                    455: for(p = hashtab ; p<lasthash ; ++p)
                    456:     if(q = p->varp)
                    457:        {
                    458:        qstg = q->vstg;
                    459:        qtype = q->vtype;
                    460:        qclass = q->vclass;
                    461: 
                    462: #ifdef SDB
                    463:                 if(sdbflag && qclass==CLVAR) switch(qstg)
                    464:                         {
                    465:                         case STGAUTO:
                    466:                                 prstab(varstr(VL,q->varname), N_LSYM,
                    467:                                         stabtype(q),
                    468:                                         convic( - q->voffset)) ;
                    469:                                 prstleng(q, iarrlen(q));
                    470:                                 break;
                    471: 
                    472:                         case STGBSS:
                    473:                                 prstab(varstr(VL,q->varname), N_LCSYM,
                    474:                                         stabtype(q),
                    475:                                         memname(qstg,q->vardesc.varno) );
                    476:                                 prstleng(q, iarrlen(q));
                    477:                                 break;
                    478: 
                    479:                         case STGINIT:
                    480:                                 prstab(varstr(VL,q->varname), N_STSYM,
                    481:                                         stabtype(q),
                    482:                                         memname(qstg,q->vardesc.varno) );
                    483:                                 prstleng(q, iarrlen(q));
                    484:                                 break;
                    485:                         }
                    486: #endif
                    487: 
                    488:        if( (qclass==CLUNKNOWN && qstg!=STGARG) ||
                    489:            (qclass==CLVAR && qstg==STGUNKNOWN) )
                    490:                warn1("local variable %s never used", varstr(VL,q->varname) );
                    491:        else if(qclass==CLVAR && qstg==STGBSS)
                    492:                {
                    493:                align = (qtype==TYCHAR ? ALILONG : typealign[qtype]);
                    494:                if(bssleng % align != 0)
                    495:                        {
                    496:                        bssleng = roundup(bssleng, align);
                    497:                        preven(align);
                    498:                        }
                    499:                prlocvar(memname(STGBSS,q->vardesc.varno), iarrl = iarrlen(q) );
                    500:                bssleng += iarrl;
                    501:                }
                    502:        else if(qclass==CLPROC && q->vprocclass==PEXTERNAL && qstg!=STGARG)
                    503:                mkext(varunder(VL, q->varname)) ->extstg = STGEXT;
                    504: 
                    505:        if(qclass==CLVAR && qstg!=STGARG)
                    506:                {
                    507:                if(q->vdim && !ISICON(q->vdim->nelt) )
                    508:                        dclerr("adjustable dimension on non-argument", q);
                    509:                if(qtype==TYCHAR && (q->vleng==NULL || !ISICON(q->vleng)))
                    510:                        dclerr("adjustable leng on nonargument", q);
                    511:                }
                    512:        }
                    513: 
                    514: for(i = 0 ; i < nequiv ; ++i)
                    515:        if(eqvclass[i].eqvinit==NO && (leng = eqvclass[i].eqvleng)!=0 )
                    516:                {
                    517:                bssleng = roundup(bssleng, ALIDOUBLE);
                    518:                preven(ALIDOUBLE);
                    519:                prlocvar( memname(STGEQUIV, i), leng);
                    520:                bssleng += leng;
                    521:                }
                    522: }
                    523: 
                    524: 
                    525: 
                    526: donmlist()
                    527: {
                    528: register struct Hashentry *p;
                    529: register Namep q;
                    530: 
                    531: pruse(asmfile, USEINIT);
                    532: 
                    533: for(p=hashtab; p<lasthash; ++p)
                    534:        if( (q = p->varp) && q->vclass==CLNAMELIST)
                    535:                namelist(q);
                    536: }
                    537: 
                    538: 
                    539: doext()
                    540: {
                    541: struct Extsym *p;
                    542: 
                    543: for(p = extsymtab ; p<nextext ; ++p)
                    544:        prext( varstr(XL, p->extname), p->maxleng, p->extinit);
                    545: }
                    546: 
                    547: 
                    548: 
                    549: 
                    550: ftnint iarrlen(q)
                    551: register Namep q;
                    552: {
                    553: ftnint leng;
                    554: 
                    555: leng = typesize[q->vtype];
                    556: if(leng <= 0)
                    557:        return(-1);
                    558: if(q->vdim)
                    559:        if( ISICON(q->vdim->nelt) )
                    560:                leng *= q->vdim->nelt->constblock.const.ci;
                    561:        else    return(-1);
                    562: if(q->vleng)
                    563:        if( ISICON(q->vleng) )
                    564:                leng *= q->vleng->constblock.const.ci;
                    565:        else    return(-1);
                    566: return(leng);
                    567: }
                    568: 
                    569: /* This routine creates a static block representing the namelist.
                    570:    An equivalent declaration of the structure produced is:
                    571:        struct namelist
                    572:                {
                    573:                char namelistname[16];
                    574:                struct namelistentry
                    575:                        {
                    576:                        char varname[16];
                    577:                        char *varaddr;
                    578:                        int type; # negative means -type= number of chars
                    579:                        struct dimensions *dimp; # null means scalar
                    580:                        } names[];
                    581:                };
                    582: 
                    583:        struct dimensions
                    584:                {
                    585:                int numberofdimensions;
                    586:                int numberofelements
                    587:                int baseoffset;
                    588:                int span[numberofdimensions];
                    589:                };
                    590:    where the namelistentry list terminates with a null varname
                    591:    If dimp is not null, then the corner element of the array is at
                    592:    varaddr.  However,  the element with subscripts (i1,...,in) is at
                    593:    varaddr - dimp->baseoffset + sizeoftype * (i1+span[0]*(i2+span[1]*...)
                    594: */
                    595: 
                    596: namelist(np)
                    597: Namep np;
                    598: {
                    599: register chainp q;
                    600: register Namep v;
                    601: register struct Dimblock *dp;
                    602: char *memname();
                    603: int type, dimno, dimoffset;
                    604: flag bad;
                    605: 
                    606: 
                    607: preven(ALILONG);
                    608: fprintf(asmfile, LABELFMT, memname(STGINIT, np->vardesc.varno));
                    609: putstr(asmfile, varstr(VL, np->varname), 16);
                    610: dimno = ++lastvarno;
                    611: dimoffset = 0;
                    612: bad = NO;
                    613: 
                    614: for(q = np->varxptr.namelist ; q ; q = q->nextp)
                    615:        {
                    616:        vardcl( v = (Namep) (q->datap) );
                    617:        type = v->vtype;
                    618:        if( ONEOF(v->vstg, MSKSTATIC) )
                    619:                {
                    620:                preven(ALILONG);
                    621:                putstr(asmfile, varstr(VL,v->varname), 16);
                    622:                praddr(asmfile, v->vstg, v->vardesc.varno, v->voffset);
                    623:                prconi(asmfile, TYINT,
                    624:                        type==TYCHAR ?
                    625:                            -(v->vleng->constblock.const.ci) : (ftnint) type);
                    626:                if(v->vdim)
                    627:                        {
                    628:                        praddr(asmfile, STGINIT, dimno, (ftnint)dimoffset);
                    629:                        dimoffset += 3 + v->vdim->ndim;
                    630:                        }
                    631:                else
                    632:                        praddr(asmfile, STGNULL,0,(ftnint) 0);
                    633:                }
                    634:        else
                    635:                {
                    636:                dclerr("may not appear in namelist", v);
                    637:                bad = YES;
                    638:                }
                    639:        }
                    640: 
                    641: if(bad)
                    642:        return;
                    643: 
                    644: putstr(asmfile, "", 16);
                    645: 
                    646: if(dimoffset > 0)
                    647:        {
                    648:        fprintf(asmfile, LABELFMT, memname(STGINIT,dimno));
                    649:        for(q = np->varxptr.namelist ; q ; q = q->nextp)
                    650:                if(dp = q->datap->nameblock.vdim)
                    651:                        {
                    652:                        int i;
                    653:                        prconi(asmfile, TYINT, (ftnint) (dp->ndim) );
                    654:                        prconi(asmfile, TYINT,
                    655:                                (ftnint) (dp->nelt->constblock.const.ci) );
                    656:                        prconi(asmfile, TYINT,
                    657:                                (ftnint) (dp->baseoffset->constblock.const.ci));
                    658:                        for(i=0; i<dp->ndim ; ++i)
                    659:                                prconi(asmfile, TYINT,
                    660:                                        dp->dims[i].dimsize->constblock.const.ci);
                    661:                        }
                    662:        }
                    663: 
                    664: }
                    665: 
                    666: LOCAL docommon()
                    667: {
                    668: register struct Extsym *p;
                    669: register chainp q;
                    670: struct Dimblock *t;
                    671: expptr neltp;
                    672: register Namep v;
                    673: ftnint size;
                    674: int type;
                    675: 
                    676: for(p = extsymtab ; p<nextext ; ++p)
                    677:        if(p->extstg==STGCOMMON)
                    678:                {
                    679: #ifdef SDB
                    680:                if(sdbflag)
                    681:                        prstab(CNULL, N_BCOMM, 0, 0);
                    682: #endif
                    683:                for(q = p->extp ; q ; q = q->nextp)
                    684:                        {
                    685:                        v = (Namep) (q->datap);
                    686:                        if(v->vdcldone == NO)
                    687:                                vardcl(v);
                    688:                        type = v->vtype;
                    689:                        if(p->extleng % typealign[type] != 0)
                    690:                                {
                    691:                                dclerr("common alignment", v);
                    692:                                p->extleng = roundup(p->extleng, typealign[type]);
                    693:                                }
                    694:                        v->voffset = p->extleng;
                    695:                        v->vardesc.varno = p - extsymtab;
                    696:                        if(type == TYCHAR)
                    697:                                size = v->vleng->constblock.const.ci;
                    698:                        else    size = typesize[type];
                    699:                        if(t = v->vdim)
                    700:                                if( (neltp = t->nelt) && ISCONST(neltp) )
                    701:                                        size *= neltp->constblock.const.ci;
                    702:                                else
                    703:                                        dclerr("adjustable array in common", v);
                    704:                        p->extleng += size;
                    705: #ifdef SDB
                    706:                        if(sdbflag)
                    707:                                {
                    708:                                prstssym(v);
                    709:                                prstleng(v, size);
                    710:                                }
                    711: #endif
                    712:                        }
                    713: 
                    714:                frchain( &(p->extp) );
                    715: #ifdef SDB
                    716:                if(sdbflag)
                    717:                        prstab(varstr(XL,p->extname), N_ECOMM, 0, 0);
                    718: #endif
                    719:                }
                    720: }
                    721: 
                    722: 
                    723: 
                    724: 
                    725: 
                    726: LOCAL docomleng()
                    727: {
                    728: register struct Extsym *p;
                    729: 
                    730: for(p = extsymtab ; p < nextext ; ++p)
                    731:        if(p->extstg == STGCOMMON)
                    732:                {
                    733:                if(p->maxleng!=0 && p->extleng!=0 && p->maxleng!=p->extleng
                    734:                    && !eqn(XL,"_BLNK__ ",p->extname) )
                    735:                        warn1("incompatible lengths for common block %s",
                    736:                                nounder(XL, p->extname) );
                    737:                if(p->maxleng < p->extleng)
                    738:                        p->maxleng = p->extleng;
                    739:                p->extleng = 0;
                    740:        }
                    741: }
                    742: 
                    743: 
                    744: 
                    745: 
                    746: /* ROUTINES DEALING WITH AUTOMATIC AND TEMPORARY STORAGE */
                    747: 
                    748: frtemp(p)
                    749: Addrp p;
                    750: {
                    751: /* restore clobbered character string lengths */
                    752: if(p->vtype==TYCHAR && p->varleng!=0)
                    753:        {
                    754:        frexpr(p->vleng);
                    755:        p->vleng = ICON(p->varleng);
                    756:        }
                    757: 
                    758: /* put block on chain of temps to be reclaimed */
                    759: holdtemps = mkchain(p, holdtemps);
                    760: }
                    761: 
                    762: 
                    763: 
                    764: 
                    765: /* allocate an automatic variable slot */
                    766: 
                    767: Addrp autovar(nelt, t, lengp)
                    768: register int nelt, t;
                    769: expptr lengp;
                    770: {
                    771: ftnint leng;
                    772: register Addrp q;
                    773: 
                    774: if(t == TYCHAR)
                    775:        if( ISICON(lengp) )
                    776:                leng = lengp->constblock.const.ci;
                    777:        else    {
                    778:                fatal("automatic variable of nonconstant length");
                    779:                }
                    780: else
                    781:        leng = typesize[t];
                    782: autoleng = roundup( autoleng, typealign[t]);
                    783: 
                    784: q = ALLOC(Addrblock);
                    785: q->tag = TADDR;
                    786: q->vtype = t;
                    787: if(t == TYCHAR)
                    788:        {
                    789:        q->vleng = ICON(leng);
                    790:        q->varleng = leng;
                    791:        }
                    792: q->vstg = STGAUTO;
                    793: q->ntempelt = nelt;
                    794: #if TARGET==PDP11 || TARGET==VAX
                    795:        /* stack grows downward */
                    796:        autoleng += nelt*leng;
                    797:        q->memoffset = ICON( - autoleng );
                    798: #else
                    799:        q->memoffset = ICON( autoleng );
                    800:        autoleng += nelt*leng;
                    801: #endif
                    802: 
                    803: return(q);
                    804: }
                    805: 
                    806: 
                    807: Addrp mktmpn(nelt, type, lengp)
                    808: int nelt;
                    809: register int type;
                    810: expptr lengp;
                    811: {
                    812: ftnint leng;
                    813: chainp p, oldp;
                    814: register Addrp q;
                    815: 
                    816: if(type==TYUNKNOWN || type==TYERROR)
                    817:        badtype("mktmpn", type);
                    818: 
                    819: if(type==TYCHAR)
                    820:        if( ISICON(lengp) )
                    821:                leng = lengp->constblock.const.ci;
                    822:        else    {
                    823:                err("adjustable length");
                    824:                return( errnode() );
                    825:                }
                    826: /*
                    827:  * if an temporary of appropriate shape is on the templist,
                    828:  * remove it from the list and return it
                    829:  */
                    830: 
                    831: for(oldp=CHNULL, p=templist  ;  p  ;  oldp=p, p=p->nextp)
                    832:        {
                    833:        q = (Addrp) (p->datap);
                    834:        if(q->vtype==type && q->ntempelt==nelt &&
                    835:            (type!=TYCHAR || q->vleng->constblock.const.ci==leng) )
                    836:                {
                    837:                if(oldp)
                    838:                        oldp->nextp = p->nextp;
                    839:                else
                    840:                        templist = p->nextp;
                    841:                free( (charptr) p);
                    842:                return(q);
                    843:                }
                    844:        }
                    845: q = autovar(nelt, type, lengp);
                    846: q->istemp = YES;
                    847: return(q);
                    848: }
                    849: 
                    850: 
                    851: 
                    852: 
                    853: Addrp mktemp(type, lengp)
                    854: int type;
                    855: expptr lengp;
                    856: {
                    857: return( mktmpn(1,type,lengp) );
                    858: }
                    859: 
                    860: /* VARIOUS ROUTINES FOR PROCESSING DECLARATIONS */
                    861: 
                    862: struct Extsym *comblock(len, s)
                    863: register int len;
                    864: register char *s;
                    865: {
                    866: struct Extsym *p;
                    867: 
                    868: if(len == 0)
                    869:        {
                    870:        s = BLANKCOMMON;
                    871:        len = strlen(s);
                    872:        }
                    873: p = mkext( varunder(len, s) );
                    874: if(p->extstg == STGUNKNOWN)
                    875:        p->extstg = STGCOMMON;
                    876: else if(p->extstg != STGCOMMON)
                    877:        {
                    878:        errstr("%s cannot be a common block name", s);
                    879:        return(0);
                    880:        }
                    881: 
                    882: return( p );
                    883: }
                    884: 
                    885: 
                    886: incomm(c, v)
                    887: struct Extsym *c;
                    888: Namep v;
                    889: {
                    890: if(v->vstg != STGUNKNOWN)
                    891:        dclerr("incompatible common declaration", v);
                    892: else
                    893:        {
                    894:        v->vstg = STGCOMMON;
                    895:        c->extp = hookup(c->extp, mkchain(v,CHNULL) );
                    896:        }
                    897: }
                    898: 
                    899: 
                    900: 
                    901: 
                    902: settype(v, type, length)
                    903: register Namep  v;
                    904: register int type;
                    905: register int length;
                    906: {
                    907: if(type == TYUNKNOWN)
                    908:        return;
                    909: 
                    910: if(type==TYSUBR && v->vtype!=TYUNKNOWN && v->vstg==STGARG)
                    911:        {
                    912:        v->vtype = TYSUBR;
                    913:        frexpr(v->vleng);
                    914:        }
                    915: else if(type < 0)      /* storage class set */
                    916:        {
                    917:        if(v->vstg == STGUNKNOWN)
                    918:                v->vstg = - type;
                    919:        else if(v->vstg != -type)
                    920:                dclerr("incompatible storage declarations", v);
                    921:        }
                    922: else if(v->vtype == TYUNKNOWN)
                    923:        {
                    924:        if( (v->vtype = lengtype(type, length))==TYCHAR && length>=0)
                    925:                v->vleng = ICON(length);
                    926:        }
                    927: else if(v->vtype!=type || (type==TYCHAR && v->vleng->constblock.const.ci!=length) )
                    928:        dclerr("incompatible type declarations", v);
                    929: }
                    930: 
                    931: 
                    932: 
                    933: 
                    934: 
                    935: lengtype(type, length)
                    936: register int type;
                    937: register int length;
                    938: {
                    939: switch(type)
                    940:        {
                    941:        case TYREAL:
                    942:                if(length == 8)
                    943:                        return(TYDREAL);
                    944:                if(length == 4)
                    945:                        goto ret;
                    946:                break;
                    947: 
                    948:        case TYCOMPLEX:
                    949:                if(length == 16)
                    950:                        return(TYDCOMPLEX);
                    951:                if(length == 8)
                    952:                        goto ret;
                    953:                break;
                    954: 
                    955:        case TYSHORT:
                    956:        case TYDREAL:
                    957:        case TYDCOMPLEX:
                    958:        case TYCHAR:
                    959:        case TYUNKNOWN:
                    960:        case TYSUBR:
                    961:        case TYERROR:
                    962:                goto ret;
                    963: 
                    964:        case TYLOGICAL:
                    965:                if(length == typesize[TYLOGICAL])
                    966:                        goto ret;
                    967:                break;
                    968: 
                    969:        case TYLONG:
                    970:                if(length == 0)
                    971:                        return(tyint);
                    972:                if(length == 2)
                    973:                        return(TYSHORT);
                    974:                if(length == 4)
                    975:                        goto ret;
                    976:                break;
                    977:        default:
                    978:                badtype("lengtype", type);
                    979:        }
                    980: 
                    981: if(length != 0)
                    982:        err("incompatible type-length combination");
                    983: 
                    984: ret:
                    985:        return(type);
                    986: }
                    987: 
                    988: 
                    989: 
                    990: 
                    991: 
                    992: setintr(v)
                    993: register Namep  v;
                    994: {
                    995: register int k;
                    996: 
                    997: if(v->vstg == STGUNKNOWN)
                    998:        v->vstg = STGINTR;
                    999: else if(v->vstg!=STGINTR)
                   1000:        dclerr("incompatible use of intrinsic function", v);
                   1001: if(v->vclass==CLUNKNOWN)
                   1002:        v->vclass = CLPROC;
                   1003: if(v->vprocclass == PUNKNOWN)
                   1004:        v->vprocclass = PINTRINSIC;
                   1005: else if(v->vprocclass != PINTRINSIC)
                   1006:        dclerr("invalid intrinsic declaration", v);
                   1007: if(k = intrfunct(v->varname))
                   1008:        v->vardesc.varno = k;
                   1009: else
                   1010:        dclerr("unknown intrinsic function", v);
                   1011: }
                   1012: 
                   1013: 
                   1014: 
                   1015: setext(v)
                   1016: register Namep  v;
                   1017: {
                   1018: if(v->vclass == CLUNKNOWN)
                   1019:        v->vclass = CLPROC;
                   1020: else if(v->vclass != CLPROC)
                   1021:        dclerr("invalid external declaration", v);
                   1022: 
                   1023: if(v->vprocclass == PUNKNOWN)
                   1024:        v->vprocclass = PEXTERNAL;
                   1025: else if(v->vprocclass != PEXTERNAL)
                   1026:        dclerr("invalid external declaration", v);
                   1027: }
                   1028: 
                   1029: 
                   1030: 
                   1031: 
                   1032: /* create dimensions block for array variable */
                   1033: 
                   1034: setbound(v, nd, dims)
                   1035: register Namep  v;
                   1036: int nd;
                   1037: struct { expptr lb, ub; } dims[ ];
                   1038: {
                   1039: register expptr q, t;
                   1040: register struct Dimblock *p;
                   1041: int i;
                   1042: 
                   1043: if(v->vclass == CLUNKNOWN)
                   1044:        v->vclass = CLVAR;
                   1045: else if(v->vclass != CLVAR)
                   1046:        {
                   1047:        dclerr("only variables may be arrays", v);
                   1048:        return;
                   1049:        }
                   1050: 
                   1051: v->vdim = p = (struct Dimblock *)
                   1052:                ckalloc( sizeof(int) + (3+2*nd)*sizeof(expptr) );
                   1053: p->ndim = nd;
                   1054: p->nelt = ICON(1);
                   1055: 
                   1056: for(i=0 ; i<nd ; ++i)
                   1057:        {
                   1058:        if( (q = dims[i].ub) == NULL)
                   1059:                {
                   1060:                if(i == nd-1)
                   1061:                        {
                   1062:                        frexpr(p->nelt);
                   1063:                        p->nelt = NULL;
                   1064:                        }
                   1065:                else
                   1066:                        err("only last bound may be asterisk");
                   1067:                p->dims[i].dimsize = ICON(1);;
                   1068:                p->dims[i].dimexpr = NULL;
                   1069:                }
                   1070:        else
                   1071:                {
                   1072:                if(dims[i].lb)
                   1073:                        {
                   1074:                        q = mkexpr(OPMINUS, q, cpexpr(dims[i].lb));
                   1075:                        q = mkexpr(OPPLUS, q, ICON(1) );
                   1076:                        }
                   1077:                if( ISCONST(q) )
                   1078:                        {
                   1079:                        p->dims[i].dimsize = q;
                   1080:                        p->dims[i].dimexpr = (expptr) PNULL;
                   1081:                        }
                   1082:                else    {
                   1083:                        p->dims[i].dimsize = (expptr) autovar(1, tyint, PNULL);
                   1084:                        p->dims[i].dimexpr = q;
                   1085:                        }
                   1086:                if(p->nelt)
                   1087:                        p->nelt = mkexpr(OPSTAR, p->nelt,
                   1088:                                        cpexpr(p->dims[i].dimsize) );
                   1089:                }
                   1090:        }
                   1091: 
                   1092: q = dims[nd-1].lb;
                   1093: if(q == NULL)
                   1094:        q = ICON(1);
                   1095: 
                   1096: for(i = nd-2 ; i>=0 ; --i)
                   1097:        {
                   1098:        t = dims[i].lb;
                   1099:        if(t == NULL)
                   1100:                t = ICON(1);
                   1101:        if(p->dims[i].dimsize)
                   1102:                q = mkexpr(OPPLUS, t, mkexpr(OPSTAR, cpexpr(p->dims[i].dimsize), q) );
                   1103:        }
                   1104: 
                   1105: if( ISCONST(q) )
                   1106:        {
                   1107:        p->baseoffset = q;
                   1108:        p->basexpr = NULL;
                   1109:        }
                   1110: else
                   1111:        {
                   1112:        p->baseoffset = (expptr) autovar(1, tyint, PNULL);
                   1113:        p->basexpr = q;
                   1114:        }
                   1115: }

unix.superglobalmegacorp.com

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