Annotation of 43BSDTahoe/ucb/pascal/src/pcproc.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[] = "@(#)pcproc.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:  * The constant EXPOSIZE specifies the number of digits in the exponent
                     27:  * of real numbers.
                     28:  *
                     29:  * The constant REALSPC defines the amount of forced padding preceeding
                     30:  * real numbers when they are printed. If REALSPC == 0, then no padding
                     31:  * is added, REALSPC == 1 adds one extra blank irregardless of the width
                     32:  * specified by the user.
                     33:  *
                     34:  * N.B. - Values greater than one require program mods.
                     35:  */
                     36: #define EXPOSIZE       2
                     37: #define        REALSPC         0
                     38: 
                     39: /*
                     40:  * The following array is used to determine which classes may be read
                     41:  * from textfiles. It is indexed by the return value from classify.
                     42:  */
                     43: #define rdops(x) rdxxxx[(x)-(TFIRST)]
                     44: 
                     45: int rdxxxx[] = {
                     46:        0,              /* -7 file types */
                     47:        0,              /* -6 record types */
                     48:        0,              /* -5 array types */
                     49:        O_READE,        /* -4 scalar types */
                     50:        0,              /* -3 pointer types */
                     51:        0,              /* -2 set types */
                     52:        0,              /* -1 string types */
                     53:        0,              /*  0 nil, no type */
                     54:        O_READE,        /*  1 boolean */
                     55:        O_READC,        /*  2 character */
                     56:        O_READ4,        /*  3 integer */
                     57:        O_READ8         /*  4 real */
                     58: };
                     59: 
                     60: /*
                     61:  * Proc handles procedure calls.
                     62:  * Non-builtin procedures are "buck-passed" to func (with a flag
                     63:  * indicating that they are actually procedures.
                     64:  * builtin procedures are handled here.
                     65:  */
                     66: pcproc(r)
                     67:        struct tnode *r;        /* T_PCALL */
                     68: {
                     69:        register struct nl *p;
                     70:        register struct tnode *alv, *al;
                     71:        register op;
                     72:        struct nl *filetype, *ap;
                     73:        int argc, typ, fmtspec, strfmt;
                     74:        struct tnode *argv, *file;
                     75:        char fmt, format[20], *strptr, *cmd;
                     76:        int prec, field, strnglen, fmtstart;
                     77:        char *pu;
                     78:        struct tnode *pua, *pui, *puz;
                     79:        int i, j, k;
                     80:        int itemwidth;
                     81:        char            *readname;
                     82:        struct nl       *tempnlp;
                     83:        long            readtype;
                     84:        struct tmps     soffset;
                     85:        bool            soffset_flag;
                     86: 
                     87: #define        CONPREC 4
                     88: #define        VARPREC 8
                     89: #define        CONWIDTH 1
                     90: #define        VARWIDTH 2
                     91: #define SKIP 16
                     92: 
                     93:        /*
                     94:         * Verify that the name is
                     95:         * defined and is that of a
                     96:         * procedure.
                     97:         */
                     98:        p = lookup(r->pcall_node.proc_id);
                     99:        if (p == NLNIL) {
                    100:                rvlist(r->pcall_node.arg);
                    101:                return;
                    102:        }
                    103:        if (p->class != PROC && p->class != FPROC) {
                    104:                error("Can't call %s, its %s not a procedure", p->symbol, classes[p->class]);
                    105:                rvlist(r->pcall_node.arg);
                    106:                return;
                    107:        }
                    108:        argv = r->pcall_node.arg;
                    109: 
                    110:        /*
                    111:         * Call handles user defined
                    112:         * procedures and functions.
                    113:         */
                    114:        if (bn != 0) {
                    115:                (void) call(p, argv, PROC, bn);
                    116:                return;
                    117:        }
                    118: 
                    119:        /*
                    120:         * Call to built-in procedure.
                    121:         * Count the arguments.
                    122:         */
                    123:        argc = 0;
                    124:        for (al = argv; al != TR_NIL; al = al->list_node.next)
                    125:                argc++;
                    126: 
                    127:        /*
                    128:         * Switch on the operator
                    129:         * associated with the built-in
                    130:         * procedure in the namelist
                    131:         */
                    132:        op = p->value[0] &~ NSTAND;
                    133:        if (opt('s') && (p->value[0] & NSTAND)) {
                    134:                standard();
                    135:                error("%s is a nonstandard procedure", p->symbol);
                    136:        }
                    137:        switch (op) {
                    138: 
                    139:        case O_ABORT:
                    140:                if (argc != 0)
                    141:                        error("null takes no arguments");
                    142:                return;
                    143: 
                    144:        case O_FLUSH:
                    145:                if (argc == 0) {
                    146:                        putleaf( PCC_ICON , 0 , 0 , PCCT_INT , "_PFLUSH" );
                    147:                        putop( PCCOM_UNARY PCC_CALL , PCCT_INT );
                    148:                        putdot( filename , line );
                    149:                        return;
                    150:                }
                    151:                if (argc != 1) {
                    152:                        error("flush takes at most one argument");
                    153:                        return;
                    154:                }
                    155:                putleaf( PCC_ICON , 0 , 0
                    156:                        , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    157:                        , "_FLUSH" );
                    158:                ap = stklval(argv->list_node.list, NOFLAGS);
                    159:                if (ap == NLNIL)
                    160:                        return;
                    161:                if (ap->class != FILET) {
                    162:                        error("flush's argument must be a file, not %s", nameof(ap));
                    163:                        return;
                    164:                }
                    165:                putop( PCC_CALL , PCCT_INT );
                    166:                putdot( filename , line );
                    167:                return;
                    168: 
                    169:        case O_MESSAGE:
                    170:        case O_WRITEF:
                    171:        case O_WRITLN:
                    172:                /*
                    173:                 * Set up default file "output"'s type
                    174:                 */
                    175:                file = NIL;
                    176:                filetype = nl+T1CHAR;
                    177:                /*
                    178:                 * Determine the file implied
                    179:                 * for the write and generate
                    180:                 * code to make it the active file.
                    181:                 */
                    182:                if (op == O_MESSAGE) {
                    183:                        /*
                    184:                         * For message, all that matters
                    185:                         * is that the filetype is
                    186:                         * a character file.
                    187:                         * Thus "output" will suit us fine.
                    188:                         */
                    189:                        putleaf( PCC_ICON , 0 , 0 , PCCT_INT , "_PFLUSH" );
                    190:                        putop( PCCOM_UNARY PCC_CALL , PCCT_INT );
                    191:                        putdot( filename , line );
                    192:                        putRV( (char *) 0 , cbn , CURFILEOFFSET , NLOCAL ,
                    193:                                PCCTM_PTR|PCCT_STRTY );
                    194:                        putLV( "__err" , 0 , 0 , NGLOBAL , PCCTM_PTR|PCCT_STRTY );
                    195:                        putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY );
                    196:                        putdot( filename , line );
                    197:                } else if (argv != TR_NIL && (al = argv->list_node.list)->tag !=
                    198:                                        T_WEXP) {
                    199:                        /*
                    200:                         * If there is a first argument which has
                    201:                         * no write widths, then it is potentially
                    202:                         * a file name.
                    203:                         */
                    204:                        codeoff();
                    205:                        ap = stkrval(argv->list_node.list, NLNIL, (long) RREQ );
                    206:                        codeon();
                    207:                        if (ap == NLNIL)
                    208:                                argv = argv->list_node.next;
                    209:                        if (ap != NIL && ap->class == FILET) {
                    210:                                /*
                    211:                                 * Got "write(f, ...", make
                    212:                                 * f the active file, and save
                    213:                                 * it and its type for use in
                    214:                                 * processing the rest of the
                    215:                                 * arguments to write.
                    216:                                 */
                    217:                                putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL ,
                    218:                                        PCCTM_PTR|PCCT_STRTY );
                    219:                                putleaf( PCC_ICON , 0 , 0
                    220:                                    , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    221:                                    , "_UNIT" );
                    222:                                file = argv->list_node.list;
                    223:                                filetype = ap->type;
                    224:                                (void) stklval(argv->list_node.list, NOFLAGS);
                    225:                                putop( PCC_CALL , PCCT_INT );
                    226:                                putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY );
                    227:                                putdot( filename , line );
                    228:                                /*
                    229:                                 * Skip over the first argument
                    230:                                 */
                    231:                                argv = argv->list_node.next;
                    232:                                argc--;
                    233:                        } else {
                    234:                                /*
                    235:                                 * Set up for writing on 
                    236:                                 * standard output.
                    237:                                 */
                    238:                                putRV((char *) 0, cbn , CURFILEOFFSET ,
                    239:                                        NLOCAL , PCCTM_PTR|PCCT_STRTY );
                    240:                                putLV( "_output" , 0 , 0 , NGLOBAL ,
                    241:                                        PCCTM_PTR|PCCT_STRTY );
                    242:                                putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY );
                    243:                                putdot( filename , line );
                    244:                                output->nl_flags |= NUSED;
                    245:                        }
                    246:                } else {
                    247:                        putRV((char *) 0, cbn , CURFILEOFFSET , NLOCAL ,
                    248:                                PCCTM_PTR|PCCT_STRTY );
                    249:                        putLV( "_output" , 0 , 0 , NGLOBAL , PCCTM_PTR|PCCT_STRTY );
                    250:                        putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY );
                    251:                        putdot( filename , line );
                    252:                        output->nl_flags |= NUSED;
                    253:                }
                    254:                /*
                    255:                 * Loop and process each
                    256:                 * of the arguments.
                    257:                 */
                    258:                for (; argv != TR_NIL; argv = argv->list_node.next) {
                    259:                        soffset_flag = FALSE;
                    260:                        /*
                    261:                         * fmtspec indicates the type (CONstant or VARiable)
                    262:                         *      and number (none, WIDTH, and/or PRECision)
                    263:                         *      of the fields in the printf format for this
                    264:                         *      output variable.
                    265:                         * fmt is the format output indicator (D, E, F, O, X, S)
                    266:                         * fmtstart = 0 for leading blank; = 1 for no blank
                    267:                         */
                    268:                        fmtspec = NIL;
                    269:                        fmt = 'D';
                    270:                        fmtstart = 1;
                    271:                        al = argv->list_node.list;
                    272:                        if (al == NIL)
                    273:                                continue;
                    274:                        if (al->tag == T_WEXP)
                    275:                                alv = al->wexpr_node.expr1;
                    276:                        else
                    277:                                alv = al;
                    278:                        if (alv == TR_NIL)
                    279:                                continue;
                    280:                        codeoff();
                    281:                        ap = stkrval(alv, NLNIL , (long) RREQ );
                    282:                        codeon();
                    283:                        if (ap == NLNIL)
                    284:                                continue;
                    285:                        typ = classify(ap);
                    286:                        if (al->tag == T_WEXP) {
                    287:                                /*
                    288:                                 * Handle width expressions.
                    289:                                 * The basic game here is that width
                    290:                                 * expressions get evaluated. If they
                    291:                                 * are constant, the value is placed
                    292:                                 * directly in the format string.
                    293:                                 * Otherwise the value is pushed onto
                    294:                                 * the stack and an indirection is
                    295:                                 * put into the format string.
                    296:                                 */
                    297:                                if (al->wexpr_node.expr3 == 
                    298:                                                (struct tnode *) OCT)
                    299:                                        fmt = 'O';
                    300:                                else if (al->wexpr_node.expr3 == 
                    301:                                                (struct tnode *) HEX)
                    302:                                        fmt = 'X';
                    303:                                else if (al->wexpr_node.expr3 != TR_NIL) {
                    304:                                        /*
                    305:                                         * Evaluate second format spec
                    306:                                         */
                    307:                                        if ( constval(al->wexpr_node.expr3)
                    308:                                            && isa( con.ctype , "i" ) ) {
                    309:                                                fmtspec += CONPREC;
                    310:                                                prec = con.crval;
                    311:                                        } else {
                    312:                                                fmtspec += VARPREC;
                    313:                                        }
                    314:                                        fmt = 'f';
                    315:                                        switch ( typ ) {
                    316:                                        case TINT:
                    317:                                                if ( opt( 's' ) ) {
                    318:                                                    standard();
                    319:                                                    error("Writing %ss with two write widths is non-standard", clnames[typ]);
                    320:                                                }
                    321:                                                /* and fall through */
                    322:                                        case TDOUBLE:
                    323:                                                break;
                    324:                                        default:
                    325:                                                error("Cannot write %ss with two write widths", clnames[typ]);
                    326:                                                continue;
                    327:                                        }
                    328:                                }
                    329:                                /*
                    330:                                 * Evaluate first format spec
                    331:                                 */
                    332:                                if (al->wexpr_node.expr2 != TR_NIL) {
                    333:                                        if ( constval(al->wexpr_node.expr2)
                    334:                                            && isa( con.ctype , "i" ) ) {
                    335:                                                fmtspec += CONWIDTH;
                    336:                                                field = con.crval;
                    337:                                        } else {
                    338:                                                fmtspec += VARWIDTH;
                    339:                                        }
                    340:                                }
                    341:                                if ((fmtspec & CONPREC) && prec < 0 ||
                    342:                                    (fmtspec & CONWIDTH) && field < 0) {
                    343:                                        error("Negative widths are not allowed");
                    344:                                        continue;
                    345:                                }
                    346:                                if ( opt('s') &&
                    347:                                    ((fmtspec & CONPREC) && prec == 0 ||
                    348:                                    (fmtspec & CONWIDTH) && field == 0)) {
                    349:                                        standard();
                    350:                                        error("Zero widths are non-standard");
                    351:                                }
                    352:                        }
                    353:                        if (filetype != nl+T1CHAR) {
                    354:                                if (fmt == 'O' || fmt == 'X') {
                    355:                                        error("Oct/hex allowed only on text files");
                    356:                                        continue;
                    357:                                }
                    358:                                if (fmtspec) {
                    359:                                        error("Write widths allowed only on text files");
                    360:                                        continue;
                    361:                                }
                    362:                                /*
                    363:                                 * Generalized write, i.e.
                    364:                                 * to a non-textfile.
                    365:                                 */
                    366:                                putleaf( PCC_ICON , 0 , 0
                    367:                                    , (int) (PCCM_ADDTYPE(
                    368:                                        PCCM_ADDTYPE(
                    369:                                            PCCM_ADDTYPE( p2type( filetype )
                    370:                                                    , PCCTM_PTR )
                    371:                                            , PCCTM_FTN )
                    372:                                        , PCCTM_PTR ))
                    373:                                    , "_FNIL" );
                    374:                                (void) stklval(file, NOFLAGS);
                    375:                                putop( PCC_CALL
                    376:                                    , PCCM_ADDTYPE( p2type( filetype ) , PCCTM_PTR ) );
                    377:                                putop( PCCOM_UNARY PCC_MUL , p2type( filetype ) );
                    378:                                /*
                    379:                                 * file^ := ...
                    380:                                 */
                    381:                                switch ( classify( filetype ) ) {
                    382:                                    case TBOOL:
                    383:                                    case TCHAR:
                    384:                                    case TINT:
                    385:                                    case TSCAL:
                    386:                                        precheck( filetype , "_RANG4"  , "_RSNG4" );
                    387:                                            /* and fall through */
                    388:                                    case TDOUBLE:
                    389:                                    case TPTR:
                    390:                                        ap = rvalue( argv->list_node.list , filetype , RREQ );
                    391:                                        break;
                    392:                                    default:
                    393:                                        ap = rvalue( argv->list_node.list , filetype , LREQ );
                    394:                                        break;
                    395:                                }
                    396:                                if (ap == NIL)
                    397:                                        continue;
                    398:                                if (incompat(ap, filetype, argv->list_node.list)) {
                    399:                                        cerror("Type mismatch in write to non-text file");
                    400:                                        continue;
                    401:                                }
                    402:                                switch ( classify( filetype ) ) {
                    403:                                    case TBOOL:
                    404:                                    case TCHAR:
                    405:                                    case TINT:
                    406:                                    case TSCAL:
                    407:                                            postcheck(filetype, ap);
                    408:                                            sconv(p2type(ap), p2type(filetype));
                    409:                                                /* and fall through */
                    410:                                    case TDOUBLE:
                    411:                                    case TPTR:
                    412:                                            putop( PCC_ASSIGN , p2type( filetype ) );
                    413:                                            putdot( filename , line );
                    414:                                            break;
                    415:                                    default:
                    416:                                            putstrop(PCC_STASG,
                    417:                                                    PCCM_ADDTYPE(p2type(filetype),
                    418:                                                            PCCTM_PTR),
                    419:                                                    (int) lwidth(filetype),
                    420:                                                    align(filetype));
                    421:                                            putdot( filename , line );
                    422:                                            break;
                    423:                                }
                    424:                                /*
                    425:                                 * put(file)
                    426:                                 */
                    427:                                putleaf( PCC_ICON , 0 , 0
                    428:                                    , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    429:                                    , "_PUT" );
                    430:                                putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL ,
                    431:                                        PCCTM_PTR|PCCT_STRTY );
                    432:                                putop( PCC_CALL , PCCT_INT );
                    433:                                putdot( filename , line );
                    434:                                continue;
                    435:                        }
                    436:                        /*
                    437:                         * Write to a textfile
                    438:                         *
                    439:                         * Evaluate the expression
                    440:                         * to be written.
                    441:                         */
                    442:                        if (fmt == 'O' || fmt == 'X') {
                    443:                                if (opt('s')) {
                    444:                                        standard();
                    445:                                        error("Oct and hex are non-standard");
                    446:                                }
                    447:                                if (typ == TSTR || typ == TDOUBLE) {
                    448:                                        error("Can't write %ss with oct/hex", clnames[typ]);
                    449:                                        continue;
                    450:                                }
                    451:                                if (typ == TCHAR || typ == TBOOL)
                    452:                                        typ = TINT;
                    453:                        }
                    454:                        /*
                    455:                         * If there is no format specified by the programmer,
                    456:                         * implement the default.
                    457:                         */
                    458:                        switch (typ) {
                    459:                        case TPTR:
                    460:                                warning();
                    461:                                if (opt('s')) {
                    462:                                        standard();
                    463:                                }
                    464:                                error("Writing %ss to text files is non-standard",
                    465:                                    clnames[typ]);
                    466:                                /* and fall through */
                    467:                        case TINT:
                    468:                                if (fmt == 'f') {
                    469:                                        typ = TDOUBLE;
                    470:                                        goto tdouble;
                    471:                                }
                    472:                                if (fmtspec == NIL) {
                    473:                                        if (fmt == 'D')
                    474:                                                field = 10;
                    475:                                        else if (fmt == 'X')
                    476:                                                field = 8;
                    477:                                        else if (fmt == 'O')
                    478:                                                field = 11;
                    479:                                        else
                    480:                                                panic("fmt1");
                    481:                                        fmtspec = CONWIDTH;
                    482:                                }
                    483:                                break;
                    484:                        case TCHAR:
                    485:                             tchar:
                    486:                                fmt = 'c';
                    487:                                break;
                    488:                        case TSCAL:
                    489:                                warning();
                    490:                                if (opt('s')) {
                    491:                                        standard();
                    492:                                }
                    493:                                error("Writing %ss to text files is non-standard",
                    494:                                    clnames[typ]);
                    495:                        case TBOOL:
                    496:                                fmt = 's';
                    497:                                break;
                    498:                        case TDOUBLE:
                    499:                             tdouble:
                    500:                                switch (fmtspec) {
                    501:                                case NIL:
                    502:                                        field = 14 + (5 + EXPOSIZE);
                    503:                                        prec = field - (5 + EXPOSIZE);
                    504:                                        fmt = 'e';
                    505:                                        fmtspec = CONWIDTH + CONPREC;
                    506:                                        break;
                    507:                                case CONWIDTH:
                    508:                                        field -= REALSPC;
                    509:                                        if (field < 1)
                    510:                                                field = 1;
                    511:                                        prec = field - (5 + EXPOSIZE);
                    512:                                        if (prec < 1)
                    513:                                                prec = 1;
                    514:                                        fmtspec += CONPREC;
                    515:                                        fmt = 'e';
                    516:                                        break;
                    517:                                case VARWIDTH:
                    518:                                        fmtspec += VARPREC;
                    519:                                        fmt = 'e';
                    520:                                        break;
                    521:                                case CONWIDTH + CONPREC:
                    522:                                case CONWIDTH + VARPREC:
                    523:                                        field -= REALSPC;
                    524:                                        if (field < 1)
                    525:                                                field = 1;
                    526:                                }
                    527:                                format[0] = ' ';
                    528:                                fmtstart = 1 - REALSPC;
                    529:                                break;
                    530:                        case TSTR:
                    531:                                (void) constval( alv );
                    532:                                switch ( classify( con.ctype ) ) {
                    533:                                    case TCHAR:
                    534:                                        typ = TCHAR;
                    535:                                        goto tchar;
                    536:                                    case TSTR:
                    537:                                        strptr = con.cpval;
                    538:                                        for (strnglen = 0;  *strptr++;  strnglen++) /* void */;
                    539:                                        strptr = con.cpval;
                    540:                                        break;
                    541:                                    default:
                    542:                                        strnglen = width(ap);
                    543:                                        break;
                    544:                                }
                    545:                                fmt = 's';
                    546:                                strfmt = fmtspec;
                    547:                                if (fmtspec == NIL) {
                    548:                                        fmtspec = SKIP;
                    549:                                        break;
                    550:                                }
                    551:                                if (fmtspec & CONWIDTH) {
                    552:                                        if (field <= strnglen)
                    553:                                                fmtspec = SKIP;
                    554:                                        else
                    555:                                                field -= strnglen;
                    556:                                }
                    557:                                break;
                    558:                        default:
                    559:                                error("Can't write %ss to a text file", clnames[typ]);
                    560:                                continue;
                    561:                        }
                    562:                        /*
                    563:                         * Generate the format string
                    564:                         */
                    565:                        switch (fmtspec) {
                    566:                        default:
                    567:                                panic("fmt2");
                    568:                        case NIL:
                    569:                                if (fmt == 'c') {
                    570:                                        if ( opt( 't' ) ) {
                    571:                                            putleaf( PCC_ICON , 0 , 0
                    572:                                                , PCCM_ADDTYPE( PCCTM_FTN|PCCT_INT , PCCTM_PTR )
                    573:                                                , "_WRITEC" );
                    574:                                            putRV((char *) 0 , cbn , CURFILEOFFSET ,
                    575:                                                    NLOCAL , PCCTM_PTR|PCCT_STRTY );
                    576:                                            (void) stkrval( alv , NLNIL , (long) RREQ );
                    577:                                            putop( PCC_CM , PCCT_INT );
                    578:                                        } else {
                    579:                                            putleaf( PCC_ICON , 0 , 0
                    580:                                                , PCCM_ADDTYPE( PCCTM_FTN|PCCT_INT , PCCTM_PTR )
                    581:                                                , "_fputc" );
                    582:                                            (void) stkrval( alv , NLNIL ,
                    583:                                                        (long) RREQ );
                    584:                                        }
                    585:                                        putleaf( PCC_ICON , 0 , 0
                    586:                                            , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    587:                                            , "_ACTFILE" );
                    588:                                        putRV((char *) 0, cbn , CURFILEOFFSET ,
                    589:                                                NLOCAL , PCCTM_PTR|PCCT_STRTY );
                    590:                                        putop( PCC_CALL , PCCT_INT );
                    591:                                        putop( PCC_CM , PCCT_INT );
                    592:                                        putop( PCC_CALL , PCCT_INT );
                    593:                                        putdot( filename , line );
                    594:                                } else  {
                    595:                                        sprintf(&format[1], "%%%c", fmt);
                    596:                                        goto fmtgen;
                    597:                                }
                    598:                        case SKIP:
                    599:                                break;
                    600:                        case CONWIDTH:
                    601:                                sprintf(&format[1], "%%%1D%c", field, fmt);
                    602:                                goto fmtgen;
                    603:                        case VARWIDTH:
                    604:                                sprintf(&format[1], "%%*%c", fmt);
                    605:                                goto fmtgen;
                    606:                        case CONWIDTH + CONPREC:
                    607:                                sprintf(&format[1], "%%%1D.%1D%c", field, prec, fmt);
                    608:                                goto fmtgen;
                    609:                        case CONWIDTH + VARPREC:
                    610:                                sprintf(&format[1], "%%%1D.*%c", field, fmt);
                    611:                                goto fmtgen;
                    612:                        case VARWIDTH + CONPREC:
                    613:                                sprintf(&format[1], "%%*.%1D%c", prec, fmt);
                    614:                                goto fmtgen;
                    615:                        case VARWIDTH + VARPREC:
                    616:                                sprintf(&format[1], "%%*.*%c", fmt);
                    617:                        fmtgen:
                    618:                                if ( opt( 't' ) ) {
                    619:                                    putleaf( PCC_ICON , 0 , 0
                    620:                                        , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    621:                                        , "_WRITEF" );
                    622:                                    putRV((char *) 0 , cbn , CURFILEOFFSET ,
                    623:                                            NLOCAL , PCCTM_PTR|PCCT_STRTY );
                    624:                                    putleaf( PCC_ICON , 0 , 0
                    625:                                        , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    626:                                        , "_ACTFILE" );
                    627:                                    putRV((char *) 0 , cbn , CURFILEOFFSET ,
                    628:                                            NLOCAL , PCCTM_PTR|PCCT_STRTY );
                    629:                                    putop( PCC_CALL , PCCT_INT );
                    630:                                    putop( PCC_CM , PCCT_INT );
                    631:                                } else {
                    632:                                    putleaf( PCC_ICON , 0 , 0
                    633:                                        , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    634:                                        , "_fprintf" );
                    635:                                    putleaf( PCC_ICON , 0 , 0
                    636:                                        , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    637:                                        , "_ACTFILE" );
                    638:                                    putRV((char *) 0 , cbn , CURFILEOFFSET ,
                    639:                                            NLOCAL , PCCTM_PTR|PCCT_STRTY );
                    640:                                    putop( PCC_CALL , PCCT_INT );
                    641:                                }
                    642:                                putCONG( &format[ fmtstart ]
                    643:                                        , strlen( &format[ fmtstart ] )
                    644:                                        , LREQ );
                    645:                                putop( PCC_CM , PCCT_INT );
                    646:                                if ( fmtspec & VARWIDTH ) {
                    647:                                        /*
                    648:                                         * either
                    649:                                         *      ,(temp=width,MAX(temp,...)),
                    650:                                         * or
                    651:                                         *      , MAX( width , ... ) ,
                    652:                                         */
                    653:                                    if ( ( typ == TDOUBLE &&
                    654:                                                al->wexpr_node.expr3 == TR_NIL )
                    655:                                        || typ == TSTR ) {
                    656:                                        soffset_flag = TRUE;
                    657:                                        soffset = sizes[cbn].curtmps;
                    658:                                        tempnlp = tmpalloc((long) (sizeof(long)),
                    659:                                                nl+T4INT, REGOK);
                    660:                                        putRV((char *) 0 , cbn ,
                    661:                                            tempnlp -> value[ NL_OFFS ] ,
                    662:                                            tempnlp -> extra_flags , PCCT_INT );
                    663:                                        ap = stkrval( al->wexpr_node.expr2 ,
                    664:                                                NLNIL , (long) RREQ );
                    665:                                        putop( PCC_ASSIGN , PCCT_INT );
                    666:                                        putleaf( PCC_ICON , 0 , 0
                    667:                                            , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    668:                                            , "_MAX" );
                    669:                                        putRV((char *) 0 , cbn ,
                    670:                                            tempnlp -> value[ NL_OFFS ] ,
                    671:                                            tempnlp -> extra_flags , PCCT_INT );
                    672:                                    } else {
                    673:                                        if (opt('t')
                    674:                                            || typ == TSTR || typ == TDOUBLE) {
                    675:                                            putleaf( PCC_ICON , 0 , 0
                    676:                                                ,PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT, PCCTM_PTR )
                    677:                                                ,"_MAX" );
                    678:                                        }
                    679:                                        ap = stkrval( al->wexpr_node.expr2,
                    680:                                                NLNIL , (long) RREQ );
                    681:                                    }
                    682:                                    if (ap == NLNIL)
                    683:                                            continue;
                    684:                                    if (isnta(ap,"i")) {
                    685:                                            error("First write width must be integer, not %s", nameof(ap));
                    686:                                            continue;
                    687:                                    }
                    688:                                    switch ( typ ) {
                    689:                                    case TDOUBLE:
                    690:                                        putleaf( PCC_ICON , REALSPC , 0 , PCCT_INT , (char *) 0 );
                    691:                                        putop( PCC_CM , PCCT_INT );
                    692:                                        putleaf( PCC_ICON , 1 , 0 , PCCT_INT , (char *) 0 );
                    693:                                        putop( PCC_CM , PCCT_INT );
                    694:                                        putop( PCC_CALL , PCCT_INT );
                    695:                                        if ( al->wexpr_node.expr3 == TR_NIL ) {
                    696:                                                /*
                    697:                                                 * finish up the comma op
                    698:                                                 */
                    699:                                            putop( PCC_COMOP , PCCT_INT );
                    700:                                            fmtspec &= ~VARPREC;
                    701:                                            putop( PCC_CM , PCCT_INT );
                    702:                                            putleaf( PCC_ICON , 0 , 0
                    703:                                                , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    704:                                                , "_MAX" );
                    705:                                            putRV((char *) 0 , cbn ,
                    706:                                                tempnlp -> value[ NL_OFFS ] ,
                    707:                                                tempnlp -> extra_flags ,
                    708:                                                PCCT_INT );
                    709:                                            putleaf( PCC_ICON ,
                    710:                                                5 + EXPOSIZE + REALSPC ,
                    711:                                                0 , PCCT_INT , (char *) 0 );
                    712:                                            putop( PCC_CM , PCCT_INT );
                    713:                                            putleaf( PCC_ICON , 1 , 0 , PCCT_INT , (char *) 0 );
                    714:                                            putop( PCC_CM , PCCT_INT );
                    715:                                            putop( PCC_CALL , PCCT_INT );
                    716:                                        }
                    717:                                        putop( PCC_CM , PCCT_INT );
                    718:                                        break;
                    719:                                    case TSTR:
                    720:                                        putleaf( PCC_ICON , strnglen , 0 , PCCT_INT , (char *) 0 );
                    721:                                        putop( PCC_CM , PCCT_INT );
                    722:                                        putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 );
                    723:                                        putop( PCC_CM , PCCT_INT );
                    724:                                        putop( PCC_CALL , PCCT_INT );
                    725:                                        putop( PCC_COMOP , PCCT_INT );
                    726:                                        putop( PCC_CM , PCCT_INT );
                    727:                                        break;
                    728:                                    default:
                    729:                                        if (opt('t')) {
                    730:                                            putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 );
                    731:                                            putop( PCC_CM , PCCT_INT );
                    732:                                            putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 );
                    733:                                            putop( PCC_CM , PCCT_INT );
                    734:                                            putop( PCC_CALL , PCCT_INT );
                    735:                                        }
                    736:                                        putop( PCC_CM , PCCT_INT );
                    737:                                        break;
                    738:                                    }
                    739:                                }
                    740:                                /*
                    741:                                 * If there is a variable precision,
                    742:                                 * evaluate it 
                    743:                                 */
                    744:                                if (fmtspec & VARPREC) {
                    745:                                        if (opt('t')) {
                    746:                                        putleaf( PCC_ICON , 0 , 0
                    747:                                            , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    748:                                            , "_MAX" );
                    749:                                        }
                    750:                                        ap = stkrval( al->wexpr_node.expr3 ,
                    751:                                                NLNIL , (long) RREQ );
                    752:                                        if (ap == NIL)
                    753:                                                continue;
                    754:                                        if (isnta(ap,"i")) {
                    755:                                                error("Second write width must be integer, not %s", nameof(ap));
                    756:                                                continue;
                    757:                                        }
                    758:                                        if (opt('t')) {
                    759:                                            putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 );
                    760:                                            putop( PCC_CM , PCCT_INT );
                    761:                                            putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 );
                    762:                                            putop( PCC_CM , PCCT_INT );
                    763:                                            putop( PCC_CALL , PCCT_INT );
                    764:                                        }
                    765:                                        putop( PCC_CM , PCCT_INT );
                    766:                                }
                    767:                                /*
                    768:                                 * evaluate the thing we want printed.
                    769:                                 */
                    770:                                switch ( typ ) {
                    771:                                case TPTR:
                    772:                                case TCHAR:
                    773:                                case TINT:
                    774:                                    (void) stkrval( alv , NLNIL , (long) RREQ );
                    775:                                    putop( PCC_CM , PCCT_INT );
                    776:                                    break;
                    777:                                case TDOUBLE:
                    778:                                    ap = stkrval( alv , NLNIL , (long) RREQ );
                    779:                                    if (isnta(ap, "d")) {
                    780:                                        sconv(p2type(ap), PCCT_DOUBLE);
                    781:                                    }
                    782:                                    putop( PCC_CM , PCCT_INT );
                    783:                                    break;
                    784:                                case TSCAL:
                    785:                                case TBOOL:
                    786:                                    putleaf( PCC_ICON , 0 , 0
                    787:                                        , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    788:                                        , "_NAM" );
                    789:                                    ap = stkrval( alv , NLNIL , (long) RREQ );
                    790:                                    sprintf( format , PREFIXFORMAT , LABELPREFIX
                    791:                                            , listnames( ap ) );
                    792:                                    putleaf( PCC_ICON , 0 , 0 ,
                    793:                                        (int) (PCCTM_PTR | PCCT_CHAR), format );
                    794:                                    putop( PCC_CM , PCCT_INT );
                    795:                                    putop( PCC_CALL , PCCT_INT );
                    796:                                    putop( PCC_CM , PCCT_INT );
                    797:                                    break;
                    798:                                case TSTR:
                    799:                                    putCONG( "" , 0 , LREQ );
                    800:                                    putop( PCC_CM , PCCT_INT );
                    801:                                    break;
                    802:                                default:
                    803:                                    panic("fmt3");
                    804:                                    break;
                    805:                                }
                    806:                                putop( PCC_CALL , PCCT_INT );
                    807:                                putdot( filename , line );
                    808:                        }
                    809:                        /*
                    810:                         * Write the string after its blank padding
                    811:                         */
                    812:                        if (typ == TSTR ) {
                    813:                                if ( opt( 't' ) ) {
                    814:                                    putleaf( PCC_ICON , 0 , 0
                    815:                                        , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    816:                                        , "_WRITES" );
                    817:                                    putRV((char *) 0 , cbn , CURFILEOFFSET ,
                    818:                                            NLOCAL , PCCTM_PTR|PCCT_STRTY );
                    819:                                    ap = stkrval(alv, NLNIL , (long) RREQ );
                    820:                                    putop( PCC_CM , PCCT_INT );
                    821:                                } else {
                    822:                                    putleaf( PCC_ICON , 0 , 0
                    823:                                        , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    824:                                        , "_fwrite" );
                    825:                                    ap = stkrval(alv, NLNIL , (long) RREQ );
                    826:                                }
                    827:                                if (strfmt & VARWIDTH) {
                    828:                                            /*
                    829:                                             *  min, inline expanded as
                    830:                                             *  temp < len ? temp : len
                    831:                                             */
                    832:                                        putRV((char *) 0 , cbn ,
                    833:                                            tempnlp -> value[ NL_OFFS ] ,
                    834:                                            tempnlp -> extra_flags , PCCT_INT );
                    835:                                        putleaf( PCC_ICON , strnglen , 0 , PCCT_INT , (char *) 0 );
                    836:                                        putop( PCC_LT , PCCT_INT );
                    837:                                        putRV((char *) 0 , cbn ,
                    838:                                            tempnlp -> value[ NL_OFFS ] ,
                    839:                                            tempnlp -> extra_flags , PCCT_INT );
                    840:                                        putleaf( PCC_ICON , strnglen , 0 , PCCT_INT , (char *) 0 );
                    841:                                        putop( PCC_COLON , PCCT_INT );
                    842:                                        putop( PCC_QUEST , PCCT_INT );
                    843:                                } else {
                    844:                                        if (   ( fmtspec & SKIP )
                    845:                                            && ( strfmt & CONWIDTH ) ) {
                    846:                                                strnglen = field;
                    847:                                        }
                    848:                                        putleaf( PCC_ICON , strnglen , 0 , PCCT_INT , (char *) 0 );
                    849:                                }
                    850:                                putop( PCC_CM , PCCT_INT );
                    851:                                putleaf( PCC_ICON , 1 , 0 , PCCT_INT , (char *) 0 );
                    852:                                putop( PCC_CM , PCCT_INT );
                    853:                                putleaf( PCC_ICON , 0 , 0
                    854:                                    , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    855:                                    , "_ACTFILE" );
                    856:                                putRV((char *) 0, cbn , CURFILEOFFSET , NLOCAL ,
                    857:                                        PCCTM_PTR|PCCT_STRTY );
                    858:                                putop( PCC_CALL , PCCT_INT );
                    859:                                putop( PCC_CM , PCCT_INT );
                    860:                                putop( PCC_CALL , PCCT_INT );
                    861:                                putdot( filename , line );
                    862:                        }
                    863:                        if (soffset_flag) {
                    864:                                tmpfree(&soffset);
                    865:                                soffset_flag = FALSE;
                    866:                        }
                    867:                }
                    868:                /*
                    869:                 * Done with arguments.
                    870:                 * Handle writeln and
                    871:                 * insufficent number of args.
                    872:                 */
                    873:                switch (p->value[0] &~ NSTAND) {
                    874:                        case O_WRITEF:
                    875:                                if (argc == 0)
                    876:                                        error("Write requires an argument");
                    877:                                break;
                    878:                        case O_MESSAGE:
                    879:                                if (argc == 0)
                    880:                                        error("Message requires an argument");
                    881:                        case O_WRITLN:
                    882:                                if (filetype != nl+T1CHAR)
                    883:                                        error("Can't 'writeln' a non text file");
                    884:                                if ( opt( 't' ) ) {
                    885:                                    putleaf( PCC_ICON , 0 , 0
                    886:                                        , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    887:                                        , "_WRITLN" );
                    888:                                    putRV((char *) 0 , cbn , CURFILEOFFSET ,
                    889:                                            NLOCAL , PCCTM_PTR|PCCT_STRTY );
                    890:                                } else {
                    891:                                    putleaf( PCC_ICON , 0 , 0
                    892:                                        , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    893:                                        , "_fputc" );
                    894:                                    putleaf( PCC_ICON , '\n' , 0 , (int) PCCT_CHAR , (char *) 0 );
                    895:                                    putleaf( PCC_ICON , 0 , 0
                    896:                                        , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    897:                                        , "_ACTFILE" );
                    898:                                    putRV((char *) 0 , cbn , CURFILEOFFSET ,
                    899:                                            NLOCAL , PCCTM_PTR|PCCT_STRTY );
                    900:                                    putop( PCC_CALL , PCCT_INT );
                    901:                                    putop( PCC_CM , PCCT_INT );
                    902:                                }
                    903:                                putop( PCC_CALL , PCCT_INT );
                    904:                                putdot( filename , line );
                    905:                                break;
                    906:                }
                    907:                return;
                    908: 
                    909:        case O_READ4:
                    910:        case O_READLN:
                    911:                /*
                    912:                 * Set up default
                    913:                 * file "input".
                    914:                 */
                    915:                file = NIL;
                    916:                filetype = nl+T1CHAR;
                    917:                /*
                    918:                 * Determine the file implied
                    919:                 * for the read and generate
                    920:                 * code to make it the active file.
                    921:                 */
                    922:                if (argv != TR_NIL) {
                    923:                        codeoff();
                    924:                        ap = stkrval(argv->list_node.list, NLNIL, (long) RREQ );
                    925:                        codeon();
                    926:                        if (ap == NLNIL)
                    927:                                argv = argv->list_node.next;
                    928:                        if (ap != NLNIL && ap->class == FILET) {
                    929:                                /*
                    930:                                 * Got "read(f, ...", make
                    931:                                 * f the active file, and save
                    932:                                 * it and its type for use in
                    933:                                 * processing the rest of the
                    934:                                 * arguments to read.
                    935:                                 */
                    936:                                file = argv->list_node.list;
                    937:                                filetype = ap->type;
                    938:                                putRV((char *) 0, cbn , CURFILEOFFSET , NLOCAL ,
                    939:                                        PCCTM_PTR|PCCT_STRTY );
                    940:                                putleaf( PCC_ICON , 0 , 0 
                    941:                                        , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                    942:                                        , "_UNIT" );
                    943:                                (void) stklval(argv->list_node.list, NOFLAGS);
                    944:                                putop( PCC_CALL , PCCT_INT );
                    945:                                putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY );
                    946:                                putdot( filename , line );
                    947:                                argv = argv->list_node.next;
                    948:                                argc--;
                    949:                        } else {
                    950:                                /*
                    951:                                 * Default is read from
                    952:                                 * standard input.
                    953:                                 */
                    954:                                putRV((char *) 0, cbn , CURFILEOFFSET , NLOCAL ,
                    955:                                        PCCTM_PTR|PCCT_STRTY );
                    956:                                putLV( "_input" , 0 , 0 , NGLOBAL ,
                    957:                                        PCCTM_PTR|PCCT_STRTY );
                    958:                                putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY );
                    959:                                putdot( filename , line );
                    960:                                input->nl_flags |= NUSED;
                    961:                        }
                    962:                } else {
                    963:                        putRV((char *) 0, cbn , CURFILEOFFSET , NLOCAL ,
                    964:                                PCCTM_PTR|PCCT_STRTY );
                    965:                        putLV( "_input" , 0 , 0 , NGLOBAL , PCCTM_PTR|PCCT_STRTY );
                    966:                        putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY );
                    967:                        putdot( filename , line );
                    968:                        input->nl_flags |= NUSED;
                    969:                }
                    970:                /*
                    971:                 * Loop and process each
                    972:                 * of the arguments.
                    973:                 */
                    974:                for (; argv != TR_NIL; argv = argv->list_node.next) {
                    975:                        /*
                    976:                         * Get the address of the target
                    977:                         * on the stack.
                    978:                         */
                    979:                        al = argv->list_node.list;
                    980:                        if (al == TR_NIL)
                    981:                                continue;
                    982:                        if (al->tag != T_VAR) {
                    983:                                error("Arguments to %s must be variables, not expressions", p->symbol);
                    984:                                continue;
                    985:                        }
                    986:                        codeoff();
                    987:                        ap = stklval(al, MOD|ASGN|NOUSE);
                    988:                        codeon();
                    989:                        if (ap == NLNIL)
                    990:                                continue;
                    991:                        if (filetype != nl+T1CHAR) {
                    992:                                /*
                    993:                                 * Generalized read, i.e.
                    994:                                 * from a non-textfile.
                    995:                                 */
                    996:                                if (incompat(filetype, ap, argv->list_node.list )) {
                    997:                                        error("Type mismatch in read from non-text file");
                    998:                                        continue;
                    999:                                }
                   1000:                                /*
                   1001:                                 * var := file ^;
                   1002:                                 */
                   1003:                                ap = lvalue( al , MOD | ASGN | NOUSE , RREQ );
                   1004:                                if ( isa( ap , "bsci" ) ) {
                   1005:                                        precheck( ap , "_RANG4" , "_RSNG4" );
                   1006:                                }
                   1007:                                putleaf( PCC_ICON , 0 , 0
                   1008:                                    , (int) (PCCM_ADDTYPE(
                   1009:                                        PCCM_ADDTYPE(
                   1010:                                            PCCM_ADDTYPE(
                   1011:                                                p2type( filetype ) , PCCTM_PTR )
                   1012:                                            , PCCTM_FTN )
                   1013:                                        , PCCTM_PTR ))
                   1014:                                    , "_FNIL" );
                   1015:                                if (file != NIL)
                   1016:                                        (void) stklval(file, NOFLAGS);
                   1017:                                else /* Magic */
                   1018:                                        putRV( "_input" , 0 , 0 , NGLOBAL ,
                   1019:                                                PCCTM_PTR | PCCT_STRTY );
                   1020:                                putop(PCC_CALL, PCCM_ADDTYPE(p2type(filetype), PCCTM_PTR));
                   1021:                                switch ( classify( filetype ) ) {
                   1022:                                    case TBOOL:
                   1023:                                    case TCHAR:
                   1024:                                    case TINT:
                   1025:                                    case TSCAL:
                   1026:                                    case TDOUBLE:
                   1027:                                    case TPTR:
                   1028:                                        putop( PCCOM_UNARY PCC_MUL
                   1029:                                                , p2type( filetype ) );
                   1030:                                }
                   1031:                                switch ( classify( filetype ) ) {
                   1032:                                    case TBOOL:
                   1033:                                    case TCHAR:
                   1034:                                    case TINT:
                   1035:                                    case TSCAL:
                   1036:                                            postcheck(ap, filetype);
                   1037:                                            sconv(p2type(filetype), p2type(ap));
                   1038:                                                /* and fall through */
                   1039:                                    case TDOUBLE:
                   1040:                                    case TPTR:
                   1041:                                            putop( PCC_ASSIGN , p2type( ap ) );
                   1042:                                            putdot( filename , line );
                   1043:                                            break;
                   1044:                                    default:
                   1045:                                            putstrop(PCC_STASG,
                   1046:                                                    PCCM_ADDTYPE(p2type(ap), PCCTM_PTR),
                   1047:                                                    (int) lwidth(ap),
                   1048:                                                    align(ap));
                   1049:                                            putdot( filename , line );
                   1050:                                            break;
                   1051:                                }
                   1052:                                /*
                   1053:                                 * get(file);
                   1054:                                 */
                   1055:                                putleaf( PCC_ICON , 0 , 0 
                   1056:                                        , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1057:                                        , "_GET" );
                   1058:                                putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL ,
                   1059:                                        PCCTM_PTR|PCCT_STRTY );
                   1060:                                putop( PCC_CALL , PCCT_INT );
                   1061:                                putdot( filename , line );
                   1062:                                continue;
                   1063:                        }
                   1064:                            /*
                   1065:                             *  if you get to here, you are reading from
                   1066:                             *  a text file.  only possiblities are:
                   1067:                             *  character, integer, real, or scalar.
                   1068:                             *  read( f , foo , ... ) is done as
                   1069:                             *  foo := read( f ) with rangechecking
                   1070:                             *  if appropriate.
                   1071:                             */
                   1072:                        typ = classify(ap);
                   1073:                        op = rdops(typ);
                   1074:                        if (op == NIL) {
                   1075:                                error("Can't read %ss from a text file", clnames[typ]);
                   1076:                                continue;
                   1077:                        }
                   1078:                            /*
                   1079:                             *  left hand side of foo := read( f )
                   1080:                             */
                   1081:                        ap = lvalue( al , MOD|ASGN|NOUSE , RREQ );
                   1082:                        if ( isa( ap , "bsci" ) ) {
                   1083:                            precheck( ap , "_RANG4" , "_RSNG4" );
                   1084:                        }
                   1085:                        switch ( op ) {
                   1086:                            case O_READC:
                   1087:                                readname = "_READC";
                   1088:                                readtype = PCCT_INT;
                   1089:                                break;
                   1090:                            case O_READ4:
                   1091:                                readname = "_READ4";
                   1092:                                readtype = PCCT_INT;
                   1093:                                break;
                   1094:                            case O_READ8:
                   1095:                                readname = "_READ8";
                   1096:                                readtype = PCCT_DOUBLE;
                   1097:                                break;
                   1098:                            case O_READE:
                   1099:                                readname = "_READE";
                   1100:                                readtype = PCCT_INT;
                   1101:                                break;
                   1102:                        }
                   1103:                        putleaf( PCC_ICON , 0 , 0
                   1104:                                , (int) PCCM_ADDTYPE( PCCTM_FTN | readtype , PCCTM_PTR )
                   1105:                                , readname );
                   1106:                        putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL ,
                   1107:                                PCCTM_PTR|PCCT_STRTY );
                   1108:                        if ( op == O_READE ) {
                   1109:                                sprintf( format , PREFIXFORMAT , LABELPREFIX
                   1110:                                        , listnames( ap ) );
                   1111:                                putleaf( PCC_ICON , 0, 0, (int) (PCCTM_PTR | PCCT_CHAR),
                   1112:                                        format );
                   1113:                                putop( PCC_CM , PCCT_INT );
                   1114:                                warning();
                   1115:                                if (opt('s')) {
                   1116:                                        standard();
                   1117:                                }
                   1118:                                error("Reading scalars from text files is non-standard");
                   1119:                        }
                   1120:                        putop( PCC_CALL , (int) readtype );
                   1121:                        if ( isa( ap , "bcsi" ) ) {
                   1122:                            postcheck(ap, readtype==PCCT_INT?nl+T4INT:nl+TDOUBLE);
                   1123:                        }
                   1124:                        sconv((int) readtype, p2type(ap));
                   1125:                        putop( PCC_ASSIGN , p2type( ap ) );
                   1126:                        putdot( filename , line );
                   1127:                }
                   1128:                /*
                   1129:                 * Done with arguments.
                   1130:                 * Handle readln and
                   1131:                 * insufficient number of args.
                   1132:                 */
                   1133:                if (p->value[0] == O_READLN) {
                   1134:                        if (filetype != nl+T1CHAR)
                   1135:                                error("Can't 'readln' a non text file");
                   1136:                        putleaf( PCC_ICON , 0 , 0 
                   1137:                                , (int) PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1138:                                , "_READLN" );
                   1139:                        putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL ,
                   1140:                                PCCTM_PTR|PCCT_STRTY );
                   1141:                        putop( PCC_CALL , PCCT_INT );
                   1142:                        putdot( filename , line );
                   1143:                } else if (argc == 0)
                   1144:                        error("read requires an argument");
                   1145:                return;
                   1146: 
                   1147:        case O_GET:
                   1148:        case O_PUT:
                   1149:                if (argc != 1) {
                   1150:                        error("%s expects one argument", p->symbol);
                   1151:                        return;
                   1152:                }
                   1153:                putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
                   1154:                putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1155:                        , "_UNIT" );
                   1156:                ap = stklval(argv->list_node.list, NOFLAGS);
                   1157:                if (ap == NLNIL)
                   1158:                        return;
                   1159:                if (ap->class != FILET) {
                   1160:                        error("Argument to %s must be a file, not %s", p->symbol, nameof(ap));
                   1161:                        return;
                   1162:                }
                   1163:                putop( PCC_CALL , PCCT_INT );
                   1164:                putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY );
                   1165:                putdot( filename , line );
                   1166:                putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1167:                        , op == O_GET ? "_GET" : "_PUT" );
                   1168:                putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
                   1169:                putop( PCC_CALL , PCCT_INT );
                   1170:                putdot( filename , line );
                   1171:                return;
                   1172: 
                   1173:        case O_RESET:
                   1174:        case O_REWRITE:
                   1175:                if (argc == 0 || argc > 2) {
                   1176:                        error("%s expects one or two arguments", p->symbol);
                   1177:                        return;
                   1178:                }
                   1179:                if (opt('s') && argc == 2) {
                   1180:                        standard();
                   1181:                        error("Two argument forms of reset and rewrite are non-standard");
                   1182:                }
                   1183:                putleaf( PCC_ICON , 0 , 0 , PCCT_INT
                   1184:                        , op == O_RESET ? "_RESET" : "_REWRITE" );
                   1185:                ap = stklval(argv->list_node.list, MOD|NOUSE);
                   1186:                if (ap == NLNIL)
                   1187:                        return;
                   1188:                if (ap->class != FILET) {
                   1189:                        error("First argument to %s must be a file, not %s", p->symbol, nameof(ap));
                   1190:                        return;
                   1191:                }
                   1192:                if (argc == 2) {
                   1193:                        /*
                   1194:                         * Optional second argument
                   1195:                         * is a string name of a
                   1196:                         * UNIX (R) file to be associated.
                   1197:                         */
                   1198:                        al = argv->list_node.next;
                   1199:                        al = (struct tnode *) stkrval(al->list_node.list,
                   1200:                                        NLNIL , (long) RREQ );
                   1201:                        if (al == TR_NIL)
                   1202:                                return;
                   1203:                        if (classify((struct nl *) al) != TSTR) {
                   1204:                                error("Second argument to %s must be a string, not %s", p->symbol, nameof((struct nl *) al));
                   1205:                                return;
                   1206:                        }
                   1207:                        strnglen = width((struct nl *) al);
                   1208:                } else {
                   1209:                        putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 );
                   1210:                        strnglen = 0;
                   1211:                }
                   1212:                putop( PCC_CM , PCCT_INT );
                   1213:                putleaf( PCC_ICON , strnglen , 0 , PCCT_INT , (char *) 0 );
                   1214:                putop( PCC_CM , PCCT_INT );
                   1215:                putleaf( PCC_ICON , text(ap) ? 0: width(ap->type) , 0 , PCCT_INT , (char *) 0 );
                   1216:                putop( PCC_CM , PCCT_INT );
                   1217:                putop( PCC_CALL , PCCT_INT );
                   1218:                putdot( filename , line );
                   1219:                return;
                   1220: 
                   1221:        case O_NEW:
                   1222:        case O_DISPOSE:
                   1223:                if (argc == 0) {
                   1224:                        error("%s expects at least one argument", p->symbol);
                   1225:                        return;
                   1226:                }
                   1227:                alv = argv->list_node.list;
                   1228:                codeoff();
                   1229:                ap = stklval(alv, op == O_NEW ? ( MOD | NOUSE ) : MOD );
                   1230:                codeon();
                   1231:                if (ap == NLNIL)
                   1232:                        return;
                   1233:                if (ap->class != PTR) {
                   1234:                        error("(First) argument to %s must be a pointer, not %s", p->symbol, nameof(ap));
                   1235:                        return;
                   1236:                }
                   1237:                ap = ap->type;
                   1238:                if (ap == NLNIL)
                   1239:                        return;
                   1240:                if (op == O_NEW)
                   1241:                        cmd = "_NEW";
                   1242:                else /* op == O_DISPOSE */
                   1243:                        if ((ap->nl_flags & NFILES) != 0)
                   1244:                                cmd = "_DFDISPOSE";
                   1245:                        else
                   1246:                                cmd = "_DISPOSE";
                   1247:                putleaf( PCC_ICON, 0, 0, PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ), cmd);
                   1248:                (void) stklval(alv, op == O_NEW ? ( MOD | NOUSE ) : MOD );
                   1249:                argv = argv->list_node.next;
                   1250:                if (argv != TR_NIL) {
                   1251:                        if (ap->class != RECORD) {
                   1252:                                error("Record required when specifying variant tags");
                   1253:                                return;
                   1254:                        }
                   1255:                        for (; argv != TR_NIL; argv = argv->list_node.next) {
                   1256:                                if (ap->ptr[NL_VARNT] == NIL) {
                   1257:                                        error("Too many tag fields");
                   1258:                                        return;
                   1259:                                }
                   1260:                                if (!isconst(argv->list_node.list)) {
                   1261:                                        error("Second and successive arguments to %s must be constants", p->symbol);
                   1262:                                        return;
                   1263:                                }
                   1264:                                gconst(argv->list_node.list);
                   1265:                                if (con.ctype == NIL)
                   1266:                                        return;
                   1267:                                if (incompat(con.ctype, (ap->ptr[NL_TAG])->type , TR_NIL )) {
                   1268:                                        cerror("Specified tag constant type clashed with variant case selector type");
                   1269:                                        return;
                   1270:                                }
                   1271:                                for (ap = ap->ptr[NL_VARNT]; ap != NIL; ap = ap->chain)
                   1272:                                        if (ap->range[0] == con.crval)
                   1273:                                                break;
                   1274:                                if (ap == NIL) {
                   1275:                                        error("No variant case label value equals specified constant value");
                   1276:                                        return;
                   1277:                                }
                   1278:                                ap = ap->ptr[NL_VTOREC];
                   1279:                        }
                   1280:                }
                   1281:                putleaf( PCC_ICON , width( ap ) , 0 , PCCT_INT , (char *) 0 );
                   1282:                putop( PCC_CM , PCCT_INT );
                   1283:                putop( PCC_CALL , PCCT_INT );
                   1284:                putdot( filename , line );
                   1285:                if (opt('t') && op == O_NEW) {
                   1286:                    putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1287:                            , "_blkclr" );
                   1288:                    (void) stkrval(alv, NLNIL , (long) RREQ );
                   1289:                    putleaf( PCC_ICON , width( ap ) , 0 , PCCT_INT , (char *) 0 );
                   1290:                    putop( PCC_CM , PCCT_INT );
                   1291:                    putop( PCC_CALL , PCCT_INT );
                   1292:                    putdot( filename , line );
                   1293:                }
                   1294:                return;
                   1295: 
                   1296:        case O_DATE:
                   1297:        case O_TIME:
                   1298:                if (argc != 1) {
                   1299:                        error("%s expects one argument", p->symbol);
                   1300:                        return;
                   1301:                }
                   1302:                putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1303:                        , op == O_DATE ? "_DATE" : "_TIME" );
                   1304:                ap = stklval(argv->list_node.list, MOD|NOUSE);
                   1305:                if (ap == NIL)
                   1306:                        return;
                   1307:                if (classify(ap) != TSTR || width(ap) != 10) {
                   1308:                        error("Argument to %s must be a alfa, not %s", p->symbol, nameof(ap));
                   1309:                        return;
                   1310:                }
                   1311:                putop( PCC_CALL , PCCT_INT );
                   1312:                putdot( filename , line );
                   1313:                return;
                   1314: 
                   1315:        case O_HALT:
                   1316:                if (argc != 0) {
                   1317:                        error("halt takes no arguments");
                   1318:                        return;
                   1319:                }
                   1320:                putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1321:                        , "_HALT" );
                   1322: 
                   1323:                putop( PCCOM_UNARY PCC_CALL , PCCT_INT );
                   1324:                putdot( filename , line );
                   1325:                noreach = TRUE;
                   1326:                return;
                   1327: 
                   1328:        case O_ARGV:
                   1329:                if (argc != 2) {
                   1330:                        error("argv takes two arguments");
                   1331:                        return;
                   1332:                }
                   1333:                putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1334:                        , "_ARGV" );
                   1335:                ap = stkrval(argv->list_node.list, NLNIL , (long) RREQ );
                   1336:                if (ap == NLNIL)
                   1337:                        return;
                   1338:                if (isnta(ap, "i")) {
                   1339:                        error("argv's first argument must be an integer, not %s", nameof(ap));
                   1340:                        return;
                   1341:                }
                   1342:                al = argv->list_node.next;
                   1343:                ap = stklval(al->list_node.list, MOD|NOUSE);
                   1344:                if (ap == NLNIL)
                   1345:                        return;
                   1346:                if (classify(ap) != TSTR) {
                   1347:                        error("argv's second argument must be a string, not %s", nameof(ap));
                   1348:                        return;
                   1349:                }
                   1350:                putop( PCC_CM , PCCT_INT );
                   1351:                putleaf( PCC_ICON , width( ap ) , 0 , PCCT_INT , (char *) 0 );
                   1352:                putop( PCC_CM , PCCT_INT );
                   1353:                putop( PCC_CALL , PCCT_INT );
                   1354:                putdot( filename , line );
                   1355:                return;
                   1356: 
                   1357:        case O_STLIM:
                   1358:                if (argc != 1) {
                   1359:                        error("stlimit requires one argument");
                   1360:                        return;
                   1361:                }
                   1362:                putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1363:                        , "_STLIM" );
                   1364:                ap = stkrval(argv->list_node.list, NLNIL , (long) RREQ );
                   1365:                if (ap == NLNIL)
                   1366:                        return;
                   1367:                if (isnta(ap, "i")) {
                   1368:                        error("stlimit's argument must be an integer, not %s", nameof(ap));
                   1369:                        return;
                   1370:                }
                   1371:                putop( PCC_CALL , PCCT_INT );
                   1372:                putdot( filename , line );
                   1373:                return;
                   1374: 
                   1375:        case O_REMOVE:
                   1376:                if (argc != 1) {
                   1377:                        error("remove expects one argument");
                   1378:                        return;
                   1379:                }
                   1380:                putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1381:                        , "_REMOVE" );
                   1382:                ap = stkrval(argv->list_node.list, NLNIL, (long) RREQ );
                   1383:                if (ap == NLNIL)
                   1384:                        return;
                   1385:                if (classify(ap) != TSTR) {
                   1386:                        error("remove's argument must be a string, not %s", nameof(ap));
                   1387:                        return;
                   1388:                }
                   1389:                putleaf( PCC_ICON , width( ap ) , 0 , PCCT_INT , (char *) 0 );
                   1390:                putop( PCC_CM , PCCT_INT );
                   1391:                putop( PCC_CALL , PCCT_INT );
                   1392:                putdot( filename , line );
                   1393:                return;
                   1394: 
                   1395:        case O_LLIMIT:
                   1396:                if (argc != 2) {
                   1397:                        error("linelimit expects two arguments");
                   1398:                        return;
                   1399:                }
                   1400:                putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1401:                        , "_LLIMIT" );
                   1402:                ap = stklval(argv->list_node.list, NOFLAGS|NOUSE);
                   1403:                if (ap == NLNIL)
                   1404:                        return;
                   1405:                if (!text(ap)) {
                   1406:                        error("linelimit's first argument must be a text file, not %s", nameof(ap));
                   1407:                        return;
                   1408:                }
                   1409:                al = argv->list_node.next;
                   1410:                ap = stkrval(al->list_node.list, NLNIL , (long) RREQ );
                   1411:                if (ap == NLNIL)
                   1412:                        return;
                   1413:                if (isnta(ap, "i")) {
                   1414:                        error("linelimit's second argument must be an integer, not %s", nameof(ap));
                   1415:                        return;
                   1416:                }
                   1417:                putop( PCC_CM , PCCT_INT );
                   1418:                putop( PCC_CALL , PCCT_INT );
                   1419:                putdot( filename , line );
                   1420:                return;
                   1421:        case O_PAGE:
                   1422:                if (argc != 1) {
                   1423:                        error("page expects one argument");
                   1424:                        return;
                   1425:                }
                   1426:                putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
                   1427:                putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1428:                        , "_UNIT" );
                   1429:                ap = stklval(argv->list_node.list, NOFLAGS);
                   1430:                if (ap == NLNIL)
                   1431:                        return;
                   1432:                if (!text(ap)) {
                   1433:                        error("Argument to page must be a text file, not %s", nameof(ap));
                   1434:                        return;
                   1435:                }
                   1436:                putop( PCC_CALL , PCCT_INT );
                   1437:                putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY );
                   1438:                putdot( filename , line );
                   1439:                if ( opt( 't' ) ) {
                   1440:                    putleaf( PCC_ICON , 0 , 0
                   1441:                        , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1442:                        , "_PAGE" );
                   1443:                    putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
                   1444:                } else {
                   1445:                    putleaf( PCC_ICON , 0 , 0
                   1446:                        , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1447:                        , "_fputc" );
                   1448:                    putleaf( PCC_ICON , '\f' , 0 , (int) PCCT_CHAR , (char *) 0 );
                   1449:                    putleaf( PCC_ICON , 0 , 0
                   1450:                        , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1451:                        , "_ACTFILE" );
                   1452:                    putRV((char *) 0 , cbn , CURFILEOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
                   1453:                    putop( PCC_CALL , PCCT_INT );
                   1454:                    putop( PCC_CM , PCCT_INT );
                   1455:                }
                   1456:                putop( PCC_CALL , PCCT_INT );
                   1457:                putdot( filename , line );
                   1458:                return;
                   1459: 
                   1460:        case O_ASRT:
                   1461:                if (!opt('t'))
                   1462:                        return;
                   1463:                if (argc == 0 || argc > 2) {
                   1464:                        error("Assert expects one or two arguments");
                   1465:                        return;
                   1466:                }
                   1467:                if (argc == 2)
                   1468:                        cmd = "_ASRTS";
                   1469:                else
                   1470:                        cmd = "_ASRT";
                   1471:                putleaf( PCC_ICON , 0 , 0
                   1472:                    , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , cmd );
                   1473:                ap = stkrval(argv->list_node.list, NLNIL , (long) RREQ );
                   1474:                if (ap == NLNIL)
                   1475:                        return;
                   1476:                if (isnta(ap, "b"))
                   1477:                        error("Assert expression must be Boolean, not %ss", nameof(ap));
                   1478:                if (argc == 2) {
                   1479:                        /*
                   1480:                         * Optional second argument is a string specifying
                   1481:                         * why the assertion failed.
                   1482:                         */
                   1483:                        al = argv->list_node.next;
                   1484:                        al = (struct tnode *) stkrval(al->list_node.list, NLNIL , (long) RREQ );
                   1485:                        if (al == TR_NIL)
                   1486:                                return;
                   1487:                        if (classify((struct nl *) al) != TSTR) {
                   1488:                                error("Second argument to assert must be a string, not %s", nameof((struct nl *) al));
                   1489:                                return;
                   1490:                        }
                   1491:                        putop( PCC_CM , PCCT_INT );
                   1492:                }
                   1493:                putop( PCC_CALL , PCCT_INT );
                   1494:                putdot( filename , line );
                   1495:                return;
                   1496: 
                   1497:        case O_PACK:
                   1498:                if (argc != 3) {
                   1499:                        error("pack expects three arguments");
                   1500:                        return;
                   1501:                }
                   1502:                putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1503:                        , "_PACK" );
                   1504:                pu = "pack(a,i,z)";
                   1505:                pua = (al = argv)->list_node.list;
                   1506:                pui = (al = al->list_node.next)->list_node.list;
                   1507:                puz = (al = al->list_node.next)->list_node.list;
                   1508:                goto packunp;
                   1509:        case O_UNPACK:
                   1510:                if (argc != 3) {
                   1511:                        error("unpack expects three arguments");
                   1512:                        return;
                   1513:                }
                   1514:                putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
                   1515:                        , "_UNPACK" );
                   1516:                pu = "unpack(z,a,i)";
                   1517:                puz = (al = argv)->list_node.list;
                   1518:                pua = (al = al->list_node.next)->list_node.list;
                   1519:                pui = (al = al->list_node.next)->list_node.list;
                   1520: packunp:
                   1521:                ap = stkrval(pui, NLNIL , (long) RREQ );
                   1522:                if (ap == NIL)
                   1523:                        return;
                   1524:                ap = stklval(pua, op == O_PACK ? NOFLAGS : MOD|NOUSE);
                   1525:                if (ap == NIL)
                   1526:                        return;
                   1527:                if (ap->class != ARRAY) {
                   1528:                        error("%s requires a to be an unpacked array, not %s", pu, nameof(ap));
                   1529:                        return;
                   1530:                }
                   1531:                putop( PCC_CM , PCCT_INT );
                   1532:                al = (struct tnode *) stklval(puz, op == O_UNPACK ? NOFLAGS : MOD|NOUSE);
                   1533:                if (((struct nl *) al)->class != ARRAY) {
                   1534:                        error("%s requires z to be a packed array, not %s", pu, nameof(ap));
                   1535:                        return;
                   1536:                }
                   1537:                if (((struct nl *) al)->type == NIL || 
                   1538:                        ((struct nl *) ap)->type == NIL)
                   1539:                        return;
                   1540:                if (((struct nl *) al)->type != ((struct nl *) ap)->type) {
                   1541:                        error("%s requires a and z to be arrays of the same type", pu, nameof(ap));
                   1542:                        return;
                   1543:                }
                   1544:                putop( PCC_CM , PCCT_INT );
                   1545:                k = width((struct nl *) al);
                   1546:                itemwidth = width(ap->type);
                   1547:                ap = ap->chain;
                   1548:                al = ((struct tnode *) ((struct nl *) al)->chain);
                   1549:                if (ap->chain != NIL || ((struct nl *) al)->chain != NIL) {
                   1550:                        error("%s requires a and z to be single dimension arrays", pu);
                   1551:                        return;
                   1552:                }
                   1553:                if (ap == NIL || al == NIL)
                   1554:                        return;
                   1555:                /*
                   1556:                 * al is the range for z i.e. u..v
                   1557:                 * ap is the range for a i.e. m..n
                   1558:                 * i will be n-m+1
                   1559:                 * j will be v-u+1
                   1560:                 */
                   1561:                i = ap->range[1] - ap->range[0] + 1;
                   1562:                j = ((struct nl *) al)->range[1] - 
                   1563:                        ((struct nl *) al)->range[0] + 1;
                   1564:                if (i < j) {
                   1565:                        error("%s cannot have more elements in a (%d) than in z (%d)", pu, (char *) j, (char *) i);
                   1566:                        return;
                   1567:                }
                   1568:                /*
                   1569:                 * get n-m-(v-u) and m for the interpreter
                   1570:                 */
                   1571:                i -= j;
                   1572:                j = ap->range[0];
                   1573:                putleaf( PCC_ICON , itemwidth , 0 , PCCT_INT , (char *) 0 );
                   1574:                putop( PCC_CM , PCCT_INT );
                   1575:                putleaf( PCC_ICON , j , 0 , PCCT_INT , (char *) 0 );
                   1576:                putop( PCC_CM , PCCT_INT );
                   1577:                putleaf( PCC_ICON , i , 0 , PCCT_INT , (char *) 0 );
                   1578:                putop( PCC_CM , PCCT_INT );
                   1579:                putleaf( PCC_ICON , k , 0 , PCCT_INT , (char *) 0 );
                   1580:                putop( PCC_CM , PCCT_INT );
                   1581:                putop( PCC_CALL , PCCT_INT );
                   1582:                putdot( filename , line );
                   1583:                return;
                   1584:        case 0:
                   1585:                error("%s is an unimplemented extension", p->symbol);
                   1586:                return;
                   1587: 
                   1588:        default:
                   1589:                panic("proc case");
                   1590:        }
                   1591: }
                   1592: #endif PC

unix.superglobalmegacorp.com

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