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

unix.superglobalmegacorp.com

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