Annotation of 43BSDReno/pgrm/pascal/src/call.c, revision 1.1.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.