Annotation of 40BSD/cmd/pc0/pcfunc.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1979 Regents of the University of California */
                      2: 
                      3: static char sccsid[] = "@(#)pcfunc.c 1.3 10/19/80";
                      4: 
                      5: #include "whoami.h"
                      6: #ifdef PC
                      7:     /*
                      8:      * and to the end of the file
                      9:      */
                     10: #include "0.h"
                     11: #include "tree.h"
                     12: #include "opcode.h"
                     13: #include       "pc.h"
                     14: #include       "pcops.h"
                     15: 
                     16: /*
                     17:  * Funccod generates code for
                     18:  * built in function calls and calls
                     19:  * call to generate calls to user
                     20:  * defined functions and procedures.
                     21:  */
                     22: pcfunccod( r )
                     23:        int      *r;
                     24: {
                     25:        struct nl *p;
                     26:        register struct nl *p1;
                     27:        register int *al;
                     28:        register op;
                     29:        int argc, *argv;
                     30:        int tr[2], tr2[4];
                     31:        char            *funcname;
                     32:        long            tempoff;
                     33:        long            temptype;
                     34:        struct nl       *rettype;
                     35: 
                     36:        /*
                     37:         * Verify that the given name
                     38:         * is defined and the name of
                     39:         * a function.
                     40:         */
                     41:        p = lookup(r[2]);
                     42:        if (p == NIL) {
                     43:                rvlist(r[3]);
                     44:                return (NIL);
                     45:        }
                     46:        if (p->class != FUNC && p->class != FFUNC) {
                     47:                error("%s is not a function", p->symbol);
                     48:                rvlist(r[3]);
                     49:                return (NIL);
                     50:        }
                     51:        argv = r[3];
                     52:        /*
                     53:         * Call handles user defined
                     54:         * procedures and functions
                     55:         */
                     56:        if (bn != 0)
                     57:                return (call(p, argv, FUNC, bn));
                     58:        /*
                     59:         * Count the arguments
                     60:         */
                     61:        argc = 0;
                     62:        for (al = argv; al != NIL; al = al[2])
                     63:                argc++;
                     64:        /*
                     65:         * Built-in functions have
                     66:         * their interpreter opcode
                     67:         * associated with them.
                     68:         */
                     69:        op = p->value[0] &~ NSTAND;
                     70:        if (opt('s') && (p->value[0] & NSTAND)) {
                     71:                standard();
                     72:                error("%s is a nonstandard function", p->symbol);
                     73:        }
                     74:        if ( op == O_ARGC ) {
                     75:            putleaf( P2NAME , 0 , 0 , P2INT , "__argc" );
                     76:            return nl + T4INT;
                     77:        }
                     78:        switch (op) {
                     79:                /*
                     80:                 * Parameterless functions
                     81:                 */
                     82:                case O_CLCK:
                     83:                        funcname = "_CLCK";
                     84:                        goto noargs;
                     85:                case O_SCLCK:
                     86:                        funcname = "_SCLCK";
                     87:                        goto noargs;
                     88: noargs:
                     89:                        if (argc != 0) {
                     90:                                error("%s takes no arguments", p->symbol);
                     91:                                rvlist(argv);
                     92:                                return (NIL);
                     93:                        }
                     94:                        putleaf( P2ICON , 0 , 0
                     95:                                , ADDTYPE( P2FTN | P2INT , P2PTR )
                     96:                                , funcname );
                     97:                        putop( P2UNARY P2CALL , P2INT );
                     98:                        return (nl+T4INT);
                     99:                case O_WCLCK:
                    100:                        if (argc != 0) {
                    101:                                error("%s takes no arguments", p->symbol);
                    102:                                rvlist(argv);
                    103:                                return (NIL);
                    104:                        }
                    105:                        putleaf( P2ICON , 0 , 0
                    106:                                , ADDTYPE( P2FTN | P2INT , P2PTR )
                    107:                                , "_time" );
                    108:                        putleaf( P2ICON , 0 , 0 , P2INT , 0 );
                    109:                        putop( P2CALL , P2INT );
                    110:                        return (nl+T4INT);
                    111:                case O_EOF:
                    112:                case O_EOLN:
                    113:                        if (argc == 0) {
                    114:                                argv = tr;
                    115:                                tr[1] = tr2;
                    116:                                tr2[0] = T_VAR;
                    117:                                tr2[2] = input->symbol;
                    118:                                tr2[1] = tr2[3] = NIL;
                    119:                                argc = 1;
                    120:                        } else if (argc != 1) {
                    121:                                error("%s takes either zero or one argument", p->symbol);
                    122:                                rvlist(argv);
                    123:                                return (NIL);
                    124:                        }
                    125:                }
                    126:        /*
                    127:         * All other functions take
                    128:         * exactly one argument.
                    129:         */
                    130:        if (argc != 1) {
                    131:                error("%s takes exactly one argument", p->symbol);
                    132:                rvlist(argv);
                    133:                return (NIL);
                    134:        }
                    135:        /*
                    136:         * find out the type of the argument
                    137:         */
                    138:        codeoff();
                    139:        p1 = stkrval((int *) argv[1], NLNIL , RREQ );
                    140:        codeon();
                    141:        if (p1 == NIL)
                    142:                return (NIL);
                    143:        /*
                    144:         * figure out the return type and the funtion name
                    145:         */
                    146:        switch (op) {
                    147:            case O_EXP:
                    148:                    funcname = "_exp";
                    149:                    goto mathfunc;
                    150:            case O_SIN:
                    151:                    funcname = "_sin";
                    152:                    goto mathfunc;
                    153:            case O_COS:
                    154:                    funcname = "_cos";
                    155:                    goto mathfunc;
                    156:            case O_ATAN:
                    157:                    funcname = "_atan";
                    158:                    goto mathfunc;
                    159:            case O_LN:
                    160:                    funcname = opt('t') ? "_LN" : "_log";
                    161:                    goto mathfunc;
                    162:            case O_SQRT:
                    163:                    funcname = opt('t') ? "_SQRT" : "_sqrt";
                    164:                    goto mathfunc;
                    165:            case O_RANDOM:
                    166:                    funcname = "_RANDOM";
                    167:                    goto mathfunc;
                    168: mathfunc:
                    169:                    if (isnta(p1, "id")) {
                    170:                            error("%s's argument must be integer or real, not %s", p->symbol, nameof(p1));
                    171:                            return (NIL);
                    172:                    }
                    173:                    putleaf( P2ICON , 0 , 0
                    174:                            , ADDTYPE( P2FTN | P2DOUBLE , P2PTR ) , funcname );
                    175:                    p1 = stkrval( (int *) argv[1] , NLNIL , RREQ );
                    176:                    if ( isa( p1 , "i" ) ) {
                    177:                        putop( P2SCONV , P2DOUBLE );
                    178:                    }
                    179:                    putop( P2CALL , P2DOUBLE );
                    180:                    return nl + TDOUBLE;
                    181:            case O_EXPO:
                    182:                    if (isnta( p1 , "id" ) ) {
                    183:                            error("%s's argument must be integer or real, not %s", p->symbol, nameof(p1));
                    184:                            return NIL;
                    185:                    }
                    186:                    putleaf( P2ICON , 0 , 0
                    187:                            , ADDTYPE( P2FTN | P2INT , P2PTR ) , "_EXPO" );
                    188:                    p1 = stkrval( (int *) argv[1] , NLNIL , RREQ );
                    189:                    if ( isa( p1 , "i" ) ) {
                    190:                        putop( P2SCONV , P2DOUBLE );
                    191:                    }
                    192:                    putop( P2CALL , P2INT );
                    193:                    return ( nl + T4INT );
                    194:            case O_UNDEF:
                    195:                    if ( isnta( p1 , "id" ) ) {
                    196:                            error("%s's argument must be integer or real, not %s", p->symbol, nameof(p1));
                    197:                            return NIL;
                    198:                    }
                    199:                    p1 = stkrval( (int *) argv[1] , NLNIL , RREQ );
                    200:                    putleaf( P2ICON , 0 , 0 , P2INT , 0 );
                    201:                    putop( P2COMOP , P2INT );
                    202:                    return ( nl + TBOOL );
                    203:            case O_SEED:
                    204:                    if (isnta(p1, "i")) {
                    205:                            error("seed's argument must be an integer, not %s", nameof(p1));
                    206:                            return (NIL);
                    207:                    }
                    208:                    putleaf( P2ICON , 0 , 0
                    209:                            , ADDTYPE( P2FTN | P2INT , P2PTR ) , "_SEED" );
                    210:                    p1 = stkrval( (int *) argv[1] , NLNIL , RREQ );
                    211:                    putop( P2CALL , P2INT );
                    212:                    return nl + T4INT;
                    213:            case O_ROUND:
                    214:            case O_TRUNC:
                    215:                    if ( isnta( p1 , "d" ) ) {
                    216:                            error("%s's argument must be a real, not %s", p->symbol, nameof(p1));
                    217:                            return (NIL);
                    218:                    }
                    219:                    putleaf( P2ICON , 0 , 0
                    220:                            , ADDTYPE( P2FTN | P2INT , P2PTR )
                    221:                            , op == O_ROUND ? "_ROUND" : "_TRUNC" );
                    222:                    p1 = stkrval( (int *) argv[1] , NLNIL , RREQ );
                    223:                    putop( P2CALL , P2INT );
                    224:                    return nl + T4INT;
                    225:            case O_ABS2:
                    226:                        if ( isa( p1 , "d" ) ) {
                    227:                            putleaf( P2ICON , 0 , 0
                    228:                                , ADDTYPE( P2FTN | P2DOUBLE , P2PTR )
                    229:                                , "_fabs" );
                    230:                            p1 = stkrval( (int *) argv[1] , NLNIL , RREQ );
                    231:                            putop( P2CALL , P2DOUBLE );
                    232:                            return nl + TDOUBLE;
                    233:                        }
                    234:                        if ( isa( p1 , "i" ) ) {
                    235:                            putleaf( P2ICON , 0 , 0
                    236:                                , ADDTYPE( P2FTN | P2INT , P2PTR ) , "_abs" );
                    237:                            p1 = stkrval( (int *) argv[1] , NLNIL , RREQ );
                    238:                            putop( P2CALL , P2INT );
                    239:                            return nl + T4INT;
                    240:                        }
                    241:                        error("%s's argument must be an integer or real, not %s", p->symbol, nameof(p1));
                    242:                        return NIL;
                    243:            case O_SQR2:
                    244:                        if ( isa( p1 , "d" ) ) {
                    245:                            temptype = P2DOUBLE;
                    246:                            rettype = nl + TDOUBLE;
                    247:                            sizes[ cbn ].om_off -= sizeof( double );
                    248:                        } else if ( isa( p1 , "i" ) ) {
                    249:                            temptype = P2INT;
                    250:                            rettype = nl + T4INT;
                    251:                            sizes[ cbn ].om_off -= sizeof( long );
                    252:                        } else {
                    253:                            error("%s's argument must be an integer or real, not %s", p->symbol, nameof(p1));
                    254:                            return NIL;
                    255:                        }
                    256:                        tempoff = sizes[ cbn ].om_off;
                    257:                        if ( tempoff < sizes[ cbn ].om_max ) {
                    258:                            sizes[ cbn ].om_max = tempoff;
                    259:                        }
                    260:                        putlbracket( ftnno , -tempoff );
                    261:                        putRV( 0 , cbn , tempoff , temptype , 0 );
                    262:                        p1 = rvalue( (int *) argv[1] , NLNIL , RREQ );
                    263:                        putop( P2ASSIGN , temptype );
                    264:                        putRV( 0 , cbn , tempoff , temptype , 0 );
                    265:                        putRV( 0 , cbn , tempoff , temptype , 0 );
                    266:                        putop( P2MUL , temptype );
                    267:                        putop( P2COMOP , temptype );
                    268:                        return rettype;
                    269:            case O_ORD2:
                    270:                        p1 = stkrval( (int *) argv[1] , NLNIL , RREQ );
                    271:                        if (isa(p1, "bcis") || classify(p1) == TPTR) {
                    272:                                return (nl+T4INT);
                    273:                        }
                    274:                        error("ord's argument must be of scalar type or a pointer, not %s", nameof(p1));
                    275:                        return (NIL);
                    276:            case O_SUCC2:
                    277:            case O_PRED2:
                    278:                        if (isa(p1, "d")) {
                    279:                                error("%s is forbidden for reals", p->symbol);
                    280:                                return (NIL);
                    281:                        }
                    282:                        if ( isnta( p1 , "bcsi" ) ) {
                    283:                            error("%s's argument must be of scalar type, not %s", p->symbol, nameof(p1));
                    284:                            return NIL;
                    285:                        }
                    286:                        if ( opt( 't' ) ) {
                    287:                            putleaf( P2ICON , 0 , 0
                    288:                                    , ADDTYPE( P2FTN | P2INT , P2PTR )
                    289:                                    , op == O_SUCC2 ? "_SUCC" : "_PRED" );
                    290:                            p1 = stkrval( (int *) argv[1] , NLNIL , RREQ );
                    291:                            putleaf( P2ICON , p1 -> range[0] , 0 , P2INT , 0 );
                    292:                            putop( P2LISTOP , P2INT );
                    293:                            putleaf( P2ICON , p1 -> range[1] , 0 , P2INT , 0 );
                    294:                            putop( P2LISTOP , P2INT );
                    295:                            putop( P2CALL , P2INT );
                    296:                        } else {
                    297:                            p1 = rvalue( argv[1] , NIL , RREQ );
                    298:                            putleaf( P2ICON , 1 , 0 , P2INT , 0 );
                    299:                            putop( op == O_SUCC2 ? P2PLUS : P2MINUS , P2INT );
                    300:                        }
                    301:                        if ( isa( p1 , "bcs" ) ) {
                    302:                            return p1;
                    303:                        } else {
                    304:                            return nl + T4INT;
                    305:                        }
                    306:            case O_ODD2:
                    307:                        if (isnta(p1, "i")) {
                    308:                                error("odd's argument must be an integer, not %s", nameof(p1));
                    309:                                return (NIL);
                    310:                        }
                    311:                        p1 = rvalue( (int *) argv[1] , NLNIL , RREQ );
                    312:                        putleaf( P2ICON , 1 , 0 , P2INT , 0 );
                    313:                        putop( P2AND , P2INT );
                    314:                        return nl + TBOOL;
                    315:            case O_CHR2:
                    316:                        if (isnta(p1, "i")) {
                    317:                                error("chr's argument must be an integer, not %s", nameof(p1));
                    318:                                return (NIL);
                    319:                        }
                    320:                        if (opt('t')) {
                    321:                            putleaf( P2ICON , 0 , 0
                    322:                                , ADDTYPE( P2FTN | P2CHAR , P2PTR ) , "_CHR" );
                    323:                            p1 = stkrval( (int *) argv[1] , NLNIL , RREQ );
                    324:                            putop( P2CALL , P2CHAR );
                    325:                        } else {
                    326:                            p1 = stkrval( (int *) argv[1] , NLNIL , RREQ );
                    327:                        }
                    328:                        return nl + TCHAR;
                    329:            case O_CARD:
                    330:                        if (isnta(p1, "t")) {
                    331:                            error("Argument to card must be a set, not %s", nameof(p1));
                    332:                            return (NIL);
                    333:                        }
                    334:                        putleaf( P2ICON , 0 , 0
                    335:                            , ADDTYPE( P2FTN | P2INT , P2PTR ) , "_CARD" );
                    336:                        p1 = stkrval( (int *) argv[1] , NLNIL , LREQ );
                    337:                        putleaf( P2ICON , lwidth( p1 ) , 0 , P2INT , 0 );
                    338:                        putop( P2LISTOP , P2INT );
                    339:                        putop( P2CALL , P2INT );
                    340:                        return nl + T2INT;
                    341:            case O_EOLN:
                    342:                        if (!text(p1)) {
                    343:                                error("Argument to eoln must be a text file, not %s", nameof(p1));
                    344:                                return (NIL);
                    345:                        }
                    346:                        putleaf( P2ICON , 0 , 0
                    347:                            , ADDTYPE( P2FTN | P2INT , P2PTR ) , "_TEOLN" );
                    348:                        p1 = stklval( (int *) argv[1] , NOFLAGS );
                    349:                        putop( P2CALL , P2INT );
                    350:                        return nl + TBOOL;
                    351:            case O_EOF:
                    352:                        if (p1->class != FILET) {
                    353:                                error("Argument to eof must be file, not %s", nameof(p1));
                    354:                                return (NIL);
                    355:                        }
                    356:                        putleaf( P2ICON , 0 , 0
                    357:                            , ADDTYPE( P2FTN | P2INT , P2PTR ) , "_TEOF" );
                    358:                        p1 = stklval( (int *) argv[1] , NOFLAGS );
                    359:                        putop( P2CALL , P2INT );
                    360:                        return nl + TBOOL;
                    361:            case 0:
                    362:                        error("%s is an unimplemented 6000-3.4 extension", p->symbol);
                    363:            default:
                    364:                        panic("func1");
                    365:        }
                    366: }
                    367: #endif PC

unix.superglobalmegacorp.com

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