Annotation of 40BSD/cmd/pi/fdec.c, revision 1.1.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.