Annotation of 41BSD/cmd/pi/fdec.c, revision 1.1

1.1     ! root        1: /* Copyright (c) 1979 Regents of the University of California */
        !             2: 
        !             3: static char sccsid[] = "@(#)fdec.c 1.7 10/28/80";
        !             4: 
        !             5: #include "whoami.h"
        !             6: #include "0.h"
        !             7: #include "tree.h"
        !             8: #include "opcode.h"
        !             9: #include "objfmt.h"
        !            10: #include "align.h"
        !            11: 
        !            12: /*
        !            13:  * this array keeps the pxp counters associated with
        !            14:  * functions and procedures, so that they can be output
        !            15:  * when their bodies are encountered
        !            16:  */
        !            17: int    bodycnts[ DSPLYSZ ];
        !            18: 
        !            19: #ifdef PC
        !            20: #   include "pc.h"
        !            21: #   include "pcops.h"
        !            22: #endif PC
        !            23: 
        !            24: #ifdef OBJ
        !            25: int    cntpatch;
        !            26: int    nfppatch;
        !            27: #endif OBJ
        !            28: 
        !            29: /*
        !            30:  * Funchdr inserts
        !            31:  * declaration of a the
        !            32:  * prog/proc/func into the
        !            33:  * namelist. It also handles
        !            34:  * the arguments and puts out
        !            35:  * a transfer which defines
        !            36:  * the entry point of a procedure.
        !            37:  */
        !            38: 
        !            39: struct nl *
        !            40: funchdr(r)
        !            41:        int *r;
        !            42: {
        !            43:        register struct nl *p;
        !            44:        register *il, **rl;
        !            45:        int *rll;
        !            46:        struct nl *cp, *dp, *sp;
        !            47:        int s, o, *pp;
        !            48: 
        !            49:        if (inpflist(r[2])) {
        !            50:                opush('l');
        !            51:                yyretrieve();   /* kludge */
        !            52:        }
        !            53:        pfcnt++;
        !            54:        parts[ cbn ] |= RPRT;
        !            55:        line = r[1];
        !            56:        if (r[3] == NIL && (p=lookup1(r[2])) != NIL && bn == cbn) {
        !            57:                /*
        !            58:                 * Symbol already defined
        !            59:                 * in this block. it is either
        !            60:                 * a redeclared symbol (error)
        !            61:                 * a forward declaration,
        !            62:                 * or an external declaration.
        !            63:                 */
        !            64:                if ((p->class == FUNC || p->class == PROC) && (p->nl_flags & NFORWD) != 0) {
        !            65:                        /*
        !            66:                         * Grammar doesnt forbid
        !            67:                         * types on a resolution
        !            68:                         * of a forward function
        !            69:                         * declaration.
        !            70:                         */
        !            71:                        if (p->class == FUNC && r[4])
        !            72:                                error("Function type should be given only in forward declaration");
        !            73:                        /*
        !            74:                         * get another counter for the actual
        !            75:                         */
        !            76:                        if ( monflg ) {
        !            77:                            bodycnts[ cbn ] = getcnt();
        !            78:                        }
        !            79: #                      ifdef PC
        !            80:                            enclosing[ cbn ] = p -> symbol;
        !            81: #                      endif PC
        !            82: #                      ifdef PTREE
        !            83:                                /*
        !            84:                                 *      mark this proc/func as forward
        !            85:                                 *      in the pTree.
        !            86:                                 */
        !            87:                            pDEF( p -> inTree ).PorFForward = TRUE;
        !            88: #                      endif PTREE
        !            89:                        return (p);
        !            90:                }
        !            91:        }
        !            92: 
        !            93:        /* if a routine segment is being compiled,
        !            94:         * do level one processing.
        !            95:         */
        !            96: 
        !            97:         if ((r[0] != T_PROG) && (!progseen))
        !            98:                level1();
        !            99: 
        !           100: 
        !           101:        /*
        !           102:         * Declare the prog/proc/func
        !           103:         */
        !           104:        switch (r[0]) {
        !           105:            case T_PROG:
        !           106:                    progseen++;
        !           107:                    if (opt('z'))
        !           108:                            monflg++;
        !           109:                    program = p = defnl(r[2], PROG, 0, 0);
        !           110:                    p->value[3] = r[1];
        !           111:                    break;
        !           112:            case T_PDEC:
        !           113:                    if (r[4] != NIL)
        !           114:                            error("Procedures do not have types, only functions do");
        !           115:                    p = enter(defnl(r[2], PROC, 0, 0));
        !           116:                    p->nl_flags |= NMOD;
        !           117: #                  ifdef PC
        !           118:                        enclosing[ cbn ] = r[2];
        !           119: #                  endif PC
        !           120:                    break;
        !           121:            case T_FDEC:
        !           122:                    il = r[4];
        !           123:                    if (il == NIL)
        !           124:                            error("Function type must be specified");
        !           125:                    else if (il[0] != T_TYID) {
        !           126:                            il = NIL;
        !           127:                            error("Function type can be specified only by using a type identifier");
        !           128:                    } else
        !           129:                            il = gtype(il);
        !           130:                    p = enter(defnl(r[2], FUNC, il, NIL));
        !           131:                    p->nl_flags |= NMOD;
        !           132:                    /*
        !           133:                     * An arbitrary restriction
        !           134:                     */
        !           135:                    switch (o = classify(p->type)) {
        !           136:                            case TFILE:
        !           137:                            case TARY:
        !           138:                            case TREC:
        !           139:                            case TSET:
        !           140:                            case TSTR:
        !           141:                                    warning();
        !           142:                                    if (opt('s')) {
        !           143:                                            standard();
        !           144:                                    }
        !           145:                                    error("Functions should not return %ss", clnames[o]);
        !           146:                    }
        !           147: #                  ifdef PC
        !           148:                        enclosing[ cbn ] = r[2];
        !           149: #                  endif PC
        !           150:                    break;
        !           151:            default:
        !           152:                    panic("funchdr");
        !           153:        }
        !           154:        if (r[0] != T_PROG) {
        !           155:                /*
        !           156:                 * Mark this proc/func as
        !           157:                 * being forward declared
        !           158:                 */
        !           159:                p->nl_flags |= NFORWD;
        !           160:                /*
        !           161:                 * Enter the parameters
        !           162:                 * in the next block for
        !           163:                 * the time being
        !           164:                 */
        !           165:                if (++cbn >= DSPLYSZ) {
        !           166:                        error("Procedure/function nesting too deep");
        !           167:                        pexit(ERRS);
        !           168:                }
        !           169:                /*
        !           170:                 * For functions, the function variable
        !           171:                 */
        !           172:                if (p->class == FUNC) {
        !           173: #                      ifdef OBJ
        !           174:                            cp = defnl(r[2], FVAR, p->type, 0);
        !           175: #                      endif OBJ
        !           176: #                      ifdef PC
        !           177:                                /*
        !           178:                                 * fvars used to be allocated and deallocated
        !           179:                                 * by the caller right before the arguments.
        !           180:                                 * the offset of the fvar was kept in
        !           181:                                 * value[NL_OFFS] of function (very wierd,
        !           182:                                 * but see asgnop).
        !           183:                                 * now, they are locals to the function
        !           184:                                 * with the offset kept in the fvar.
        !           185:                                 */
        !           186: 
        !           187:                            cp = defnl( r[2] , FVAR , p -> type
        !           188:                                      , -( roundup( DPOFF1+width( p -> type )
        !           189:                                                  , align( p -> type ) ) ) );
        !           190: #                      endif PC
        !           191:                        cp->chain = p;
        !           192:                        p->ptr[NL_FVAR] = cp;
        !           193:                }
        !           194:                /*
        !           195:                 * Enter the parameters
        !           196:                 * and compute total size
        !           197:                 */
        !           198:                cp = sp = p;
        !           199: 
        !           200: #              ifdef OBJ
        !           201:                    o = 0;
        !           202: #              endif OBJ
        !           203: #              ifdef PC
        !           204:                        /*
        !           205:                         * parameters used to be allocated backwards,
        !           206:                         * then fixed.  for pc, they are allocated correctly.
        !           207:                         * also, they are aligned.
        !           208:                         */
        !           209:                o = DPOFF2;
        !           210: #              endif PC
        !           211:                for (rl = r[3]; rl != NIL; rl = rl[2]) {
        !           212:                        p = NIL;
        !           213:                        if (rl[1] == NIL)
        !           214:                                continue;
        !           215:                        /*
        !           216:                         * Parametric procedures
        !           217:                         * don't have types !?!
        !           218:                         */
        !           219:                        if (rl[1][0] != T_PPROC) {
        !           220:                                rll = rl[1][2];
        !           221:                                if (rll[0] != T_TYID) {
        !           222:                                        error("Types for arguments can be specified only by using type identifiers");
        !           223:                                        p = NIL;
        !           224:                                } else
        !           225:                                        p = gtype(rll);
        !           226:                        }
        !           227:                        for (il = rl[1][1]; il != NIL; il = il[2]) {
        !           228:                                switch (rl[1][0]) {
        !           229:                                    default:
        !           230:                                            panic("funchdr2");
        !           231:                                    case T_PVAL:
        !           232:                                            if (p != NIL) {
        !           233:                                                    if (p->class == FILET)
        !           234:                                                            error("Files cannot be passed by value");
        !           235:                                                    else if (p->nl_flags & NFILES)
        !           236:                                                            error("Files cannot be a component of %ss passed by value",
        !           237:                                                                    nameof(p));
        !           238:                                            }
        !           239: #                                          ifdef OBJ
        !           240:                                                dp = defnl(il[1], VAR, p, o -= even(width(p)));
        !           241: #                                          endif OBJ
        !           242: #                                          ifdef PC
        !           243:                                                dp = defnl( il[1] , VAR , p 
        !           244:                                                        , o = roundup( o , A_STACK ) );
        !           245:                                                o += width( p );
        !           246: #                                          endif PC
        !           247:                                            dp->nl_flags |= NMOD;
        !           248:                                            break;
        !           249:                                    case T_PVAR:
        !           250: #                                          ifdef OBJ
        !           251:                                                dp = defnl(il[1], REF, p, o -= sizeof ( int * ) );
        !           252: #                                          endif OBJ
        !           253: #                                          ifdef PC
        !           254:                                                dp = defnl( il[1] , REF , p
        !           255:                                                        , o = roundup( o , A_STACK ) );
        !           256:                                                o += sizeof(char *);
        !           257: #                                          endif PC
        !           258:                                            break;
        !           259:                                    case T_PFUNC:
        !           260: #                                          ifdef OBJ
        !           261:                                                dp = defnl(il[1], FFUNC, p, o -= sizeof ( int * ) );
        !           262: #                                          endif OBJ
        !           263: #                                          ifdef PC
        !           264:                                                dp = defnl( il[1] , FFUNC , p
        !           265:                                                        , o = roundup( o , A_STACK ) );
        !           266:                                                o += sizeof(char *);
        !           267: #                                          endif PC
        !           268:                                            dp -> nl_flags |= NMOD;
        !           269:                                            break;
        !           270:                                    case T_PPROC:
        !           271: #                                          ifdef OBJ
        !           272:                                                dp = defnl(il[1], FPROC, p, o -= sizeof ( int * ) );
        !           273: #                                          endif OBJ
        !           274: #                                          ifdef PC
        !           275:                                                dp = defnl( il[1] , FPROC , p
        !           276:                                                        , o = roundup( o , A_STACK ) );
        !           277:                                                o += sizeof(char *);
        !           278: #                                          endif PC
        !           279:                                            dp -> nl_flags |= NMOD;
        !           280:                                            break;
        !           281:                                    }
        !           282:                                if (dp != NIL) {
        !           283:                                        cp->chain = dp;
        !           284:                                        cp = dp;
        !           285:                                }
        !           286:                        }
        !           287:                }
        !           288:                cbn--;
        !           289:                p = sp;
        !           290: #              ifdef OBJ
        !           291:                    p->value[NL_OFFS] = -o+DPOFF2;
        !           292:                        /*
        !           293:                         * Correct the naivete (naievity)
        !           294:                         * of our above code to
        !           295:                         * calculate offsets
        !           296:                         */
        !           297:                    for (il = p->chain; il != NIL; il = il->chain)
        !           298:                            il->value[NL_OFFS] += p->value[NL_OFFS];
        !           299: #              endif OBJ
        !           300: #              ifdef PC
        !           301:                    p -> value[ NL_OFFS ] = roundup( o , A_STACK );
        !           302: #              endif PC
        !           303:        } else { 
        !           304:                /*
        !           305:                 * The wonderful
        !           306:                 * program statement!
        !           307:                 */
        !           308: #              ifdef OBJ
        !           309:                    if (monflg) {
        !           310:                            put(1, O_PXPBUF);
        !           311:                            cntpatch = put(2, O_CASE4, 0);
        !           312:                            nfppatch = put(2, O_CASE4, 0);
        !           313:                    }
        !           314: #              endif OBJ
        !           315:                cp = p;
        !           316:                for (rl = r[3]; rl; rl = rl[2]) {
        !           317:                        if (rl[1] == NIL)
        !           318:                                continue;
        !           319:                        dp = defnl(rl[1], VAR, 0, 0);
        !           320:                        cp->chain = dp;
        !           321:                        cp = dp;
        !           322:                }
        !           323:        }
        !           324:        /*
        !           325:         * Define a branch at
        !           326:         * the "entry point" of
        !           327:         * the prog/proc/func.
        !           328:         */
        !           329:        p->entloc = getlab();
        !           330:        if (monflg) {
        !           331:                bodycnts[ cbn ] = getcnt();
        !           332:                p->value[ NL_CNTR ] = 0;
        !           333:        }
        !           334: #      ifdef OBJ
        !           335:            put(2, O_TRA4, p->entloc);
        !           336: #      endif OBJ
        !           337: #      ifdef PTREE
        !           338:            {
        !           339:                pPointer        PF = tCopy( r );
        !           340: 
        !           341:                pSeize( PorFHeader[ nesting ] );
        !           342:                if ( r[0] != T_PROG ) {
        !           343:                        pPointer        *PFs;
        !           344: 
        !           345:                        PFs = &( pDEF( PorFHeader[ nesting ] ).PorFPFs );
        !           346:                        *PFs = ListAppend( *PFs , PF );
        !           347:                } else {
        !           348:                        pDEF( PorFHeader[ nesting ] ).GlobProg = PF;
        !           349:                }
        !           350:                pRelease( PorFHeader[ nesting ] );
        !           351:            }
        !           352: #      endif PTREE
        !           353:        return (p);
        !           354: }
        !           355: 
        !           356: funcfwd(fp)
        !           357:        struct nl *fp;
        !           358: {
        !           359: 
        !           360:            /*
        !           361:             *  save the counter for this function
        !           362:             */
        !           363:        if ( monflg ) {
        !           364:            fp -> value[ NL_CNTR ] = bodycnts[ cbn ];
        !           365:        }
        !           366:        return (fp);
        !           367: }
        !           368: 
        !           369: /*
        !           370:  * Funcext marks the procedure or
        !           371:  * function external in the symbol
        !           372:  * table. Funcext should only be
        !           373:  * called if PC, and is an error
        !           374:  * otherwise.
        !           375:  */
        !           376: 
        !           377: funcext(fp)
        !           378:        struct nl *fp;
        !           379: {
        !           380: 
        !           381: #ifdef PC
        !           382:        if (opt('s')) {
        !           383:                standard();
        !           384:                error("External procedures and functions are not standard");
        !           385:        } else {
        !           386:                if (cbn == 1) {
        !           387:                        fp->ext_flags |= NEXTERN;
        !           388:                        stabefunc( fp -> symbol , fp -> class , line );
        !           389:                }
        !           390:                else
        !           391:                        error("External procedures and functions can only be declared at the outermost level.");
        !           392:        }
        !           393: #endif PC
        !           394: #ifdef OBJ
        !           395:        error("Procedures or functions cannot be declared external.");
        !           396: #endif OBJ
        !           397: 
        !           398:        return(fp);
        !           399: }
        !           400: 
        !           401: /*
        !           402:  * Funcbody is called
        !           403:  * when the actual (resolved)
        !           404:  * declaration of a procedure is
        !           405:  * encountered. It puts the names
        !           406:  * of the (function) and parameters
        !           407:  * into the symbol table.
        !           408:  */
        !           409: funcbody(fp)
        !           410:        struct nl *fp;
        !           411: {
        !           412:        register struct nl *q, *p;
        !           413: 
        !           414:        cbn++;
        !           415:        if (cbn >= DSPLYSZ) {
        !           416:                error("Too many levels of function/procedure nesting");
        !           417:                pexit(ERRS);
        !           418:        }
        !           419:        sizes[cbn].om_max = sizes[cbn].om_off = -DPOFF1;
        !           420:        gotos[cbn] = NIL;
        !           421:        errcnt[cbn] = syneflg;
        !           422:        parts[ cbn ] = NIL;
        !           423:        dfiles[ cbn ] = FALSE;
        !           424:        if (fp == NIL)
        !           425:                return (NIL);
        !           426:        /*
        !           427:         * Save the virtual name
        !           428:         * list stack pointer so
        !           429:         * the space can be freed
        !           430:         * later (funcend).
        !           431:         */
        !           432:        fp->ptr[2] = nlp;
        !           433: #      ifdef PC
        !           434:            if ( fp -> class != PROG ) {
        !           435:                stabfunc( fp -> symbol , fp -> class , line , cbn - 1 );
        !           436:            } else {
        !           437:                stabfunc( "program" , fp -> class , line , 0 );
        !           438:            }
        !           439: #      endif PC
        !           440:        if (fp->class != PROG) {
        !           441:                for (q = fp->chain; q != NIL; q = q->chain) {
        !           442:                        enter(q);
        !           443: #                      ifdef PC
        !           444:                            stabparam( q -> symbol , p2type( q -> type )
        !           445:                                        , q -> value[ NL_OFFS ]
        !           446:                                        , lwidth( q -> type ) );
        !           447: #                      endif PC
        !           448:                }
        !           449:        }
        !           450:        if (fp->class == FUNC) {
        !           451:                /*
        !           452:                 * For functions, enter the fvar
        !           453:                 */
        !           454:                enter(fp->ptr[NL_FVAR]);
        !           455: #              ifdef PC
        !           456:                    q = fp -> ptr[ NL_FVAR ];
        !           457:                    sizes[cbn].om_off -= lwidth( q -> type );
        !           458:                    sizes[cbn].om_max = sizes[cbn].om_off;
        !           459:                    stabvar( q -> symbol , p2type( q -> type ) , cbn 
        !           460:                            , q -> value[ NL_OFFS ] , lwidth( q -> type )
        !           461:                            , line );
        !           462: #              endif PC
        !           463:        }
        !           464: #      ifdef PTREE
        !           465:                /*
        !           466:                 *      pick up the pointer to porf declaration
        !           467:                 */
        !           468:            PorFHeader[ ++nesting ] = fp -> inTree;
        !           469: #      endif PTREE
        !           470:        return (fp);
        !           471: }
        !           472: 
        !           473: struct nl *Fp;
        !           474: int    pnumcnt;
        !           475: /*
        !           476:  * Funcend is called to
        !           477:  * finish a block by generating
        !           478:  * the code for the statements.
        !           479:  * It then looks for unresolved declarations
        !           480:  * of labels, procedures and functions,
        !           481:  * and cleans up the name list.
        !           482:  * For the program, it checks the
        !           483:  * semantics of the program
        !           484:  * statement (yuchh).
        !           485:  */
        !           486: funcend(fp, bundle, endline)
        !           487:        struct nl *fp;
        !           488:        int *bundle;
        !           489:        int endline;
        !           490: {
        !           491:        register struct nl *p;
        !           492:        register int i, b;
        !           493:        int var, inp, out, chkref, *blk;
        !           494:        struct nl *iop;
        !           495:        char *cp;
        !           496:        extern int cntstat;
        !           497: #      ifdef PC
        !           498:            int toplabel = getlab();
        !           499:            int botlabel = getlab();
        !           500: #      endif PC
        !           501: 
        !           502:        cntstat = 0;
        !           503: /*
        !           504:  *     yyoutline();
        !           505:  */
        !           506:        if (program != NIL)
        !           507:                line = program->value[3];
        !           508:        blk = bundle[2];
        !           509:        if (fp == NIL) {
        !           510:                cbn--;
        !           511: #              ifdef PTREE
        !           512:                    nesting--;
        !           513: #              endif PTREE
        !           514:                return;
        !           515:        }
        !           516: #ifdef OBJ
        !           517:        /*
        !           518:         * Patch the branch to the
        !           519:         * entry point of the function
        !           520:         */
        !           521:        patch4(fp->entloc);
        !           522:        /*
        !           523:         * Put out the block entrance code and the block name.
        !           524:         * the CONG is overlaid by a patch later!
        !           525:         */
        !           526:        var = put(2, (lenstr(fp->symbol,0) << 8)
        !           527:                        | (cbn == 1 && opt('p') == 0 ? O_NODUMP: O_BEG), 0);
        !           528:            /*
        !           529:             *  output the number of bytes of arguments
        !           530:             *  this is only checked on formal calls.
        !           531:             */
        !           532:        put(2, O_CASE4, cbn == 1 ? 0 : fp->value[NL_OFFS]-DPOFF2);
        !           533:        put(2, O_CASE2, bundle[1]);
        !           534:        putstr(fp->symbol, 0);
        !           535: #endif OBJ
        !           536: #ifdef PC
        !           537:        /*
        !           538:         * put out the procedure entry code
        !           539:         */
        !           540:        if ( fp -> class == PROG ) {
        !           541:            putprintf( "        .text" , 0 );
        !           542:            putprintf( "        .align  1" , 0 );
        !           543:            putprintf( "        .globl  _main" , 0 );
        !           544:            putprintf( "_main:" , 0 );
        !           545:            putprintf( "        .word   0" , 0 );
        !           546:            putprintf( "        calls   $0,_PCSTART" , 0 );
        !           547:            putprintf( "        movl    4(ap),__argc" , 0 );
        !           548:            putprintf( "        movl    8(ap),__argv" , 0 );
        !           549:            putprintf( "        calls   $0,_program" , 0 );
        !           550:            putprintf( "        calls   $0,_PCEXIT" , 0 );
        !           551:            ftnno = fp -> entloc;
        !           552:            putprintf( "        .text" , 0 );
        !           553:            putprintf( "        .align  1" , 0 );
        !           554:            putprintf( "        .globl  _program" , 0 );
        !           555:            putprintf( "_program:" , 0 );
        !           556:        } else {
        !           557:            ftnno = fp -> entloc;
        !           558:            putprintf( "        .text" , 0 );
        !           559:            putprintf( "        .align  1" , 0 );
        !           560:            putprintf( "        .globl  " , 1 );
        !           561:            for ( i = 1 ; i < cbn ; i++ ) {
        !           562:                putprintf( EXTFORMAT , 1 , enclosing[ i ] );
        !           563:            }
        !           564:            putprintf( "" , 0 );
        !           565:            for ( i = 1 ; i < cbn ; i++ ) {
        !           566:                putprintf( EXTFORMAT , 1 , enclosing[ i ] );
        !           567:            }
        !           568:            putprintf( ":" , 0 );
        !           569:        }
        !           570:        stablbrac( cbn );
        !           571:            /*
        !           572:             *  register save mask
        !           573:             */
        !           574:        if ( opt( 't' ) ) {
        !           575:            putprintf( "        .word   0x%x" , 0 , RUNCHECK | RSAVEMASK );
        !           576:        } else {
        !           577:            putprintf( "        .word   0x%x" , 0 , RSAVEMASK );
        !           578:        }
        !           579:        putjbr( botlabel );
        !           580:        putlab( toplabel );
        !           581:        if ( profflag ) {
        !           582:                /*
        !           583:                 *      call mcount for profiling
        !           584:                 */
        !           585:            putprintf( "        moval   1f,r0" , 0 );
        !           586:            putprintf( "        jsb     mcount" , 0 );
        !           587:            putprintf( "        .data" , 0 );
        !           588:            putprintf( "        .align  2" , 0 );
        !           589:            putprintf( "1:" , 0 );
        !           590:            putprintf( "        .long   0" , 0 );
        !           591:            putprintf( "        .text" , 0 );
        !           592:        }
        !           593:            /*
        !           594:             *  set up unwind exception vector.
        !           595:             */
        !           596:        putprintf( "    moval   %s,%d(%s)" , 0
        !           597:                , UNWINDNAME , UNWINDOFFSET , P2FPNAME );
        !           598:            /*
        !           599:             *  save address of display entry, for unwind.
        !           600:             */
        !           601:        putprintf( "    moval   %s+%d,%d(%s)" , 0
        !           602:                , DISPLAYNAME , cbn * sizeof(struct dispsave)
        !           603:                , DPTROFFSET , P2FPNAME );
        !           604:            /*
        !           605:             *  save old display 
        !           606:             */
        !           607:        putprintf( "    movq    %s+%d,%d(%s)" , 0
        !           608:                , DISPLAYNAME , cbn * sizeof(struct dispsave)
        !           609:                , DSAVEOFFSET , P2FPNAME );
        !           610:            /*
        !           611:             *  set up new display by saving AP and FP in appropriate
        !           612:             *  slot in display structure.
        !           613:             */
        !           614:        putprintf( "    movq    %s,%s+%d" , 0
        !           615:                , P2APNAME , DISPLAYNAME , cbn * sizeof(struct dispsave) );
        !           616:            /*
        !           617:             *  ask second pass to allocate known locals
        !           618:             */
        !           619:        putlbracket( ftnno , -sizes[ cbn ].om_max );
        !           620:            /*
        !           621:             *  and zero them if checking is on
        !           622:             *  by calling zframe( bytes of locals , highest local address );
        !           623:             */
        !           624:        if ( opt( 't' ) ) {
        !           625:            if ( ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
        !           626:                putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
        !           627:                        , "_ZFRAME" );
        !           628:                putleaf( P2ICON ,  ( -sizes[ cbn ].om_max ) - DPOFF1
        !           629:                        , 0 , P2INT , 0 );
        !           630:                putLV( 0 , cbn , sizes[ cbn ].om_max , P2CHAR );
        !           631:                putop( P2LISTOP , P2INT );
        !           632:                putop( P2CALL , P2INT );
        !           633:                putdot( filename , line );
        !           634:            }
        !           635:                /*
        !           636:                 *  check number of longs of arguments
        !           637:                 *  this can only be wrong for formal calls.
        !           638:                 */
        !           639:            if ( fp -> class != PROG ) {
        !           640:                    putleaf( P2ICON , 0 , 0 , ADDTYPE( P2PTR , P2FTN | P2INT ) ,
        !           641:                            "_NARGCHK" );
        !           642:                    putleaf( P2ICON ,
        !           643:                        (fp->value[NL_OFFS] - DPOFF2) / sizeof(long) ,
        !           644:                        0 , P2INT , 0 );
        !           645:                    putop( P2CALL , P2INT );
        !           646:                    putdot( filename , line );
        !           647:            }
        !           648:        }
        !           649: #endif PC
        !           650:        if ( monflg ) {
        !           651:                if ( fp -> value[ NL_CNTR ] != 0 ) {
        !           652:                        inccnt( fp -> value [ NL_CNTR ] );
        !           653:                }
        !           654:                inccnt( bodycnts[ fp -> nl_block & 037 ] );
        !           655:        }
        !           656:        if (fp->class == PROG) {
        !           657:                /*
        !           658:                 * The glorious buffers option.
        !           659:                 *          0 = don't buffer output
        !           660:                 *          1 = line buffer output
        !           661:                 *          2 = 512 byte buffer output
        !           662:                 */
        !           663: #              ifdef OBJ
        !           664:                    if (opt('b') != 1)
        !           665:                            put(1, O_BUFF | opt('b') << 8);
        !           666: #              endif OBJ
        !           667: #              ifdef PC
        !           668:                    if ( opt( 'b' ) != 1 ) {
        !           669:                        putleaf( P2ICON , 0 , 0
        !           670:                                , ADDTYPE( P2FTN | P2INT , P2PTR ) , "_BUFF" );
        !           671:                        putleaf( P2ICON , opt( 'b' ) , 0 , P2INT , 0 );
        !           672:                        putop( P2CALL , P2INT );
        !           673:                        putdot( filename , line );
        !           674:                    }
        !           675: #              endif PC
        !           676:                out = 0;
        !           677:                for (p = fp->chain; p != NIL; p = p->chain) {
        !           678:                        if (strcmp(p->symbol, "input") == 0) {
        !           679:                                inp++;
        !           680:                                continue;
        !           681:                        }
        !           682:                        if (strcmp(p->symbol, "output") == 0) {
        !           683:                                out++;
        !           684:                                continue;
        !           685:                        }
        !           686:                        iop = lookup1(p->symbol);
        !           687:                        if (iop == NIL || bn != cbn) {
        !           688:                                error("File %s listed in program statement but not declared", p->symbol);
        !           689:                                continue;
        !           690:                        }
        !           691:                        if (iop->class != VAR) {
        !           692:                                error("File %s listed in program statement but declared as a %s", p->symbol, classes[iop->class]);
        !           693:                                continue;
        !           694:                        }
        !           695:                        if (iop->type == NIL)
        !           696:                                continue;
        !           697:                        if (iop->type->class != FILET) {
        !           698:                                error("File %s listed in program statement but defined as %s",
        !           699:                                        p->symbol, nameof(iop->type));
        !           700:                                continue;
        !           701:                        }
        !           702: #                      ifdef OBJ
        !           703:                            put(2, O_LV | bn << 8+INDX, iop->value[NL_OFFS]);
        !           704:                            i = lenstr(p->symbol,0);
        !           705:                            put(2, O_LVCON, i);
        !           706:                            putstr(p->symbol, 0);
        !           707:                            do {
        !           708:                                i--;
        !           709:                            } while (p->symbol+i == 0);
        !           710:                            put(2, O_CON24, i+1);
        !           711:                            put(2, O_CON24, text(iop->type) ? 0 : width(iop->type->type));
        !           712:                            put(1, O_DEFNAME);
        !           713: #                      endif OBJ
        !           714: #                      ifdef PC
        !           715:                            putleaf( P2ICON , 0 , 0
        !           716:                                    , ADDTYPE( P2FTN | P2INT , P2PTR )
        !           717:                                    , "_DEFNAME" );
        !           718:                            putLV( p -> symbol , bn , iop -> value[NL_OFFS]
        !           719:                                    , p2type( iop ) );
        !           720:                            putCONG( p -> symbol , strlen( p -> symbol )
        !           721:                                    , LREQ );
        !           722:                            putop( P2LISTOP , P2INT );
        !           723:                            putleaf( P2ICON , strlen( p -> symbol )
        !           724:                                    , 0 , P2INT , 0 );
        !           725:                            putop( P2LISTOP , P2INT );
        !           726:                            putleaf( P2ICON
        !           727:                                , text(iop->type) ? 0 : width(iop->type->type)
        !           728:                                , 0 , P2INT , 0 );
        !           729:                            putop( P2LISTOP , P2INT );
        !           730:                            putop( P2CALL , P2INT );
        !           731:                            putdot( filename , line );
        !           732: #                      endif PC
        !           733:                }
        !           734:                if (out == 0 && fp->chain != NIL) {
        !           735:                        recovered();
        !           736:                        error("The file output must appear in the program statement file list");
        !           737:                }
        !           738:        }
        !           739:        /*
        !           740:         * Process the prog/proc/func body
        !           741:         */
        !           742:        noreach = 0;
        !           743:        line = bundle[1];
        !           744:        statlist(blk);
        !           745: #      ifdef PTREE
        !           746:            {
        !           747:                pPointer Body = tCopy( blk );
        !           748: 
        !           749:                pDEF( PorFHeader[ nesting -- ] ).PorFBody = Body;
        !           750:            }
        !           751: #      endif PTREE
        !           752: #      ifdef OBJ
        !           753:            if (cbn== 1 && monflg != 0) {
        !           754:                    patchfil(cntpatch - 2, cnts, 2);
        !           755:                    patchfil(nfppatch - 2, pfcnt, 2);
        !           756:            }
        !           757: #      endif OBJ
        !           758: #      ifdef PC
        !           759:            if ( fp -> class == PROG && monflg ) {
        !           760:                putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
        !           761:                        , "_PMFLUSH" );
        !           762:                putleaf( P2ICON , cnts , 0 , P2INT , 0 );
        !           763:                putleaf( P2ICON , pfcnt , 0 , P2INT , 0 );
        !           764:                putop( P2LISTOP , P2INT );
        !           765:                putop( P2CALL , P2INT );
        !           766:                putdot( filename , line );
        !           767:            }
        !           768: #      endif PC
        !           769:        if (fp->class == PROG && inp == 0 && (input->nl_flags & (NUSED|NMOD)) != 0) {
        !           770:                recovered();
        !           771:                error("Input is used but not defined in the program statement");
        !           772:        }
        !           773:        /*
        !           774:         * Clean up the symbol table displays and check for unresolves
        !           775:         */
        !           776:        line = endline;
        !           777:        b = cbn;
        !           778:        Fp = fp;
        !           779:        chkref = syneflg == errcnt[cbn] && opt('w') == 0;
        !           780:        for (i = 0; i <= 077; i++) {
        !           781:                for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) {
        !           782:                        /*
        !           783:                         * Check for variables defined
        !           784:                         * but not referenced 
        !           785:                         */
        !           786:                        if (chkref && p->symbol != NIL)
        !           787:                        switch (p->class) {
        !           788:                                case FIELD:
        !           789:                                        /*
        !           790:                                         * If the corresponding record is
        !           791:                                         * unused, we shouldn't complain about
        !           792:                                         * the fields.
        !           793:                                         */
        !           794:                                default:
        !           795:                                        if ((p->nl_flags & (NUSED|NMOD)) == 0) {
        !           796:                                                warning();
        !           797:                                                nerror("%s %s is neither used nor set", classes[p->class], p->symbol);
        !           798:                                                break;
        !           799:                                        }
        !           800:                                        /*
        !           801:                                         * If a var parameter is either
        !           802:                                         * modified or used that is enough.
        !           803:                                         */
        !           804:                                        if (p->class == REF)
        !           805:                                                continue;
        !           806: #                                      ifdef OBJ
        !           807:                                            if ((p->nl_flags & NUSED) == 0) {
        !           808:                                                warning();
        !           809:                                                nerror("%s %s is never used", classes[p->class], p->symbol);
        !           810:                                                break;
        !           811:                                            }
        !           812: #                                      endif OBJ
        !           813: #                                      ifdef PC
        !           814:                                            if (((p->nl_flags & NUSED) == 0) && ((p->ext_flags & NEXTERN) == 0)) {
        !           815:                                                warning();
        !           816:                                                nerror("%s %s is never used", classes[p->class], p->symbol);
        !           817:                                                break;
        !           818:                                            }
        !           819: #                                      endif PC
        !           820:                                        if ((p->nl_flags & NMOD) == 0) {
        !           821:                                                warning();
        !           822:                                                nerror("%s %s is used but never set", classes[p->class], p->symbol);
        !           823:                                                break;
        !           824:                                        }
        !           825:                                case LABEL:
        !           826:                                case FVAR:
        !           827:                                case BADUSE:
        !           828:                                        break;
        !           829:                        }
        !           830:                        switch (p->class) {
        !           831:                                case BADUSE:
        !           832:                                        cp = "s";
        !           833:                                        if (p->chain->ud_next == NIL)
        !           834:                                                cp++;
        !           835:                                        eholdnl();
        !           836:                                        if (p->value[NL_KINDS] & ISUNDEF)
        !           837:                                                nerror("%s undefined on line%s", p->symbol, cp);
        !           838:                                        else
        !           839:                                                nerror("%s improperly used on line%s", p->symbol, cp);
        !           840:                                        pnumcnt = 10;
        !           841:                                        pnums(p->chain);
        !           842:                                        pchr('\n');
        !           843:                                        break;
        !           844: 
        !           845:                                case FUNC:
        !           846:                                case PROC:
        !           847: #                                      ifdef OBJ
        !           848:                                            if ((p->nl_flags & NFORWD))
        !           849:                                                nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
        !           850: #                                      endif OBJ
        !           851: #                                      ifdef PC
        !           852:                                            if ((p->nl_flags & NFORWD) && ((p->ext_flags & NEXTERN) == 0))
        !           853:                                                nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
        !           854: #                                      endif PC
        !           855:                                        break;
        !           856: 
        !           857:                                case LABEL:
        !           858:                                        if (p->nl_flags & NFORWD)
        !           859:                                                nerror("label %s was declared but not defined", p->symbol);
        !           860:                                        break;
        !           861:                                case FVAR:
        !           862:                                        if ((p->nl_flags & NMOD) == 0)
        !           863:                                                nerror("No assignment to the function variable");
        !           864:                                        break;
        !           865:                        }
        !           866:                }
        !           867:                /*
        !           868:                 * Pop this symbol
        !           869:                 * table slot
        !           870:                 */
        !           871:                disptab[i] = p;
        !           872:        }
        !           873: 
        !           874: #      ifdef OBJ
        !           875:            put(1, O_END);
        !           876: #      endif OBJ
        !           877: #      ifdef PC
        !           878:                /*
        !           879:                 *      if there were file variables declared at this level
        !           880:                 *      call pclose( &__disply[ cbn ] ) to clean them up.
        !           881:                 */
        !           882:            if ( dfiles[ cbn ] ) {
        !           883:                putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
        !           884:                        , "_PCLOSE" );
        !           885:                putRV( DISPLAYNAME , 0 , cbn * sizeof( struct dispsave )
        !           886:                        , P2PTR | P2CHAR );
        !           887:                putop( P2CALL , P2INT );
        !           888:                putdot( filename , line );
        !           889:            }
        !           890:                /*
        !           891:                 *      if this is a function,
        !           892:                 *      the function variable is the return value.
        !           893:                 *      if it's a scalar valued function, return scalar,
        !           894:                 *      else, return a pointer to the structure value.
        !           895:                 */
        !           896:            if ( fp -> class == FUNC ) {
        !           897:                struct nl       *fvar = fp -> ptr[ NL_FVAR ];
        !           898:                long            fvartype = p2type( fvar -> type );
        !           899:                long            label;
        !           900:                char            labelname[ BUFSIZ ];
        !           901: 
        !           902:                switch ( classify( fvar -> type ) ) {
        !           903:                    case TBOOL:
        !           904:                    case TCHAR:
        !           905:                    case TINT:
        !           906:                    case TSCAL:
        !           907:                    case TDOUBLE:
        !           908:                    case TPTR:
        !           909:                        putRV( fvar -> symbol , ( fvar -> nl_block ) & 037
        !           910:                                , fvar -> value[ NL_OFFS ] , fvartype );
        !           911:                        break;
        !           912:                    default:
        !           913:                        label = getlab();
        !           914:                        sprintf( labelname , PREFIXFORMAT ,
        !           915:                                LABELPREFIX , label );
        !           916:                        putprintf( "    .data" , 0 );
        !           917:                        putprintf( "    .lcomm  %s,%d" , 0 ,
        !           918:                                    labelname , lwidth( fvar -> type ) );
        !           919:                        putprintf( "    .text" , 0 );
        !           920:                        putleaf( P2NAME , 0 , 0 , fvartype , labelname );
        !           921:                        putLV( fvar -> symbol , ( fvar -> nl_block ) & 037
        !           922:                                , fvar -> value[ NL_OFFS ] , fvartype );
        !           923:                        putstrop( P2STASG , fvartype , lwidth( fvar -> type ) ,
        !           924:                                align( fvar -> type ) );
        !           925:                        putdot( filename , line );
        !           926:                        putleaf( P2ICON , 0 , 0 , fvartype , labelname );
        !           927:                        break;
        !           928:                }
        !           929:                putop( P2FORCE , fvartype );
        !           930:                putdot( filename , line );
        !           931:            }
        !           932:                /*
        !           933:                 *      restore old display entry from save area
        !           934:                 */
        !           935: 
        !           936:            putprintf( "        movq    %d(%s),%s+%d" , 0
        !           937:                , DSAVEOFFSET , P2FPNAME
        !           938:                , DISPLAYNAME , cbn * sizeof(struct dispsave) );
        !           939:            stabrbrac( cbn );
        !           940:            putprintf( "        ret" , 0 );
        !           941:                /*
        !           942:                 *      let the second pass allocate locals
        !           943:                 */
        !           944:            putlab( botlabel );
        !           945:            putprintf( "        subl2   $LF%d,sp" , 0 , ftnno );
        !           946:            putrbracket( ftnno );
        !           947:            putjbr( toplabel );
        !           948:                /*
        !           949:                 *      declare pcp counters, if any
        !           950:                 */
        !           951:            if ( monflg && fp -> class == PROG ) {
        !           952:                putprintf( "    .data" , 0 );
        !           953:                putprintf( "    .comm   " , 1 );
        !           954:                putprintf( PCPCOUNT , 1 );
        !           955:                putprintf( ",%d" , 0 , ( cnts + 1 ) * sizeof (long) );
        !           956:                putprintf( "    .text" , 0 );
        !           957:            }
        !           958: #      endif PC
        !           959: #ifdef DEBUG
        !           960:        dumpnl(fp->ptr[2], fp->symbol);
        !           961: #endif
        !           962:        /*
        !           963:         * Restore the
        !           964:         * (virtual) name list
        !           965:         * position
        !           966:         */
        !           967:        nlfree(fp->ptr[2]);
        !           968:        /*
        !           969:         * Proc/func has been
        !           970:         * resolved
        !           971:         */
        !           972:        fp->nl_flags &= ~NFORWD;
        !           973:        /*
        !           974:         * Patch the beg
        !           975:         * of the proc/func to
        !           976:         * the proper variable size
        !           977:         */
        !           978:        if (Fp == NIL)
        !           979:                elineon();
        !           980: #      ifdef OBJ
        !           981:            patchfil(var, sizes[cbn].om_max, 2);
        !           982: #      endif OBJ
        !           983:        cbn--;
        !           984:        if (inpflist(fp->symbol)) {
        !           985:                opop('l');
        !           986:        }
        !           987: }
        !           988: 
        !           989: 
        !           990: /*
        !           991:  * Segend is called to check for
        !           992:  * unresolved variables, funcs and
        !           993:  * procs, and deliver unresolved and
        !           994:  * baduse error diagnostics at the
        !           995:  * end of a routine segment (a separately
        !           996:  * compiled segment that is not the 
        !           997:  * main program) for PC. This
        !           998:  * routine should only be called
        !           999:  * by PC (not standard).
        !          1000:  */
        !          1001:  segend()
        !          1002:  {
        !          1003:        register struct nl *p;
        !          1004:        register int i,b;
        !          1005:        char *cp;
        !          1006: 
        !          1007: #ifdef PC
        !          1008:        if (opt('s')) {
        !          1009:                standard();
        !          1010:                error("Separately compiled routine segments are not standard.");
        !          1011:        } else {
        !          1012:                b = cbn;
        !          1013:                for (i=0; i<077; i++) {
        !          1014:                        for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) {
        !          1015:                        switch (p->class) {
        !          1016:                                case BADUSE:
        !          1017:                                        cp = 's';
        !          1018:                                        if (p->chain->ud_next == NIL)
        !          1019:                                                cp++;
        !          1020:                                        eholdnl();
        !          1021:                                        if (p->value[NL_KINDS] & ISUNDEF)
        !          1022:                                                nerror("%s undefined on line%s", p->symbol, cp);
        !          1023:                                        else
        !          1024:                                                nerror("%s improperly used on line%s", p->symbol, cp);
        !          1025:                                        pnumcnt = 10;
        !          1026:                                        pnums(p->chain);
        !          1027:                                        pchr('\n');
        !          1028:                                        break;
        !          1029:                                
        !          1030:                                case FUNC:
        !          1031:                                case PROC:
        !          1032:                                        if ((p->nl_flags & NFORWD) && ((p->ext_flags & NEXTERN) == 0))
        !          1033:                                                nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
        !          1034:                                        break;
        !          1035: 
        !          1036:                                case FVAR:
        !          1037:                                        if (((p->nl_flags & NMOD) == 0) && ((p->chain->ext_flags & NEXTERN) == 0))
        !          1038:                                                nerror("No assignment to the function variable");
        !          1039:                                        break;
        !          1040:                            }
        !          1041:                           }
        !          1042:                           disptab[i] = p;
        !          1043:                    }
        !          1044:        }
        !          1045: #endif PC
        !          1046: #ifdef OBJ
        !          1047:        error("Missing program statement and program body");
        !          1048: #endif OBJ
        !          1049: 
        !          1050: }
        !          1051: 
        !          1052: 
        !          1053: /*
        !          1054:  * Level1 does level one processing for
        !          1055:  * separately compiled routine segments
        !          1056:  */
        !          1057: level1()
        !          1058: {
        !          1059: 
        !          1060: #      ifdef OBJ
        !          1061:            error("Missing program statement");
        !          1062: #      endif OBJ
        !          1063: #      ifdef PC
        !          1064:            if (opt('s')) {
        !          1065:                    standard();
        !          1066:                    error("Missing program statement");
        !          1067:            }
        !          1068: #      endif PC
        !          1069: 
        !          1070:        cbn++;
        !          1071:        sizes[cbn].om_max = sizes[cbn].om_off = -DPOFF1;
        !          1072:        gotos[cbn] = NIL;
        !          1073:        errcnt[cbn] = syneflg;
        !          1074:        parts[ cbn ] = NIL;
        !          1075:        dfiles[ cbn ] = FALSE;
        !          1076:        progseen++;
        !          1077: }
        !          1078: 
        !          1079: 
        !          1080: 
        !          1081: pnums(p)
        !          1082:        struct udinfo *p;
        !          1083: {
        !          1084: 
        !          1085:        if (p->ud_next != NIL)
        !          1086:                pnums(p->ud_next);
        !          1087:        if (pnumcnt == 0) {
        !          1088:                printf("\n\t");
        !          1089:                pnumcnt = 20;
        !          1090:        }
        !          1091:        pnumcnt--;
        !          1092:        printf(" %d", p->ud_line);
        !          1093: }
        !          1094: 
        !          1095: nerror(a1, a2, a3)
        !          1096: {
        !          1097: 
        !          1098:        if (Fp != NIL) {
        !          1099:                yySsync();
        !          1100: #ifndef PI1
        !          1101:                if (opt('l'))
        !          1102:                        yyoutline();
        !          1103: #endif
        !          1104:                yysetfile(filename);
        !          1105:                printf("In %s %s:\n", classes[Fp->class], Fp->symbol);
        !          1106:                Fp = NIL;
        !          1107:                elineoff();
        !          1108:        }
        !          1109:        error(a1, a2, a3);
        !          1110: }

unix.superglobalmegacorp.com

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