Annotation of 43BSDReno/pgrm/pascal/src/call.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: static char sccsid[] = "@(#)call.c     5.3 (Berkeley) 11/12/86";
        !             9: #endif not lint
        !            10: 
        !            11: #include "whoami.h"
        !            12: #include "0.h"
        !            13: #include "tree.h"
        !            14: #include "opcode.h"
        !            15: #include "objfmt.h"
        !            16: #include "align.h"
        !            17: #ifdef PC
        !            18: #   include "pc.h"
        !            19: #   include <pcc.h>
        !            20: #endif PC
        !            21: #include "tmps.h"
        !            22: #include "tree_ty.h"
        !            23: 
        !            24: /*
        !            25:  * Call generates code for calls to
        !            26:  * user defined procedures and functions
        !            27:  * and is called by proc and funccod.
        !            28:  * P is the result of the lookup
        !            29:  * of the procedure/function symbol,
        !            30:  * and porf is PROC or FUNC.
        !            31:  * Psbn is the block number of p.
        !            32:  *
        !            33:  *     the idea here is that regular scalar functions are just called,
        !            34:  *     while structure functions and formal functions have their results
        !            35:  *     stored in a temporary after the call.
        !            36:  *     structure functions do this because they return pointers
        !            37:  *     to static results, so we copy the static
        !            38:  *     and return a pointer to the copy.
        !            39:  *     formal functions do this because we have to save the result
        !            40:  *     around a call to the runtime routine which restores the display,
        !            41:  *     so we can't just leave the result lying around in registers.
        !            42:  *     formal calls save the address of the descriptor in a local
        !            43:  *     temporary, so it can be addressed for the call which restores
        !            44:  *     the display (FRTN).
        !            45:  *     calls to formal parameters pass the formal as a hidden argument 
        !            46:  *     to a special entry point for the formal call.
        !            47:  *     [this is somewhat dependent on the way arguments are addressed.]
        !            48:  *     so PROCs and scalar FUNCs look like
        !            49:  *             p(...args...)
        !            50:  *     structure FUNCs look like
        !            51:  *             (temp = p(...args...),&temp)
        !            52:  *     formal FPROCs look like
        !            53:  *             ( t=p,( t -> entryaddr )(...args...,t,s),FRTN(t,s))
        !            54:  *     formal scalar FFUNCs look like
        !            55:  *             ( t=p,temp=( t -> entryaddr )(...args...,t,s),FRTN(t,s),temp)
        !            56:  *     formal structure FFUNCs look like
        !            57:  *             (t=p,temp = ( t -> entryaddr )(...args...,t,s),FRTN(t,s),&temp)
        !            58:  */
        !            59: struct nl *
        !            60: call(p, argv_node, porf, psbn)
        !            61:        struct nl *p;
        !            62:        struct tnode    *argv_node;     /* list node */
        !            63:        int porf, psbn;
        !            64: {
        !            65:        register struct nl *p1, *q, *p2;
        !            66:        register struct nl *ptype, *ctype;
        !            67:        struct tnode *rnode;
        !            68:        int i, j, d;
        !            69:        bool chk = TRUE;
        !            70:        struct nl       *savedispnp;    /* temporary to hold saved display */
        !            71: #      ifdef PC
        !            72:            int         p_type_class = classify( p -> type );
        !            73:            long        p_type_p2type = p2type( p -> type );
        !            74:            bool        noarguments;
        !            75:                /*
        !            76:                 *      these get used if temporaries and structures are used
        !            77:                 */
        !            78:            struct nl   *tempnlp;
        !            79:            long        temptype;       /* type of the temporary */
        !            80:            long        p_type_width;
        !            81:            long        p_type_align;
        !            82:            char        extname[ BUFSIZ ];
        !            83:            struct nl   *tempdescrp;
        !            84: #      endif PC
        !            85: 
        !            86:          if (p->class == FFUNC || p->class == FPROC) {
        !            87:            /*
        !            88:             * allocate space to save the display for formal calls
        !            89:             */
        !            90:            savedispnp = tmpalloc( (long) sizeof display , NLNIL , NOREG );
        !            91:        }
        !            92: #      ifdef OBJ
        !            93:            if (p->class == FFUNC || p->class == FPROC) {
        !            94:                (void) put(2, O_LV | cbn << 8 + INDX ,
        !            95:                        (int) savedispnp -> value[ NL_OFFS ] );
        !            96:                (void) put(2, PTR_RV | psbn << 8+INDX, (int)p->value[NL_OFFS]);
        !            97:            }
        !            98:            if (porf == FUNC) {
        !            99:                    /*
        !           100:                     * Push some space
        !           101:                     * for the function return type
        !           102:                     */
        !           103:                    (void) put(2, O_PUSH,
        !           104:                        -roundup(lwidth(p->type), (long) A_STACK));
        !           105:            }
        !           106: #      endif OBJ
        !           107: #      ifdef PC
        !           108:                /*
        !           109:                 *      if this is a formal call,
        !           110:                 *      stash the address of the descriptor
        !           111:                 *      in a temporary so we can find it
        !           112:                 *      after the FCALL for the call to FRTN
        !           113:                 */
        !           114:            if ( p -> class == FFUNC || p -> class == FPROC ) {
        !           115:                tempdescrp = tmpalloc((long) (sizeof( struct formalrtn *)),
        !           116:                                        NLNIL, REGOK );
        !           117:                putRV((char *) 0 , cbn , tempdescrp -> value[ NL_OFFS ] ,
        !           118:                        tempdescrp -> extra_flags , PCCTM_PTR|PCCT_STRTY );
        !           119:                putRV((char *) 0 , psbn , p -> value[ NL_OFFS ] ,
        !           120:                        p -> extra_flags , PCCTM_PTR|PCCT_STRTY );
        !           121:                putop( PCC_ASSIGN , PCCTM_PTR | PCCT_STRTY );
        !           122:            }
        !           123:                /*
        !           124:                 *      if we have to store a temporary,
        !           125:                 *      temptype will be its type,
        !           126:                 *      otherwise, it's PCCT_UNDEF.
        !           127:                 */
        !           128:            temptype = PCCT_UNDEF;
        !           129:            if ( porf == FUNC ) {
        !           130:                p_type_width = width( p -> type );
        !           131:                switch( p_type_class ) {
        !           132:                    case TSTR:
        !           133:                    case TSET:
        !           134:                    case TREC:
        !           135:                    case TFILE:
        !           136:                    case TARY:
        !           137:                        temptype = PCCT_STRTY;
        !           138:                        p_type_align = align( p -> type );
        !           139:                        break;
        !           140:                    default:
        !           141:                        if ( p -> class == FFUNC ) {
        !           142:                            temptype = p2type( p -> type );
        !           143:                        }
        !           144:                        break;
        !           145:                }
        !           146:                if ( temptype != PCCT_UNDEF ) {
        !           147:                    tempnlp = tmpalloc(p_type_width, p -> type, NOREG);
        !           148:                        /*
        !           149:                         *      temp
        !           150:                         *      for (temp = ...
        !           151:                         */
        !           152:                    putRV((char *) 0 , cbn , tempnlp -> value[ NL_OFFS ] ,
        !           153:                            tempnlp -> extra_flags , (int) temptype );
        !           154:                }
        !           155:            }
        !           156:            switch ( p -> class ) {
        !           157:                case FUNC:
        !           158:                case PROC:
        !           159:                        /*
        !           160:                         *      ... p( ...
        !           161:                         */
        !           162:                    sextname( extname , p -> symbol , BLOCKNO(p -> nl_block) );
        !           163:                    putleaf( PCC_ICON , 0 , 0 , p2type( p ) , extname );
        !           164:                    break;
        !           165:                case FFUNC:
        !           166:                case FPROC:
        !           167: 
        !           168:                            /*
        !           169:                             *  ... ( t -> entryaddr )( ...
        !           170:                             */
        !           171:                            /*  the descriptor */
        !           172:                        putRV((char *) 0 , cbn , tempdescrp -> value[ NL_OFFS ] ,
        !           173:                                tempdescrp -> extra_flags , PCCTM_PTR | PCCT_STRTY );
        !           174:                            /*  the entry address within the descriptor */
        !           175:                        if ( FENTRYOFFSET != 0 ) {
        !           176:                            putleaf( PCC_ICON , FENTRYOFFSET , 0 , PCCT_INT , 
        !           177:                                                (char *) 0 );
        !           178:                            putop( PCC_PLUS , 
        !           179:                                PCCM_ADDTYPE(
        !           180:                                    PCCM_ADDTYPE( PCCM_ADDTYPE( p2type( p ) , PCCTM_FTN ) ,
        !           181:                                            PCCTM_PTR ) ,
        !           182:                                        PCCTM_PTR ) );
        !           183:                        }
        !           184:                            /*
        !           185:                             *  indirect to fetch the formal entry address
        !           186:                             *  with the result type of the routine.
        !           187:                             */
        !           188:                        if (p -> class == FFUNC) {
        !           189:                            putop( PCCOM_UNARY PCC_MUL ,
        !           190:                                PCCM_ADDTYPE(PCCM_ADDTYPE(p2type(p -> type), PCCTM_FTN),
        !           191:                                        PCCTM_PTR));
        !           192:                        } else {
        !           193:                                /* procedures are int returning functions */
        !           194:                            putop( PCCOM_UNARY PCC_MUL ,
        !           195:                                PCCM_ADDTYPE(PCCM_ADDTYPE(PCCT_INT, PCCTM_FTN), PCCTM_PTR));
        !           196:                        }
        !           197:                        break;
        !           198:                default:
        !           199:                        panic("call class");
        !           200:            }
        !           201:            noarguments = TRUE;
        !           202: #      endif PC
        !           203:        /*
        !           204:         * Loop and process each of
        !           205:         * arguments to the proc/func.
        !           206:         *      ... ( ... args ... ) ...
        !           207:         */
        !           208:        ptype = NIL;
        !           209:        for (p1 = plist(p); p1 != NLNIL; p1 = p1->chain) {
        !           210:            if (argv_node == TR_NIL) {
        !           211:                    error("Not enough arguments to %s", p->symbol);
        !           212:                    return (NLNIL);
        !           213:            }
        !           214:            switch (p1->class) {
        !           215:                case REF:
        !           216:                        /*
        !           217:                         * Var parameter
        !           218:                         */
        !           219:                        rnode = argv_node->list_node.list;
        !           220:                        if (rnode != TR_NIL && rnode->tag != T_VAR) {
        !           221:                                error("Expression given (variable required) for var parameter %s of %s", p1->symbol, p->symbol);
        !           222:                                chk = FALSE;
        !           223:                                break;
        !           224:                        }
        !           225:                        q = lvalue( argv_node->list_node.list,
        !           226:                                        MOD | ASGN , LREQ );
        !           227:                        if (q == NIL) {
        !           228:                                chk = FALSE;
        !           229:                                break;
        !           230:                        }
        !           231:                        p2 = p1->type;
        !           232:                        if (p2 == NLNIL || p2->chain == NLNIL || p2->chain->class != CRANGE) {
        !           233:                            if (q != p2) {
        !           234:                                error("Parameter type not identical to type of var parameter %s of %s", p1->symbol, p->symbol);
        !           235:                                chk = FALSE;
        !           236:                            }
        !           237:                            break;
        !           238:                        } else {
        !           239:                            /* conformant array */
        !           240:                            if (p1 == ptype) {
        !           241:                                if (q != ctype) {
        !           242:                                    error("Conformant array parameters in the same specification must be the same type.");
        !           243:                                    goto conf_err;
        !           244:                                }
        !           245:                            } else {
        !           246:                                if (classify(q) != TARY && classify(q) != TSTR) {
        !           247:                                    error("Array type required for var parameter %s of %s",p1->symbol,p->symbol);
        !           248:                                    goto conf_err;
        !           249:                                }
        !           250:                                /* check base type of array */
        !           251:                                if (p2->type != q->type) {
        !           252:                                    error("Base type of array not identical to that of conformant array parameter %s of %s", p1->symbol, p->symbol);
        !           253:                                    goto conf_err;
        !           254:                                }
        !           255:                                if (p2->value[0] != q->value[0]) {
        !           256:                                    error("Subscript number mismatch on conformant array parameter %s of %s", p1->symbol, p->symbol);
        !           257:                                    /* Don't process array bounds & width */
        !           258: conf_err:                          if (p1->chain->type->class == CRANGE) {
        !           259:                                        d = p1->value[0];
        !           260:                                        for (i = 1; i <= d; i++) {
        !           261:                                            /* for each subscript, pass by
        !           262:                                             * bounds and width
        !           263:                                             */
        !           264:                                            p1 = p1->chain->chain->chain;
        !           265:                                        }
        !           266:                                    }
        !           267:                                    ptype = ctype = NLNIL;
        !           268:                                    chk = FALSE;
        !           269:                                    break;
        !           270:                                }
        !           271:                                /*
        !           272:                                 * Save array type for all parameters with same
        !           273:                                 * specification.
        !           274:                                 */
        !           275:                                ctype = q;
        !           276:                                ptype = p2;
        !           277:                                /*
        !           278:                                 * If at end of conformant array list,
        !           279:                                 * get bounds.
        !           280:                                 */
        !           281:                                if (p1->chain->type->class == CRANGE) {
        !           282:                                    /* check each subscript, put on stack */
        !           283:                                    d = ptype->value[0];
        !           284:                                    q = ctype;
        !           285:                                    for (i = 1; i <= d; i++) {
        !           286:                                        p1 = p1->chain;
        !           287:                                        q = q->chain;
        !           288:                                        if (incompat(q, p1->type, TR_NIL)){
        !           289:                                            error("Subscript type not conformable with parameter %s of %s", p1->symbol, p->symbol);
        !           290:                                            chk = FALSE;
        !           291:                                            break;
        !           292:                                        }
        !           293:                                        /* Put lower and upper bound & width */
        !           294: #                                      ifdef OBJ
        !           295:                                        if (q->type->class == CRANGE) {
        !           296:                                            putcbnds(q->type);
        !           297:                                        } else {
        !           298:                                            put(2, width(p1->type) <= 2 ? O_CON2
        !           299:                                                : O_CON4, q->range[0]);
        !           300:                                            put(2, width(p1->type) <= 2 ? O_CON2
        !           301:                                                : O_CON4, q->range[1]);
        !           302:                                            put(2, width(p1->type) <= 2 ? O_CON2
        !           303:                                                : O_CON4, aryconst(ctype,i));
        !           304:                                        }
        !           305: #                                      endif OBJ
        !           306: #                                      ifdef PC
        !           307:                                        if (q->type->class == CRANGE) {
        !           308:                                            for (j = 1; j <= 3; j++) {
        !           309:                                                p2 = p->nptr[j];
        !           310:                                                putRV(p2->symbol, (p2->nl_block
        !           311:                                                    & 037), p2->value[0],
        !           312:                                                    p2->extra_flags,p2type(p2));
        !           313:                                                putop(PCC_CM, PCCT_INT);
        !           314:                                            }
        !           315:                                        } else {
        !           316:                                            putleaf(PCC_ICON, q->range[0], 0,PCCT_INT,0);
        !           317:                                            putop( PCC_CM , PCCT_INT );
        !           318:                                            putleaf(PCC_ICON, q->range[1], 0,PCCT_INT,0);
        !           319:                                            putop( PCC_CM , PCCT_INT );
        !           320:                                            putleaf(PCC_ICON,aryconst(ctype,i),0,PCCT_INT,0);
        !           321:                                            putop( PCC_CM , PCCT_INT );
        !           322:                                        }
        !           323: #                                      endif PC
        !           324:                                        p1 = p1->chain->chain;
        !           325:                                    }
        !           326:                                }
        !           327:                            }
        !           328:                        }
        !           329:                        break;
        !           330:                case VAR:
        !           331:                        /*
        !           332:                         * Value parameter
        !           333:                         */
        !           334: #                      ifdef OBJ
        !           335:                            q = rvalue(argv_node->list_node.list,
        !           336:                                        p1->type , RREQ );
        !           337: #                      endif OBJ
        !           338: #                      ifdef PC
        !           339:                                /*
        !           340:                                 * structure arguments require lvalues,
        !           341:                                 * scalars use rvalue.
        !           342:                                 */
        !           343:                            switch( classify( p1 -> type ) ) {
        !           344:                                case TFILE:
        !           345:                                case TARY:
        !           346:                                case TREC:
        !           347:                                case TSET:
        !           348:                                case TSTR:
        !           349:                                q = stkrval(argv_node->list_node.list,
        !           350:                                                p1 -> type , (long) LREQ );
        !           351:                                    break;
        !           352:                                case TINT:
        !           353:                                case TSCAL:
        !           354:                                case TBOOL:
        !           355:                                case TCHAR:
        !           356:                                    precheck( p1 -> type , "_RANG4" , "_RSNG4" );
        !           357:                                q = stkrval(argv_node->list_node.list,
        !           358:                                                p1 -> type , (long) RREQ );
        !           359:                                    postcheck(p1 -> type, nl+T4INT);
        !           360:                                    break;
        !           361:                                case TDOUBLE:
        !           362:                                q = stkrval(argv_node->list_node.list,
        !           363:                                                p1 -> type , (long) RREQ );
        !           364:                                    sconv(p2type(q), PCCT_DOUBLE);
        !           365:                                    break;
        !           366:                                default:
        !           367:                                    q = rvalue(argv_node->list_node.list,
        !           368:                                                p1 -> type , RREQ );
        !           369:                                    break;
        !           370:                            }
        !           371: #                      endif PC
        !           372:                        if (q == NIL) {
        !           373:                                chk = FALSE;
        !           374:                                break;
        !           375:                        }
        !           376:                        if (incompat(q, p1->type,
        !           377:                                argv_node->list_node.list)) {
        !           378:                                cerror("Expression type clashed with type of value parameter %s of %s", p1->symbol, p->symbol);
        !           379:                                chk = FALSE;
        !           380:                                break;
        !           381:                        }
        !           382: #                      ifdef OBJ
        !           383:                            if (isa(p1->type, "bcsi"))
        !           384:                                    rangechk(p1->type, q);
        !           385:                            if (q->class != STR)
        !           386:                                    convert(q, p1->type);
        !           387: #                      endif OBJ
        !           388: #                      ifdef PC
        !           389:                            switch( classify( p1 -> type ) ) {
        !           390:                                case TFILE:
        !           391:                                case TARY:
        !           392:                                case TREC:
        !           393:                                case TSET:
        !           394:                                case TSTR:
        !           395:                                        putstrop( PCC_STARG
        !           396:                                            , p2type( p1 -> type )
        !           397:                                            , (int) lwidth( p1 -> type )
        !           398:                                            , align( p1 -> type ) );
        !           399:                            }
        !           400: #                      endif PC
        !           401:                        break;
        !           402:                case FFUNC:
        !           403:                        /*
        !           404:                         * function parameter
        !           405:                         */
        !           406:                        q = flvalue(argv_node->list_node.list, p1 );
        !           407:                        /*chk = (chk && fcompat(q, p1));*/
        !           408:                        if ((chk) && (fcompat(q, p1)))
        !           409:                            chk = TRUE;
        !           410:                        else
        !           411:                            chk = FALSE;
        !           412:                        break;
        !           413:                case FPROC:
        !           414:                        /*
        !           415:                         * procedure parameter
        !           416:                         */
        !           417:                        q = flvalue(argv_node->list_node.list, p1 );
        !           418:                        /* chk = (chk && fcompat(q, p1)); */
        !           419:                        if ((chk) && (fcompat(q, p1)))
        !           420:                            chk = TRUE;
        !           421:                        else chk = FALSE;
        !           422:                        break;
        !           423:                default:
        !           424:                        panic("call");
        !           425:            }
        !           426: #          ifdef PC
        !           427:                    /*
        !           428:                     *  if this is the nth (>1) argument,
        !           429:                     *  hang it on the left linear list of arguments
        !           430:                     */
        !           431:                if ( noarguments ) {
        !           432:                        noarguments = FALSE;
        !           433:                } else {
        !           434:                        putop( PCC_CM , PCCT_INT );
        !           435:                }
        !           436: #          endif PC
        !           437:            argv_node = argv_node->list_node.next;
        !           438:        }
        !           439:        if (argv_node != TR_NIL) {
        !           440:                error("Too many arguments to %s", p->symbol);
        !           441:                rvlist(argv_node);
        !           442:                return (NLNIL);
        !           443:        }
        !           444:        if (chk == FALSE)
        !           445:                return NLNIL;
        !           446: #      ifdef OBJ
        !           447:            if ( p -> class == FFUNC || p -> class == FPROC ) {
        !           448:                (void) put(2, PTR_RV | psbn << 8+INDX, (int)p->value[NL_OFFS]);
        !           449:                (void) put(2, O_LV | cbn << 8 + INDX ,
        !           450:                        (int) savedispnp -> value[ NL_OFFS ] );
        !           451:                (void) put(1, O_FCALL);
        !           452:                (void) put(2, O_FRTN, roundup(width(p->type), (long) A_STACK));
        !           453:            } else {
        !           454:                (void) put(2, O_CALL | psbn << 8, (long)p->value[NL_ENTLOC]);
        !           455:            }
        !           456: #      endif OBJ
        !           457: #      ifdef PC
        !           458:                /*
        !           459:                 *      for formal calls: add the hidden argument
        !           460:                 *      which is the formal struct describing the
        !           461:                 *      environment of the routine.
        !           462:                 *      and the argument which is the address of the
        !           463:                 *      space into which to save the display.
        !           464:                 */
        !           465:            if ( p -> class == FFUNC || p -> class == FPROC ) {
        !           466:                putRV((char *) 0 , cbn , tempdescrp -> value[ NL_OFFS ] ,
        !           467:                        tempdescrp -> extra_flags , PCCTM_PTR|PCCT_STRTY );
        !           468:                if ( !noarguments ) {
        !           469:                    putop( PCC_CM , PCCT_INT );
        !           470:                }
        !           471:                noarguments = FALSE;
        !           472:                putLV((char *) 0 , cbn , savedispnp -> value[ NL_OFFS ] ,
        !           473:                        savedispnp -> extra_flags , PCCTM_PTR | PCCT_STRTY );
        !           474:                putop( PCC_CM , PCCT_INT );
        !           475:            }
        !           476:                /*
        !           477:                 *      do the actual call:
        !           478:                 *          either      ... p( ... ) ...
        !           479:                 *          or          ... ( t -> entryaddr )( ... ) ...
        !           480:                 *      and maybe an assignment.
        !           481:                 */
        !           482:            if ( porf == FUNC ) {
        !           483:                switch ( p_type_class ) {
        !           484:                    case TBOOL:
        !           485:                    case TCHAR:
        !           486:                    case TINT:
        !           487:                    case TSCAL:
        !           488:                    case TDOUBLE:
        !           489:                    case TPTR:
        !           490:                        putop( ( noarguments ? PCCOM_UNARY PCC_CALL : PCC_CALL ) ,
        !           491:                                (int) p_type_p2type );
        !           492:                        if ( p -> class == FFUNC ) {
        !           493:                            putop( PCC_ASSIGN , (int) p_type_p2type );
        !           494:                        }
        !           495:                        break;
        !           496:                    default:
        !           497:                        putstrop( ( noarguments ? PCCOM_UNARY PCC_STCALL : PCC_STCALL ),
        !           498:                                (int) PCCM_ADDTYPE( p_type_p2type , PCCTM_PTR ) ,
        !           499:                                (int) p_type_width ,(int) p_type_align );
        !           500:                        putstrop(PCC_STASG, (int) PCCM_ADDTYPE(p_type_p2type, PCCTM_PTR),
        !           501:                                (int) lwidth(p -> type), align(p -> type));
        !           502:                        break;
        !           503:                }
        !           504:            } else {
        !           505:                putop( ( noarguments ? PCCOM_UNARY PCC_CALL : PCC_CALL ) , PCCT_INT );
        !           506:            }
        !           507:                /*
        !           508:                 *      ( t=p , ... , FRTN( t ) ...
        !           509:                 */
        !           510:            if ( p -> class == FFUNC || p -> class == FPROC ) {
        !           511:                putop( PCC_COMOP , PCCT_INT );
        !           512:                putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) ,
        !           513:                        "_FRTN" );
        !           514:                putRV((char *) 0 , cbn , tempdescrp -> value[ NL_OFFS ] ,
        !           515:                        tempdescrp -> extra_flags , PCCTM_PTR | PCCT_STRTY );
        !           516:                putLV((char *) 0 , cbn , savedispnp -> value[ NL_OFFS ] ,
        !           517:                        savedispnp -> extra_flags , PCCTM_PTR | PCCT_STRTY );
        !           518:                putop( PCC_CM , PCCT_INT );
        !           519:                putop( PCC_CALL , PCCT_INT );
        !           520:                putop( PCC_COMOP , PCCT_INT );
        !           521:            }
        !           522:                /*
        !           523:                 *      if required:
        !           524:                 *      either  ... , temp )
        !           525:                 *      or      ... , &temp )
        !           526:                 */
        !           527:            if ( porf == FUNC && temptype != PCCT_UNDEF ) {
        !           528:                if ( temptype != PCCT_STRTY ) {
        !           529:                    putRV((char *) 0 , cbn , tempnlp -> value[ NL_OFFS ] ,
        !           530:                            tempnlp -> extra_flags , (int) p_type_p2type );
        !           531:                } else {
        !           532:                    putLV((char *) 0 , cbn , tempnlp -> value[ NL_OFFS ] ,
        !           533:                            tempnlp -> extra_flags , (int) p_type_p2type );
        !           534:                }
        !           535:                putop( PCC_COMOP , PCCT_INT );
        !           536:            }
        !           537:            if ( porf == PROC ) {
        !           538:                putdot( filename , line );
        !           539:            }
        !           540: #      endif PC
        !           541:        return (p->type);
        !           542: }
        !           543: 
        !           544: rvlist(al)
        !           545:        register struct tnode *al;
        !           546: {
        !           547: 
        !           548:        for (; al != TR_NIL; al = al->list_node.next)
        !           549:                (void) rvalue( al->list_node.list, NLNIL , RREQ );
        !           550: }
        !           551: 
        !           552:     /*
        !           553:      * check that two function/procedure namelist entries are compatible
        !           554:      */
        !           555: bool
        !           556: fcompat( formal , actual )
        !           557:     struct nl  *formal;
        !           558:     struct nl  *actual;
        !           559: {
        !           560:     register struct nl *f_chain;
        !           561:     register struct nl *a_chain;
        !           562:     extern struct nl   *plist();
        !           563:     bool compat = TRUE;
        !           564: 
        !           565:     if ( formal == NLNIL || actual == NLNIL ) {
        !           566:        return FALSE;
        !           567:     }
        !           568:     for (a_chain = plist(actual), f_chain = plist(formal);
        !           569:          f_chain != NLNIL;
        !           570:         f_chain = f_chain->chain, a_chain = a_chain->chain) {
        !           571:        if (a_chain == NIL) {
        !           572:            error("%s %s declared on line %d has more arguments than",
        !           573:                parnam(formal->class), formal->symbol,
        !           574:                (char *) linenum(formal));
        !           575:            cerror("%s %s declared on line %d",
        !           576:                parnam(actual->class), actual->symbol,
        !           577:                (char *) linenum(actual));
        !           578:            return FALSE;
        !           579:        }
        !           580:        if ( a_chain -> class != f_chain -> class ) {
        !           581:            error("%s parameter %s of %s declared on line %d is not identical",
        !           582:                parnam(f_chain->class), f_chain->symbol,
        !           583:                formal->symbol, (char *) linenum(formal));
        !           584:            cerror("with %s parameter %s of %s declared on line %d",
        !           585:                parnam(a_chain->class), a_chain->symbol,
        !           586:                actual->symbol, (char *) linenum(actual));
        !           587:            compat = FALSE;
        !           588:        } else if (a_chain->class == FFUNC || a_chain->class == FPROC) {
        !           589:            /*compat = (compat && fcompat(f_chain, a_chain));*/
        !           590:            if ((compat) && (fcompat(f_chain, a_chain)))
        !           591:                compat = TRUE;
        !           592:            else compat = FALSE;
        !           593:        }
        !           594:        if ((a_chain->class != FPROC && f_chain->class != FPROC) &&
        !           595:            (a_chain->type != f_chain->type)) {
        !           596:            error("Type of %s parameter %s of %s declared on line %d is not identical",
        !           597:                parnam(f_chain->class), f_chain->symbol,
        !           598:                formal->symbol, (char *) linenum(formal));
        !           599:            cerror("to type of %s parameter %s of %s declared on line %d",
        !           600:                parnam(a_chain->class), a_chain->symbol,
        !           601:                actual->symbol, (char *) linenum(actual));
        !           602:            compat = FALSE;
        !           603:        }
        !           604:     }
        !           605:     if (a_chain != NIL) {
        !           606:        error("%s %s declared on line %d has fewer arguments than",
        !           607:            parnam(formal->class), formal->symbol,
        !           608:            (char *) linenum(formal));
        !           609:        cerror("%s %s declared on line %d",
        !           610:            parnam(actual->class), actual->symbol,
        !           611:            (char *) linenum(actual));
        !           612:        return FALSE;
        !           613:     }
        !           614:     return compat;
        !           615: }
        !           616: 
        !           617: char *
        !           618: parnam(nltype)
        !           619:     int nltype;
        !           620: {
        !           621:     switch(nltype) {
        !           622:        case REF:
        !           623:            return "var";
        !           624:        case VAR:
        !           625:            return "value";
        !           626:        case FUNC:
        !           627:        case FFUNC:
        !           628:            return "function";
        !           629:        case PROC:
        !           630:        case FPROC:
        !           631:            return "procedure";
        !           632:        default:
        !           633:            return "SNARK";
        !           634:     }
        !           635: }
        !           636: 
        !           637: struct nl *plist(p)
        !           638:     struct nl *p;
        !           639: {
        !           640:     switch (p->class) {
        !           641:        case FFUNC:
        !           642:        case FPROC:
        !           643:            return p->ptr[ NL_FCHAIN ];
        !           644:        case PROC:
        !           645:        case FUNC:
        !           646:            return p->chain;
        !           647:        default:
        !           648:            {
        !           649:                panic("plist");
        !           650:                return(NLNIL); /* this is here only so lint won't complain
        !           651:                                  panic actually aborts */
        !           652:            }
        !           653: 
        !           654:     }
        !           655: }
        !           656: 
        !           657: linenum(p)
        !           658:     struct nl *p;
        !           659: {
        !           660:     if (p->class == FUNC)
        !           661:        return p->ptr[NL_FVAR]->value[NL_LINENO];
        !           662:     return p->value[NL_LINENO];
        !           663: }

unix.superglobalmegacorp.com

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