Annotation of researchv10no/cmd/f2c/putpcc.c, revision 1.1.1.1

1.1       root        1: /****************************************************************
                      2: Copyright 1990, 1991, 1992, 1993 by AT&T Bell Laboratories and Bellcore.
                      3: 
                      4: Permission to use, copy, modify, and distribute this software
                      5: and its documentation for any purpose and without fee is hereby
                      6: granted, provided that the above copyright notice appear in all
                      7: copies and that both that the copyright notice and this
                      8: permission notice and warranty disclaimer appear in supporting
                      9: documentation, and that the names of AT&T Bell Laboratories or
                     10: Bellcore or any of their entities not be used in advertising or
                     11: publicity pertaining to distribution of the software without
                     12: specific, written prior permission.
                     13: 
                     14: AT&T and Bellcore disclaim all warranties with regard to this
                     15: software, including all implied warranties of merchantability
                     16: and fitness.  In no event shall AT&T or Bellcore be liable for
                     17: any special, indirect or consequential damages or any damages
                     18: whatsoever resulting from loss of use, data or profits, whether
                     19: in an action of contract, negligence or other tortious action,
                     20: arising out of or in connection with the use or performance of
                     21: this software.
                     22: ****************************************************************/
                     23: 
                     24: /* INTERMEDIATE CODE GENERATION FOR S. C. JOHNSON C COMPILERS */
                     25: /* NEW VERSION USING BINARY POLISH POSTFIX INTERMEDIATE */
                     26: 
                     27: #include "defs.h"
                     28: #include "pccdefs.h"
                     29: #include "output.h"            /* for nice_printf */
                     30: #include "names.h"
                     31: #include "p1defs.h"
                     32: 
                     33: Addrp realpart();
                     34: LOCAL Addrp intdouble(), putcx1(), putcxeq (), putch1 ();
                     35: LOCAL putct1 ();
                     36: 
                     37: expptr putcxop();
                     38: LOCAL expptr putcall (), putmnmx (), putcheq(), putcat ();
                     39: LOCAL expptr putaddr(), putchcmp (), putpower(), putop();
                     40: LOCAL expptr putcxcmp ();
                     41: expptr imagpart();
                     42: ftnint lencat();
                     43: 
                     44: #define FOUR 4
                     45: extern int ops2[];
                     46: extern int proc_argchanges, proc_protochanges;
                     47: extern int krparens;
                     48: 
                     49: #define P2BUFFMAX 128
                     50: 
                     51: /* Puthead -- output the header information about subroutines, functions
                     52:    and entry points */
                     53: 
                     54: puthead(s, class)
                     55: char *s;
                     56: int class;
                     57: {
                     58:        if (headerdone == NO) {
                     59:                if (class == CLMAIN)
                     60:                        s = "MAIN__";
                     61:                p1_head (class, s);
                     62:                headerdone = YES;
                     63:                }
                     64: }
                     65: 
                     66: putif(p, else_if_p)
                     67:  register expptr p;
                     68:  int else_if_p;
                     69: {
                     70:        register int k;
                     71:        int n;
                     72:        long where;
                     73: 
                     74:        if (else_if_p) {
                     75:                p1put(P1_ELSEIFSTART);
                     76:                where = ftell(pass1_file);
                     77:                }
                     78:        if( !ISLOGICAL((k = (p = fixtype(p))->headblock.vtype )) )
                     79:        {
                     80:                if(k != TYERROR)
                     81:                        err("non-logical expression in IF statement");
                     82:                }
                     83:        else {
                     84:                if (else_if_p) {
                     85:                        if (ei_next >= ei_last)
                     86:                                {
                     87:                                k = ei_last - ei_first;
                     88:                                n = k + 100;
                     89:                                ei_next = mem(n,0);
                     90:                                ei_last = ei_first + n;
                     91:                                if (k)
                     92:                                        memcpy(ei_next, ei_first, k);
                     93:                                ei_first =  ei_next;
                     94:                                ei_next += k;
                     95:                                ei_last = ei_first + n;
                     96:                                }
                     97:                        p = putx(p);
                     98:                        if (*ei_next++ = ftell(pass1_file) > where) {
                     99:                                p1_if(p);
                    100:                                new_endif();
                    101:                                }
                    102:                        else
                    103:                                p1_elif(p);
                    104:                        }
                    105:                else {
                    106:                        p = putx(p);
                    107:                        p1_if(p);
                    108:                        }
                    109:                }
                    110:        }
                    111: 
                    112: 
                    113: putout(p)
                    114: expptr p;
                    115: {
                    116:        p1_expr (p);
                    117: 
                    118: /* Used to make temporaries in holdtemps available here, but they */
                    119: /* may be reused too soon (e.g. when multiple **'s are involved). */
                    120: }
                    121: 
                    122: 
                    123: 
                    124: putcmgo(index, nlab, labs)
                    125: expptr index;
                    126: int nlab;
                    127: struct Labelblock *labs[];
                    128: {
                    129:        if(! ISINT(index->headblock.vtype) )
                    130:        {
                    131:                execerr("computed goto index must be integer", CNULL);
                    132:                return;
                    133:        }
                    134: 
                    135:        p1comp_goto (index, nlab, labs);
                    136: }
                    137: 
                    138:  static expptr
                    139: krput(p)
                    140:  register expptr p;
                    141: {
                    142:        register expptr e, e1;
                    143:        register unsigned op;
                    144:        int t = krparens == 2 ? TYDREAL : p->exprblock.vtype;
                    145: 
                    146:        op = p->exprblock.opcode;
                    147:        e = p->exprblock.leftp;
                    148:        if (e->tag == TEXPR && e->exprblock.opcode == op) {
                    149:                e1 = (expptr)mktmp(t, ENULL);
                    150:                putout(putassign(cpexpr(e1), e));
                    151:                p->exprblock.leftp = e1;
                    152:                }
                    153:        else
                    154:                p->exprblock.leftp = putx(e);
                    155: 
                    156:        e = p->exprblock.rightp;
                    157:        if (e->tag == TEXPR && e->exprblock.opcode == op) {
                    158:                e1 = (expptr)mktmp(t, ENULL);
                    159:                putout(putassign(cpexpr(e1), e));
                    160:                p->exprblock.rightp = e1;
                    161:                }
                    162:        else
                    163:                p->exprblock.rightp = putx(e);
                    164:        return p;
                    165:        }
                    166: 
                    167: expptr putx(p)
                    168:  register expptr p;
                    169: {
                    170:        int opc;
                    171:        int k;
                    172: 
                    173:        if (p)
                    174:          switch(p->tag)
                    175:        {
                    176:        case TERROR:
                    177:                break;
                    178: 
                    179:        case TCONST:
                    180:                switch(p->constblock.vtype)
                    181:                {
                    182:                case TYLOGICAL1:
                    183:                case TYLOGICAL2:
                    184:                case TYLOGICAL:
                    185: #ifdef TYQUAD
                    186:                case TYQUAD:
                    187: #endif
                    188:                case TYLONG:
                    189:                case TYSHORT:
                    190:                case TYINT1:
                    191:                        break;
                    192: 
                    193:                case TYADDR:
                    194:                        break;
                    195:                case TYREAL:
                    196:                case TYDREAL:
                    197: 
                    198: /* Don't write it out to the p2 file, since you'd need to call putconst,
                    199:    which is just what we need to avoid in the translator */
                    200: 
                    201:                        break;
                    202:                default:
                    203:                        p = putx( (expptr)putconst((Constp)p) );
                    204:                        break;
                    205:                }
                    206:                break;
                    207: 
                    208:        case TEXPR:
                    209:                switch(opc = p->exprblock.opcode)
                    210:                {
                    211:                case OPCALL:
                    212:                case OPCCALL:
                    213:                        if( ISCOMPLEX(p->exprblock.vtype) )
                    214:                                p = putcxop(p);
                    215:                        else    p = putcall(p, (Addrp *)NULL);
                    216:                        break;
                    217: 
                    218:                case OPMIN:
                    219:                case OPMAX:
                    220:                        p = putmnmx(p);
                    221:                        break;
                    222: 
                    223: 
                    224:                case OPASSIGN:
                    225:                        if(ISCOMPLEX(p->exprblock.leftp->headblock.vtype)
                    226:                            || ISCOMPLEX(p->exprblock.rightp->headblock.vtype)) {
                    227:                                (void) putcxeq(p);
                    228:                                p = ENULL;
                    229:                        } else if( ISCHAR(p) )
                    230:                                p = putcheq(p);
                    231:                        else
                    232:                                goto putopp;
                    233:                        break;
                    234: 
                    235:                case OPEQ:
                    236:                case OPNE:
                    237:                        if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) ||
                    238:                            ISCOMPLEX(p->exprblock.rightp->headblock.vtype) )
                    239:                        {
                    240:                                p = putcxcmp(p);
                    241:                                break;
                    242:                        }
                    243:                case OPLT:
                    244:                case OPLE:
                    245:                case OPGT:
                    246:                case OPGE:
                    247:                        if(ISCHAR(p->exprblock.leftp))
                    248:                        {
                    249:                                p = putchcmp(p);
                    250:                                break;
                    251:                        }
                    252:                        goto putopp;
                    253: 
                    254:                case OPPOWER:
                    255:                        p = putpower(p);
                    256:                        break;
                    257: 
                    258:                case OPSTAR:
                    259:                        /*   m * (2**k) -> m<<k   */
                    260:                        if(INT(p->exprblock.leftp->headblock.vtype) &&
                    261:                            ISICON(p->exprblock.rightp) &&
                    262:                            ( (k = log_2(p->exprblock.rightp->constblock.Const.ci))>0) )
                    263:                        {
                    264:                                p->exprblock.opcode = OPLSHIFT;
                    265:                                frexpr(p->exprblock.rightp);
                    266:                                p->exprblock.rightp = ICON(k);
                    267:                                goto putopp;
                    268:                        }
                    269:                        if (krparens && ISREAL(p->exprblock.vtype))
                    270:                                return krput(p);
                    271: 
                    272:                case OPMOD:
                    273:                        goto putopp;
                    274:                case OPPLUS:
                    275:                        if (krparens && ISREAL(p->exprblock.vtype))
                    276:                                return krput(p);
                    277:                case OPMINUS:
                    278:                case OPSLASH:
                    279:                case OPNEG:
                    280:                case OPNEG1:
                    281:                case OPABS:
                    282:                case OPDABS:
                    283:                        if( ISCOMPLEX(p->exprblock.vtype) )
                    284:                                p = putcxop(p);
                    285:                        else    goto putopp;
                    286:                        break;
                    287: 
                    288:                case OPCONV:
                    289:                        if( ISCOMPLEX(p->exprblock.vtype) )
                    290:                                p = putcxop(p);
                    291:                        else if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) )
                    292:                        {
                    293:                                p = putx( mkconv(p->exprblock.vtype,
                    294:                                    (expptr)realpart(putcx1(p->exprblock.leftp))));
                    295:                        }
                    296:                        else    goto putopp;
                    297:                        break;
                    298: 
                    299:                case OPNOT:
                    300:                case OPOR:
                    301:                case OPAND:
                    302:                case OPEQV:
                    303:                case OPNEQV:
                    304:                case OPADDR:
                    305:                case OPPLUSEQ:
                    306:                case OPSTAREQ:
                    307:                case OPCOMMA:
                    308:                case OPQUEST:
                    309:                case OPCOLON:
                    310:                case OPBITOR:
                    311:                case OPBITAND:
                    312:                case OPBITXOR:
                    313:                case OPBITNOT:
                    314:                case OPLSHIFT:
                    315:                case OPRSHIFT:
                    316:                case OPASSIGNI:
                    317:                case OPIDENTITY:
                    318:                case OPCHARCAST:
                    319:                case OPMIN2:
                    320:                case OPMAX2:
                    321:                case OPDMIN:
                    322:                case OPDMAX:
                    323: putopp:
                    324:                        p = putop(p);
                    325:                        break;
                    326: 
                    327:                case OPCONCAT:
                    328:                        /* weird things like ichar(a//a) */
                    329:                        p = (expptr)putch1(p);
                    330:                        break;
                    331: 
                    332:                default:
                    333:                        badop("putx", opc);
                    334:                        p = errnode ();
                    335:                }
                    336:                break;
                    337: 
                    338:        case TADDR:
                    339:                p = putaddr(p);
                    340:                break;
                    341: 
                    342:        default:
                    343:                badtag("putx", p->tag);
                    344:                p = errnode ();
                    345:        }
                    346: 
                    347:        return p;
                    348: }
                    349: 
                    350: 
                    351: 
                    352: LOCAL expptr putop(p)
                    353: expptr p;
                    354: {
                    355:        expptr lp, tp;
                    356:        int pt, lt, lt1;
                    357:        int comma;
                    358: 
                    359:        switch(p->exprblock.opcode)     /* check for special cases and rewrite */
                    360:        {
                    361:        case OPCONV:
                    362:                pt = p->exprblock.vtype;
                    363:                lp = p->exprblock.leftp;
                    364:                lt = lp->headblock.vtype;
                    365: 
                    366: /* Simplify nested type casts */
                    367: 
                    368:                while(p->tag==TEXPR && p->exprblock.opcode==OPCONV &&
                    369:                    ( (ISREAL(pt)&&ONEOF(lt,MSKREAL|MSKCOMPLEX)) ||
                    370:                    (INT(pt)&&(ONEOF(lt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) ))
                    371:                {
                    372:                        if(pt==TYDREAL && lt==TYREAL)
                    373:                        {
                    374:                                if(lp->tag==TEXPR
                    375:                                && lp->exprblock.opcode == OPCONV) {
                    376:                                    lt1 = lp->exprblock.leftp->headblock.vtype;
                    377:                                    if (lt1 == TYDREAL) {
                    378:                                        lp->exprblock.leftp =
                    379:                                                putx(lp->exprblock.leftp);
                    380:                                        return p;
                    381:                                        }
                    382:                                    if (lt1 == TYDCOMPLEX) {
                    383:                                        lp->exprblock.leftp = putx(
                    384:                                                (expptr)realpart(
                    385:                                                putcx1(lp->exprblock.leftp)));
                    386:                                        return p;
                    387:                                        }
                    388:                                    }
                    389:                                break;
                    390:                        }
                    391:                        else if (ISREAL(pt) && ISCOMPLEX(lt)) {
                    392:                                p->exprblock.leftp = putx(mkconv(pt,
                    393:                                        (expptr)realpart(
                    394:                                                putcx1(p->exprblock.leftp))));
                    395:                                break;
                    396:                                }
                    397:                        if(lt==TYCHAR && lp->tag==TEXPR &&
                    398:                            lp->exprblock.opcode==OPCALL)
                    399:                        {
                    400: 
                    401: /* May want to make a comma expression here instead.  I had one, but took
                    402:    it out for my convenience, not for the convenience of the end user */
                    403: 
                    404:                                putout (putcall (lp, (Addrp *) &(p ->
                    405:                                    exprblock.leftp)));
                    406:                                return putop (p);
                    407:                        }
                    408:                        if (lt == TYCHAR) {
                    409:                                p->exprblock.leftp = putx(p->exprblock.leftp);
                    410:                                return p;
                    411:                                }
                    412:                        frexpr(p->exprblock.vleng);
                    413:                        free( (charptr) p );
                    414:                        p = lp;
                    415:                        if (p->tag != TEXPR)
                    416:                                goto retputx;
                    417:                        pt = lt;
                    418:                        lp = p->exprblock.leftp;
                    419:                        lt = lp->headblock.vtype;
                    420:                } /* while */
                    421:                if(p->tag==TEXPR && p->exprblock.opcode==OPCONV)
                    422:                        break;
                    423:  retputx:
                    424:                return putx(p);
                    425: 
                    426:        case OPADDR:
                    427:                comma = NO;
                    428:                lp = p->exprblock.leftp;
                    429:                free( (charptr) p );
                    430:                if(lp->tag != TADDR)
                    431:                {
                    432:                        tp = (expptr)
                    433:                            mktmp(lp->headblock.vtype,lp->headblock.vleng);
                    434:                        p = putx( mkexpr(OPASSIGN, cpexpr(tp), lp) );
                    435:                        lp = tp;
                    436:                        comma = YES;
                    437:                }
                    438:                if(comma)
                    439:                        p = mkexpr(OPCOMMA, p, putaddr(lp));
                    440:                else
                    441:                        p = (expptr)putaddr(lp);
                    442:                return p;
                    443: 
                    444:        case OPASSIGN:
                    445:        case OPASSIGNI:
                    446:        case OPLT:
                    447:        case OPLE:
                    448:        case OPGT:
                    449:        case OPGE:
                    450:        case OPEQ:
                    451:        case OPNE:
                    452:            ;
                    453:        }
                    454: 
                    455:        if( ops2[p->exprblock.opcode] <= 0)
                    456:                badop("putop", p->exprblock.opcode);
                    457:        p -> exprblock.leftp = putx (p -> exprblock.leftp);
                    458:        if (p -> exprblock.rightp)
                    459:            p -> exprblock.rightp = putx (p -> exprblock.rightp);
                    460:        return p;
                    461: }
                    462: 
                    463: LOCAL expptr putpower(p)
                    464: expptr p;
                    465: {
                    466:        expptr base;
                    467:        Addrp t1, t2;
                    468:        ftnint k;
                    469:        int type;
                    470:        char buf[80];                   /* buffer for text of comment */
                    471: 
                    472:        if(!ISICON(p->exprblock.rightp) ||
                    473:            (k = p->exprblock.rightp->constblock.Const.ci)<2)
                    474:                Fatal("putpower: bad call");
                    475:        base = p->exprblock.leftp;
                    476:        type = base->headblock.vtype;
                    477:        t1 = mktmp(type, ENULL);
                    478:        t2 = NULL;
                    479: 
                    480:        free ((charptr) p);
                    481:        p = putassign (cpexpr((expptr) t1), base);
                    482: 
                    483:        sprintf (buf, "Computing %ld%s power", k,
                    484:                k == 2 ? "nd" : k == 3 ? "rd" : "th");
                    485:        p1_comment (buf);
                    486: 
                    487:        for( ; (k&1)==0 && k>2 ; k>>=1 )
                    488:        {
                    489:                p = mkexpr (OPCOMMA, p, putsteq(t1, t1));
                    490:        }
                    491: 
                    492:        if(k == 2) {
                    493: 
                    494: /* Write the power computation out immediately */
                    495:                putout (p);
                    496:                p = putx( mkexpr(OPSTAR, cpexpr((expptr)t1), cpexpr((expptr)t1)));
                    497:        } else {
                    498:                t2 = mktmp(type, ENULL);
                    499:                p = mkexpr (OPCOMMA, p, putassign(cpexpr((expptr)t2),
                    500:                                                cpexpr((expptr)t1)));
                    501: 
                    502:                for(k>>=1 ; k>1 ; k>>=1)
                    503:                {
                    504:                        p = mkexpr (OPCOMMA, p, putsteq(t1, t1));
                    505:                        if(k & 1)
                    506:                        {
                    507:                                p = mkexpr (OPCOMMA, p, putsteq(t2, t1));
                    508:                        }
                    509:                }
                    510: /* Write the power computation out immediately */
                    511:                putout (p);
                    512:                p = putx( mkexpr(OPSTAR, cpexpr((expptr)t2),
                    513:                    mkexpr(OPSTAR, cpexpr((expptr)t1), cpexpr((expptr)t1))));
                    514:        }
                    515:        frexpr((expptr)t1);
                    516:        if(t2)
                    517:                frexpr((expptr)t2);
                    518:        return p;
                    519: }
                    520: 
                    521: 
                    522: 
                    523: 
                    524: LOCAL Addrp intdouble(p)
                    525: Addrp p;
                    526: {
                    527:        register Addrp t;
                    528: 
                    529:        t = mktmp(TYDREAL, ENULL);
                    530:        putout (putassign(cpexpr((expptr)t), (expptr)p));
                    531:        return(t);
                    532: }
                    533: 
                    534: 
                    535: 
                    536: 
                    537: 
                    538: /* Complex-type variable assignment */
                    539: 
                    540: LOCAL Addrp putcxeq(p)
                    541: register expptr p;
                    542: {
                    543:        register Addrp lp, rp;
                    544:        expptr code;
                    545: 
                    546:        if(p->tag != TEXPR)
                    547:                badtag("putcxeq", p->tag);
                    548: 
                    549:        lp = putcx1(p->exprblock.leftp);
                    550:        rp = putcx1(p->exprblock.rightp);
                    551:        code = putassign ( (expptr)realpart(lp), (expptr)realpart(rp));
                    552: 
                    553:        if( ISCOMPLEX(p->exprblock.vtype) )
                    554:        {
                    555:                code = mkexpr (OPCOMMA, code, putassign
                    556:                        (imagpart(lp), imagpart(rp)));
                    557:        }
                    558:        putout (code);
                    559:        frexpr((expptr)rp);
                    560:        free ((charptr) p);
                    561:        return lp;
                    562: }
                    563: 
                    564: 
                    565: 
                    566: /* putcxop -- used to write out embedded calls to complex functions, and
                    567:    complex arguments to procedures */
                    568: 
                    569: expptr putcxop(p)
                    570: expptr p;
                    571: {
                    572:        return (expptr)putaddr((expptr)putcx1(p));
                    573: }
                    574: 
                    575: #define PAIR(x,y) mkexpr (OPCOMMA, (x), (y))
                    576: 
                    577: LOCAL Addrp putcx1(p)
                    578: register expptr p;
                    579: {
                    580:        expptr q;
                    581:        Addrp lp, rp;
                    582:        register Addrp resp;
                    583:        int opcode;
                    584:        int ltype, rtype;
                    585:        long ts, tskludge;
                    586:        expptr mkrealcon();
                    587: 
                    588:        if(p == NULL)
                    589:                return(NULL);
                    590: 
                    591:        switch(p->tag)
                    592:        {
                    593:        case TCONST:
                    594:                if( ISCOMPLEX(p->constblock.vtype) )
                    595:                        p = (expptr) putconst((Constp)p);
                    596:                return( (Addrp) p );
                    597: 
                    598:        case TADDR:
                    599:                resp = &p->addrblock;
                    600:                if (addressable(p))
                    601:                        return (Addrp) p;
                    602:                ts = tskludge = 0;
                    603:                if (q = resp->memoffset) {
                    604:                        if (resp->uname_tag == UNAM_REF) {
                    605:                                q = cpexpr((tagptr)resp);
                    606:                                q->addrblock.vtype = tyint;
                    607:                                q->addrblock.cmplx_sub = 1;
                    608:                                p->addrblock.skip_offset = 1;
                    609:                                resp->user.name->vsubscrused = 1;
                    610:                                resp->uname_tag = UNAM_NAME;
                    611:                                tskludge = typesize[resp->vtype]
                    612:                                        * (resp->Field ? 2 : 1);
                    613:                                }
                    614:                        else if (resp->isarray
                    615:                                        && resp->vtype != TYCHAR) {
                    616:                                if (ONEOF(resp->vstg, M(STGCOMMON)|M(STGEQUIV))
                    617:                                          && resp->uname_tag == UNAM_NAME)
                    618:                                        q = mkexpr(OPMINUS, q,
                    619:                                          mkintcon(resp->user.name->voffset));
                    620:                                ts = typesize[resp->vtype]
                    621:                                        * (resp->Field ? 2 : 1);
                    622:                                q = resp->memoffset = mkexpr(OPSLASH, q,
                    623:                                                                ICON(ts));
                    624:                                }
                    625:                        }
                    626:                resp = mktmp(tyint, ENULL);
                    627:                putout(putassign(cpexpr((expptr)resp), q));
                    628:                p->addrblock.memoffset = tskludge
                    629:                        ? mkexpr(OPSTAR, resp, ICON(tskludge))
                    630:                        : (expptr)resp;
                    631:                if (ts) {
                    632:                        resp = &p->addrblock;
                    633:                        q = mkexpr(OPSTAR, resp->memoffset, ICON(ts));
                    634:                        if (ONEOF(resp->vstg, M(STGCOMMON)|M(STGEQUIV))
                    635:                                && resp->uname_tag == UNAM_NAME)
                    636:                                q = mkexpr(OPPLUS, q,
                    637:                                    mkintcon(resp->user.name->voffset));
                    638:                        resp->memoffset = q;
                    639:                        }
                    640:                return (Addrp) p;
                    641: 
                    642:        case TEXPR:
                    643:                if( ISCOMPLEX(p->exprblock.vtype) )
                    644:                        break;
                    645:                resp = mktmp(TYDREAL, ENULL);
                    646:                putout (putassign( cpexpr((expptr)resp), p));
                    647:                return(resp);
                    648: 
                    649:        default:
                    650:                badtag("putcx1", p->tag);
                    651:        }
                    652: 
                    653:        opcode = p->exprblock.opcode;
                    654:        if(opcode==OPCALL || opcode==OPCCALL)
                    655:        {
                    656:                Addrp t;
                    657:                p = putcall(p, &t);
                    658:                putout(p);
                    659:                return t;
                    660:        }
                    661:        else if(opcode == OPASSIGN)
                    662:        {
                    663:                return putcxeq (p);
                    664:        }
                    665: 
                    666: /* BUG  (inefficient)  Generates too many temporary variables */
                    667: 
                    668:        resp = mktmp(p->exprblock.vtype, ENULL);
                    669:        if(lp = putcx1(p->exprblock.leftp) )
                    670:                ltype = lp->vtype;
                    671:        if(rp = putcx1(p->exprblock.rightp) )
                    672:                rtype = rp->vtype;
                    673: 
                    674:        switch(opcode)
                    675:        {
                    676:        case OPCOMMA:
                    677:                frexpr((expptr)resp);
                    678:                resp = rp;
                    679:                rp = NULL;
                    680:                break;
                    681: 
                    682:        case OPNEG:
                    683:        case OPNEG1:
                    684:                putout (PAIR (
                    685:                        putassign( (expptr)realpart(resp),
                    686:                                mkexpr(OPNEG, (expptr)realpart(lp), ENULL)),
                    687:                        putassign( imagpart(resp),
                    688:                                mkexpr(OPNEG, imagpart(lp), ENULL))));
                    689:                break;
                    690: 
                    691:        case OPPLUS:
                    692:        case OPMINUS: { expptr r;
                    693:                r = putassign( (expptr)realpart(resp),
                    694:                    mkexpr(opcode, (expptr)realpart(lp), (expptr)realpart(rp) ));
                    695:                if(rtype < TYCOMPLEX)
                    696:                        q = putassign( imagpart(resp), imagpart(lp) );
                    697:                else if(ltype < TYCOMPLEX)
                    698:                {
                    699:                        if(opcode == OPPLUS)
                    700:                                q = putassign( imagpart(resp), imagpart(rp) );
                    701:                        else
                    702:                                q = putassign( imagpart(resp),
                    703:                                    mkexpr(OPNEG, imagpart(rp), ENULL) );
                    704:                }
                    705:                else
                    706:                        q = putassign( imagpart(resp),
                    707:                            mkexpr(opcode, imagpart(lp), imagpart(rp) ));
                    708:                r = PAIR (r, q);
                    709:                putout (r);
                    710:                break;
                    711:            } /* case OPPLUS, OPMINUS: */
                    712:        case OPSTAR:
                    713:                if(ltype < TYCOMPLEX)
                    714:                {
                    715:                        if( ISINT(ltype) )
                    716:                                lp = intdouble(lp);
                    717:                        putout (PAIR (
                    718:                                putassign( (expptr)realpart(resp),
                    719:                                    mkexpr(OPSTAR, cpexpr((expptr)lp),
                    720:                                        (expptr)realpart(rp))),
                    721:                                putassign( imagpart(resp),
                    722:                                    mkexpr(OPSTAR, cpexpr((expptr)lp), imagpart(rp)))));
                    723:                }
                    724:                else if(rtype < TYCOMPLEX)
                    725:                {
                    726:                        if( ISINT(rtype) )
                    727:                                rp = intdouble(rp);
                    728:                        putout (PAIR (
                    729:                                putassign( (expptr)realpart(resp),
                    730:                                    mkexpr(OPSTAR, cpexpr((expptr)rp),
                    731:                                        (expptr)realpart(lp))),
                    732:                                putassign( imagpart(resp),
                    733:                                    mkexpr(OPSTAR, cpexpr((expptr)rp), imagpart(lp)))));
                    734:                }
                    735:                else    {
                    736:                        putout (PAIR (
                    737:                                putassign( (expptr)realpart(resp), mkexpr(OPMINUS,
                    738:                                    mkexpr(OPSTAR, (expptr)realpart(lp),
                    739:                                        (expptr)realpart(rp)),
                    740:                                    mkexpr(OPSTAR, imagpart(lp), imagpart(rp)))),
                    741:                                putassign( imagpart(resp), mkexpr(OPPLUS,
                    742:                                    mkexpr(OPSTAR, (expptr)realpart(lp), imagpart(rp)),
                    743:                                    mkexpr(OPSTAR, imagpart(lp),
                    744:                                        (expptr)realpart(rp))))));
                    745:                }
                    746:                break;
                    747: 
                    748:        case OPSLASH:
                    749:                /* fixexpr has already replaced all divisions
                    750:                 * by a complex by a function call
                    751:                 */
                    752:                if( ISINT(rtype) )
                    753:                        rp = intdouble(rp);
                    754:                putout (PAIR (
                    755:                        putassign( (expptr)realpart(resp),
                    756:                            mkexpr(OPSLASH, (expptr)realpart(lp), cpexpr((expptr)rp))),
                    757:                        putassign( imagpart(resp),
                    758:                            mkexpr(OPSLASH, imagpart(lp), cpexpr((expptr)rp)))));
                    759:                break;
                    760: 
                    761:        case OPCONV:
                    762:                if( ISCOMPLEX(lp->vtype) )
                    763:                        q = imagpart(lp);
                    764:                else if(rp != NULL)
                    765:                        q = (expptr) realpart(rp);
                    766:                else
                    767:                        q = mkrealcon(TYDREAL, "0");
                    768:                putout (PAIR (
                    769:                        putassign( (expptr)realpart(resp), (expptr)realpart(lp)),
                    770:                        putassign( imagpart(resp), q)));
                    771:                break;
                    772: 
                    773:        default:
                    774:                badop("putcx1", opcode);
                    775:        }
                    776: 
                    777:        frexpr((expptr)lp);
                    778:        frexpr((expptr)rp);
                    779:        free( (charptr) p );
                    780:        return(resp);
                    781: }
                    782: 
                    783: 
                    784: 
                    785: 
                    786: /* Only .EQ. and .NE. may be performed on COMPLEX data, other relations
                    787:    are not defined */
                    788: 
                    789: LOCAL expptr putcxcmp(p)
                    790: register expptr p;
                    791: {
                    792:        int opcode;
                    793:        register Addrp lp, rp;
                    794:        expptr q;
                    795: 
                    796:        if(p->tag != TEXPR)
                    797:                badtag("putcxcmp", p->tag);
                    798: 
                    799:        opcode = p->exprblock.opcode;
                    800:        lp = putcx1(p->exprblock.leftp);
                    801:        rp = putcx1(p->exprblock.rightp);
                    802: 
                    803:        q = mkexpr( opcode==OPEQ ? OPAND : OPOR ,
                    804:            mkexpr(opcode, (expptr)realpart(lp), (expptr)realpart(rp)),
                    805:            mkexpr(opcode, imagpart(lp), imagpart(rp)) );
                    806: 
                    807:        free( (charptr) lp);
                    808:        free( (charptr) rp);
                    809:        free( (charptr) p );
                    810:        return  putx( fixexpr((Exprp)q) );
                    811: }
                    812: 
                    813: /* putch1 -- Forces constants into the literal pool, among other things */
                    814: 
                    815: LOCAL Addrp putch1(p)
                    816: register expptr p;
                    817: {
                    818:        Addrp t;
                    819:        expptr e;
                    820: 
                    821:        switch(p->tag)
                    822:        {
                    823:        case TCONST:
                    824:                return( putconst((Constp)p) );
                    825: 
                    826:        case TADDR:
                    827:                return( (Addrp) p );
                    828: 
                    829:        case TEXPR:
                    830:                switch(p->exprblock.opcode)
                    831:                {
                    832:                        expptr q;
                    833: 
                    834:                case OPCALL:
                    835:                case OPCCALL:
                    836: 
                    837:                        p = putcall(p, &t);
                    838:                        putout (p);
                    839:                        break;
                    840: 
                    841:                case OPCONCAT:
                    842:                        t = mktmp(TYCHAR, ICON(lencat(p)));
                    843:                        q = (expptr) cpexpr(p->headblock.vleng);
                    844:                        p = putcat( cpexpr((expptr)t), p );
                    845:                        /* put the correct length on the block */
                    846:                        frexpr(t->vleng);
                    847:                        t->vleng = q;
                    848:                        putout (p);
                    849:                        break;
                    850: 
                    851:                case OPCONV:
                    852:                        if(!ISICON(p->exprblock.vleng)
                    853:                            || p->exprblock.vleng->constblock.Const.ci!=1
                    854:                            || ! INT(p->exprblock.leftp->headblock.vtype) )
                    855:                                Fatal("putch1: bad character conversion");
                    856:                        t = mktmp(TYCHAR, ICON(1));
                    857:                        e = mkexpr(OPCONV, (expptr)t, ENULL);
                    858:                        e->headblock.vtype = TYCHAR;
                    859:                        p = putop( mkexpr(OPASSIGN, cpexpr(e), p));
                    860:                        putout (p);
                    861:                        break;
                    862:                default:
                    863:                        badop("putch1", p->exprblock.opcode);
                    864:                }
                    865:                return(t);
                    866: 
                    867:        default:
                    868:                badtag("putch1", p->tag);
                    869:        }
                    870:        /* NOT REACHED */ return 0;
                    871: }
                    872: 
                    873: 
                    874: /* putchop -- Write out a character actual parameter; that is, this is
                    875:    part of a procedure invocation */
                    876: 
                    877: Addrp putchop(p)
                    878: expptr p;
                    879: {
                    880:        p = putaddr((expptr)putch1(p));
                    881:        return (Addrp)p;
                    882: }
                    883: 
                    884: 
                    885: 
                    886: 
                    887: LOCAL expptr putcheq(p)
                    888: register expptr p;
                    889: {
                    890:        expptr lp, rp;
                    891:        int nbad;
                    892: 
                    893:        if(p->tag != TEXPR)
                    894:                badtag("putcheq", p->tag);
                    895: 
                    896:        lp = p->exprblock.leftp;
                    897:        rp = p->exprblock.rightp;
                    898:        frexpr(p->exprblock.vleng);
                    899:        free( (charptr) p );
                    900: 
                    901: /* If s = t // u, don't bother copying the result, write it directly into
                    902:    this buffer */
                    903: 
                    904:        nbad = badchleng(lp) + badchleng(rp);
                    905:        if( rp->tag==TEXPR && rp->exprblock.opcode==OPCONCAT )
                    906:                p = putcat(lp, rp);
                    907:        else if( !nbad
                    908:                && ISONE(lp->headblock.vleng)
                    909:                && ISONE(rp->headblock.vleng) ) {
                    910:                lp = mkexpr(OPCONV, lp, ENULL);
                    911:                rp = mkexpr(OPCONV, rp, ENULL);
                    912:                lp->headblock.vtype = rp->headblock.vtype = TYCHAR;
                    913:                p = putop(mkexpr(OPASSIGN, lp, rp));
                    914:                }
                    915:        else
                    916:                p = putx( call2(TYSUBR, "s_copy", lp, rp) );
                    917:        return p;
                    918: }
                    919: 
                    920: 
                    921: 
                    922: 
                    923: LOCAL expptr putchcmp(p)
                    924: register expptr p;
                    925: {
                    926:        expptr lp, rp;
                    927: 
                    928:        if(p->tag != TEXPR)
                    929:                badtag("putchcmp", p->tag);
                    930: 
                    931:        lp = p->exprblock.leftp;
                    932:        rp = p->exprblock.rightp;
                    933: 
                    934:        if(ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) ) {
                    935:                lp = mkexpr(OPCONV, lp, ENULL);
                    936:                rp = mkexpr(OPCONV, rp, ENULL);
                    937:                lp->headblock.vtype = rp->headblock.vtype = TYCHAR;
                    938:                }
                    939:        else {
                    940:                lp = call2(TYINT,"s_cmp", lp, rp);
                    941:                rp = ICON(0);
                    942:                }
                    943:        p->exprblock.leftp = lp;
                    944:        p->exprblock.rightp = rp;
                    945:        p = putop(p);
                    946:        return p;
                    947: }
                    948: 
                    949: 
                    950: 
                    951: 
                    952: 
                    953: /* putcat -- Writes out a concatenation operation.  Two temporary arrays
                    954:    are allocated,   putct1()   is called to initialize them, and then a
                    955:    call to runtime library routine   s_cat()   is inserted.
                    956: 
                    957:        This routine generates code which will perform an  (nconc lhs rhs)
                    958:    at runtime.  The runtime funciton does not return a value, the routine
                    959:    that calls this   putcat   must remember the name of   lhs.
                    960: */
                    961: 
                    962: 
                    963: LOCAL expptr putcat(lhs0, rhs)
                    964:  expptr lhs0;
                    965:  register expptr rhs;
                    966: {
                    967:        register Addrp lhs = (Addrp)lhs0;
                    968:        int n, tyi;
                    969:        Addrp length_var, string_var;
                    970:        expptr p;
                    971:        static char Writing_concatenation[] = "Writing concatenation";
                    972: 
                    973: /* Create the temporary arrays */
                    974: 
                    975:        n = ncat(rhs);
                    976:        length_var = mktmpn(n, tyioint, ENULL);
                    977:        string_var = mktmpn(n, TYADDR, ENULL);
                    978:        frtemp((Addrp)cpexpr((expptr)length_var));
                    979:        frtemp((Addrp)cpexpr((expptr)string_var));
                    980: 
                    981: /* Initialize the arrays */
                    982: 
                    983:        n = 0;
                    984:        /* p1_comment scribbles on its argument, so we
                    985:         * cannot safely pass a string literal here. */
                    986:        p1_comment(Writing_concatenation);
                    987:        putct1(rhs, length_var, string_var, &n);
                    988: 
                    989: /* Create the invocation */
                    990: 
                    991:        tyi = tyint;
                    992:        tyint = tyioint;        /* for -I2 */
                    993:        p = putx (call4 (TYSUBR, "s_cat",
                    994:                                (expptr)lhs,
                    995:                                (expptr)string_var,
                    996:                                (expptr)length_var,
                    997:                                (expptr)putconst((Constp)ICON(n))));
                    998:        tyint = tyi;
                    999: 
                   1000:        return p;
                   1001: }
                   1002: 
                   1003: 
                   1004: 
                   1005: 
                   1006: 
                   1007: LOCAL putct1(q, length_var, string_var, ip)
                   1008: register expptr q;
                   1009: register Addrp length_var, string_var;
                   1010: int *ip;
                   1011: {
                   1012:        int i;
                   1013:        Addrp length_copy, string_copy;
                   1014:        expptr e;
                   1015:        extern int szleng;
                   1016: 
                   1017:        if(q->tag==TEXPR && q->exprblock.opcode==OPCONCAT)
                   1018:        {
                   1019:                putct1(q->exprblock.leftp, length_var, string_var,
                   1020:                    ip);
                   1021:                putct1(q->exprblock.rightp, length_var, string_var,
                   1022:                    ip);
                   1023:                frexpr (q -> exprblock.vleng);
                   1024:                free ((charptr) q);
                   1025:        }
                   1026:        else
                   1027:        {
                   1028:                i = (*ip)++;
                   1029:                e = cpexpr(q->headblock.vleng);
                   1030:                if (!e)
                   1031:                        return; /* error -- character*(*) */
                   1032:                length_copy = (Addrp) cpexpr((expptr)length_var);
                   1033:                length_copy->memoffset =
                   1034:                    mkexpr(OPPLUS,length_copy->memoffset, ICON(i*szleng));
                   1035:                string_copy = (Addrp) cpexpr((expptr)string_var);
                   1036:                string_copy->memoffset =
                   1037:                    mkexpr(OPPLUS, string_copy->memoffset,
                   1038:                        ICON(i*typesize[TYADDR]));
                   1039:                putout (PAIR (putassign((expptr)length_copy, e),
                   1040:                        putassign((expptr)string_copy, addrof((expptr)putch1(q)))));
                   1041:        }
                   1042: }
                   1043: 
                   1044: /* putaddr -- seems to write out function invocation actual parameters */
                   1045: 
                   1046: LOCAL expptr putaddr(p0)
                   1047:  expptr p0;
                   1048: {
                   1049:        register Addrp p;
                   1050:        chainp cp;
                   1051: 
                   1052:        if (!(p = (Addrp)p0))
                   1053:                return ENULL;
                   1054: 
                   1055:        if( p->tag==TERROR || (p->memoffset!=NULL && ISERROR(p->memoffset)) )
                   1056:        {
                   1057:                frexpr((expptr)p);
                   1058:                return ENULL;
                   1059:        }
                   1060:        if (p->isarray && p->memoffset)
                   1061:                if (p->uname_tag == UNAM_REF) {
                   1062:                        cp = p->memoffset->listblock.listp;
                   1063:                        for(; cp; cp = cp->nextp)
                   1064:                                cp->datap = (char *)fixtype((tagptr)cp->datap);
                   1065:                        }
                   1066:                else
                   1067:                        p->memoffset = putx(p->memoffset);
                   1068:        return (expptr) p;
                   1069: }
                   1070: 
                   1071:  LOCAL expptr
                   1072: addrfix(e)             /* fudge character string length if it's a TADDR */
                   1073:  expptr e;
                   1074: {
                   1075:        return e->tag == TADDR ? mkexpr(OPIDENTITY, e, ENULL) : e;
                   1076:        }
                   1077: 
                   1078:  LOCAL int
                   1079: typekludge(ccall, q, at, j)
                   1080:  int ccall;
                   1081:  register expptr q;
                   1082:  Atype *at;
                   1083:  int j;        /* alternate type */
                   1084: {
                   1085:        register int i, k;
                   1086:        extern int iocalladdr;
                   1087:        register Namep np;
                   1088: 
                   1089:        /* Return value classes:
                   1090:         *      < 100 ==> Fortran arg (pointer to type)
                   1091:         *      < 200 ==> C arg
                   1092:         *      < 300 ==> procedure arg
                   1093:         *      < 400 ==> external, no explicit type
                   1094:         *      < 500 ==> arg that may turn out to be
                   1095:         *                either a variable or a procedure
                   1096:         */
                   1097: 
                   1098:        k = q->headblock.vtype;
                   1099:        if (ccall) {
                   1100:                if (k == TYREAL)
                   1101:                        k = TYDREAL;    /* force double for library routines */
                   1102:                return k + 100;
                   1103:                }
                   1104:        if (k == TYADDR)
                   1105:                return iocalladdr;
                   1106:        i = q->tag;
                   1107:        if ((i == TEXPR && q->exprblock.opcode != OPCOMMA_ARG)
                   1108:        ||  (i == TADDR && q->addrblock.charleng)
                   1109:        ||   i == TCONST)
                   1110:                k = TYFTNLEN + 100;
                   1111:        else if (i == TADDR)
                   1112:            switch(q->addrblock.vclass) {
                   1113:                case CLPROC:
                   1114:                        if (q->addrblock.uname_tag != UNAM_NAME)
                   1115:                                k += 200;
                   1116:                        else if ((np = q->addrblock.user.name)->vprocclass
                   1117:                                        != PTHISPROC) {
                   1118:                                if (k && !np->vimpltype)
                   1119:                                        k += 200;
                   1120:                                else {
                   1121:                                        if (j > 200 && infertypes && j < 300) {
                   1122:                                                k = j;
                   1123:                                                inferdcl(np, j-200);
                   1124:                                                }
                   1125:                                        else k = (np->vstg == STGEXT
                   1126:                                                ? extsymtab[np->vardesc.varno].extype
                   1127:                                                : 0) + 200;
                   1128:                                        at->cp = mkchain((char *)np, at->cp);
                   1129:                                        }
                   1130:                                }
                   1131:                        else if (k == TYSUBR)
                   1132:                                k += 200;
                   1133:                        break;
                   1134: 
                   1135:                case CLUNKNOWN:
                   1136:                        if (q->addrblock.vstg == STGARG
                   1137:                         && q->addrblock.uname_tag == UNAM_NAME) {
                   1138:                                k += 400;
                   1139:                                at->cp = mkchain((char *)q->addrblock.user.name,
                   1140:                                                at->cp);
                   1141:                                }
                   1142:                }
                   1143:        else if (i == TNAME && q->nameblock.vstg == STGARG) {
                   1144:                np = &q->nameblock;
                   1145:                switch(np->vclass) {
                   1146:                    case CLPROC:
                   1147:                        if (!np->vimpltype)
                   1148:                                k += 200;
                   1149:                        else if (j <= 200 || !infertypes || j >= 300)
                   1150:                                k += 300;
                   1151:                        else {
                   1152:                                k = j;
                   1153:                                inferdcl(np, j-200);
                   1154:                                }
                   1155:                        goto add2chain;
                   1156: 
                   1157:                    case CLUNKNOWN:
                   1158:                        /* argument may be a scalar variable or a function */
                   1159:                        if (np->vimpltype && j && infertypes
                   1160:                        && j < 300) {
                   1161:                                inferdcl(np, j % 100);
                   1162:                                k = j;
                   1163:                                }
                   1164:                        else
                   1165:                                k += 400;
                   1166: 
                   1167:                        /* to handle procedure args only so far known to be
                   1168:                         * external, save a pointer to the symbol table entry...
                   1169:                         */
                   1170:  add2chain:
                   1171:                        at->cp = mkchain((char *)np, at->cp);
                   1172:                    }
                   1173:                }
                   1174:        return k;
                   1175:        }
                   1176: 
                   1177:  char *
                   1178: Argtype(k, buf)
                   1179:  int k;
                   1180:  char *buf;
                   1181: {
                   1182:        if (k < 100) {
                   1183:                sprintf(buf, "%s variable", ftn_types[k]);
                   1184:                return buf;
                   1185:                }
                   1186:        if (k < 200) {
                   1187:                k -= 100;
                   1188:                return ftn_types[k];
                   1189:                }
                   1190:        if (k < 300) {
                   1191:                k -= 200;
                   1192:                if (k == TYSUBR)
                   1193:                        return ftn_types[TYSUBR];
                   1194:                sprintf(buf, "%s function", ftn_types[k]);
                   1195:                return buf;
                   1196:                }
                   1197:        if (k < 400)
                   1198:                return "external argument";
                   1199:        k -= 400;
                   1200:        sprintf(buf, "%s argument", ftn_types[k]);
                   1201:        return buf;
                   1202:        }
                   1203: 
                   1204:  static void
                   1205: atype_squawk(at, msg)
                   1206:  Argtypes *at;
                   1207:  char *msg;
                   1208: {
                   1209:        register Atype *a, *ae;
                   1210:        warn(msg);
                   1211:        for(a = at->atypes, ae = a + at->nargs; a < ae; a++)
                   1212:                frchain(&a->cp);
                   1213:        at->nargs = -1;
                   1214:        if (at->changes & 2 && !at->defined)
                   1215:                proc_protochanges++;
                   1216:        }
                   1217: 
                   1218:  static char inconsist[] = "inconsistent calling sequences for ";
                   1219: 
                   1220:  void
                   1221: bad_atypes(at, fname, i, j, k, here, prev)
                   1222:  Argtypes *at;
                   1223:  char *fname, *here, *prev;
                   1224:  int i, j, k;
                   1225: {
                   1226:        char buf[208], buf1[32], buf2[32];
                   1227: 
                   1228:        sprintf(buf, "%s%.90s,\n\targ %d: %s%s%s %s.",
                   1229:                inconsist, fname, i, here, Argtype(k, buf1),
                   1230:                prev, Argtype(j, buf2));
                   1231:        atype_squawk(at, buf);
                   1232:        }
                   1233: 
                   1234:  int
                   1235: type_fixup(at,a,k)
                   1236:  Argtypes *at;
                   1237:  Atype *a;
                   1238:  int k;
                   1239: {
                   1240:        register struct Entrypoint *ep;
                   1241:        if (!infertypes)
                   1242:                return 0;
                   1243:        for(ep = entries; ep; ep = ep->entnextp)
                   1244:                if (at == ep->entryname->arginfo) {
                   1245:                        a->type = k % 100;
                   1246:                        return proc_argchanges = 1;
                   1247:                        }
                   1248:        return 0;
                   1249:        }
                   1250: 
                   1251: 
                   1252:  void
                   1253: save_argtypes(arglist, at0, at1, ccall, fname, stg, nchargs, type, zap)
                   1254:  chainp arglist;
                   1255:  Argtypes **at0, **at1;
                   1256:  int ccall, stg, nchargs, type, zap;
                   1257:  char *fname;
                   1258: {
                   1259:        Argtypes *at;
                   1260:        chainp cp;
                   1261:        int i, i0, j, k, nargs, nbad, *t, *te;
                   1262:        Atype *atypes;
                   1263:        expptr q;
                   1264:        char buf[208], buf1[32], buf2[32];
                   1265:        static int initargs[4] = {TYCOMPLEX, TYDCOMPLEX, TYCHAR, TYFTNLEN+100};
                   1266:        static int *init_ap[TYSUBR+1] = {0,0,0,0,0,0,0,
                   1267: #ifdef TYQUAD
                   1268:                                                        0,
                   1269: #endif
                   1270:                                initargs, initargs+1,0,0,0,initargs+2};
                   1271:        extern int init_ac[TYSUBR+1];
                   1272: 
                   1273:        i0 = init_ac[type];
                   1274:        t = init_ap[type];
                   1275:        te = t + i0;
                   1276:        if (at = *at0) {
                   1277:                *at1 = at;
                   1278:                nargs = at->nargs;
                   1279:                if (nargs < 0 && type && at->changes & 2 && !at->defined)
                   1280:                        --proc_protochanges;
                   1281:                if (at->dnargs >= 0 && zap != 2)
                   1282:                        type = 0;
                   1283:                if (nargs < 0) { /* inconsistent usage seen */
                   1284:                        if (type)
                   1285:                                goto newlist;
                   1286:                        return;
                   1287:                        }
                   1288:                atypes = at->atypes;
                   1289:                i = nchargs;
                   1290:                for(nbad = 0; t < te; atypes++) {
                   1291:                        if (++i > nargs) {
                   1292:  toomany:
                   1293:                                i = nchargs + i0;
                   1294:                                for(cp = arglist; cp; cp = cp->nextp)
                   1295:                                        i++;
                   1296:  toofew:
                   1297:                                switch(zap) {
                   1298:                                        case 2: zap = 6; break;
                   1299:                                        case 1: if (at->defined & 4)
                   1300:                                                        return;
                   1301:                                        }
                   1302:                                sprintf(buf,
                   1303:                "%s%.90s:\n\there %d, previously %d args and string lengths.",
                   1304:                                        inconsist, fname, i, nargs);
                   1305:                                atype_squawk(at, buf);
                   1306:                                if (type)
                   1307:                                        goto newlist;
                   1308:                                return;
                   1309:                                }
                   1310:                        j = atypes->type;
                   1311:                        k = *t++;
                   1312:                        if (j != k)
                   1313:                                goto badtypes;
                   1314:                        }
                   1315:                for(cp = arglist; cp; atypes++, cp = cp->nextp) {
                   1316:                        if (++i > nargs)
                   1317:                                goto toomany;
                   1318:                        j = atypes->type;
                   1319:                        if (!(q = (expptr)cp->datap))
                   1320:                                continue;
                   1321:                        k = typekludge(ccall, q, atypes, j);
                   1322:                        if (k >= 300 || k == j)
                   1323:                                continue;
                   1324:                        if (j >= 300) {
                   1325:                                if (k >= 200) {
                   1326:                                        if (k == TYUNKNOWN + 200)
                   1327:                                                continue;
                   1328:                                        if (j % 100 != k - 200
                   1329:                                         && k != TYSUBR + 200
                   1330:                                         && j != TYUNKNOWN + 300
                   1331:                                         && !type_fixup(at,atypes,k))
                   1332:                                                goto badtypes;
                   1333:                                        }
                   1334:                                else if (j % 100 % TYSUBR != k % TYSUBR
                   1335:                                                && !type_fixup(at,atypes,k))
                   1336:                                        goto badtypes;
                   1337:                                }
                   1338:                        else if (k < 200 || j < 200)
                   1339:                                if (j) {
                   1340:                                        if (k == TYUNKNOWN
                   1341:                                         && q->tag == TNAME
                   1342:                                         && q->nameblock.vinfproc) {
                   1343:                                                q->nameblock.vdcldone = 0;
                   1344:                                                impldcl((Namep)q);
                   1345:                                                }
                   1346:                                        goto badtypes;
                   1347:                                        }
                   1348:                                else ; /* fall through to update */
                   1349:                        else if (k == TYUNKNOWN+200)
                   1350:                                continue;
                   1351:                        else if (j != TYUNKNOWN+200)
                   1352:                                {
                   1353:  badtypes:
                   1354:                                if (++nbad == 1)
                   1355:                                        bad_atypes(at, fname, i, j, k, "here ",
                   1356:                                                ", previously");
                   1357:                                else
                   1358:                                        fprintf(stderr,
                   1359:                                         "\targ %d: here %s, previously %s.\n",
                   1360:                                                i, Argtype(k,buf1),
                   1361:                                                Argtype(j,buf2));
                   1362:                                continue;
                   1363:                                }
                   1364:                        /* We've subsequently learned the right type,
                   1365:                           as in the call on zoo below...
                   1366: 
                   1367:                                subroutine foo(x, zap)
                   1368:                                external zap
                   1369:                                call goo(zap)
                   1370:                                x = zap(3)
                   1371:                                call zoo(zap)
                   1372:                                end
                   1373:                         */
                   1374:                        if (!nbad) {
                   1375:                                atypes->type = k;
                   1376:                                at->changes |= 1;
                   1377:                                }
                   1378:                        }
                   1379:                if (i < nargs)
                   1380:                        goto toofew;
                   1381:                if (nbad) {
                   1382:                        if (type) {
                   1383:                                /* we're defining the procedure */
                   1384:                                t = init_ap[type];
                   1385:                                te = t + i0;
                   1386:                                proc_argchanges = 1;
                   1387:                                goto newlist;
                   1388:                                }
                   1389:                        return;
                   1390:                        }
                   1391:                if (zap == 1 && (at->changes & 5) != 5)
                   1392:                        at->changes = 0;
                   1393:                return;
                   1394:                }
                   1395:  newlist:
                   1396:        i = i0 + nchargs;
                   1397:        for(cp = arglist; cp; cp = cp->nextp)
                   1398:                i++;
                   1399:        k = sizeof(Argtypes) + (i-1)*sizeof(Atype);
                   1400:        *at0 = *at1 = at = stg == STGEXT ? (Argtypes *)gmem(k,1)
                   1401:                                         : (Argtypes *) mem(k,1);
                   1402:        at->dnargs = at->nargs = i;
                   1403:        at->defined = zap & 6;
                   1404:        at->changes = type ? 0 : 4;
                   1405:        atypes = at->atypes;
                   1406:        for(; t < te; atypes++) {
                   1407:                atypes->type = *t++;
                   1408:                atypes->cp = 0;
                   1409:                }
                   1410:        for(cp = arglist; cp; atypes++, cp = cp->nextp) {
                   1411:                atypes->cp = 0;
                   1412:                atypes->type = (q = (expptr)cp->datap)
                   1413:                        ? typekludge(ccall, q, atypes, 0)
                   1414:                        : 0;
                   1415:                }
                   1416:        for(; --nchargs >= 0; atypes++) {
                   1417:                atypes->type = TYFTNLEN + 100;
                   1418:                atypes->cp = 0;
                   1419:                }
                   1420:        }
                   1421: 
                   1422:  void
                   1423: saveargtypes(p)                /* for writing prototypes */
                   1424:  register Exprp p;
                   1425: {
                   1426:        Addrp a;
                   1427:        Argtypes **at0, **at1;
                   1428:        Namep np;
                   1429:        chainp arglist;
                   1430:        expptr rp;
                   1431:        Extsym *e;
                   1432:        char *fname;
                   1433: 
                   1434:        a = (Addrp)p->leftp;
                   1435:        switch(a->vstg) {
                   1436:                case STGEXT:
                   1437:                        switch(a->uname_tag) {
                   1438:                                case UNAM_EXTERN:       /* e.g., sqrt() */
                   1439:                                        e = extsymtab + a->memno;
                   1440:                                        at0 = at1 = &e->arginfo;
                   1441:                                        fname = e->fextname;
                   1442:                                        break;
                   1443:                                case UNAM_NAME:
                   1444:                                        np = a->user.name;
                   1445:                                        at0 = &extsymtab[np->vardesc.varno].arginfo;
                   1446:                                        at1 = &np->arginfo;
                   1447:                                        fname = np->fvarname;
                   1448:                                        break;
                   1449:                                default:
                   1450:                                        goto bug;
                   1451:                                }
                   1452:                        break;
                   1453:                case STGARG:
                   1454:                        if (a->uname_tag != UNAM_NAME)
                   1455:                                goto bug;
                   1456:                        np = a->user.name;
                   1457:                        at0 = at1 = &np->arginfo;
                   1458:                        fname = np->fvarname;
                   1459:                        break;
                   1460:                default:
                   1461:         bug:
                   1462:                        Fatal("Confusion in saveargtypes");
                   1463:                }
                   1464:        rp = p->rightp;
                   1465:        arglist = rp && rp->tag == TLIST ? rp->listblock.listp : 0;
                   1466:        save_argtypes(arglist, at0, at1, p->opcode == OPCCALL,
                   1467:                fname, a->vstg, 0, 0, 0);
                   1468:        }
                   1469: 
                   1470: /* putcall - fix up the argument list, and write out the invocation.   p
                   1471:    is expected to be initialized and point to an OPCALL or OPCCALL
                   1472:    expression.  The return value is a pointer to a temporary holding the
                   1473:    result of a COMPLEX or CHARACTER operation, or NULL. */
                   1474: 
                   1475: LOCAL expptr putcall(p0, temp)
                   1476:  expptr p0;
                   1477:  Addrp *temp;
                   1478: {
                   1479:     register Exprp p = (Exprp)p0;
                   1480:     chainp arglist;            /* Pointer to actual arguments, if any */
                   1481:     chainp charsp;             /* List of copies of the variables which
                   1482:                                   hold the lengths of character
                   1483:                                   parameters (other than procedure
                   1484:                                   parameters) */
                   1485:     chainp cp;                 /* Iterator over argument lists */
                   1486:     register expptr q;         /* Pointer to the current argument */
                   1487:     Addrp fval;                        /* Function return value */
                   1488:     int type;                  /* type of the call - presumably this was
                   1489:                                   set elsewhere */
                   1490:     int byvalue;               /* True iff we don't want to massage the
                   1491:                                   parameter list, since we're calling a C
                   1492:                                   library routine */
                   1493:     char *s;
                   1494:     extern struct Listblock *mklist();
                   1495: 
                   1496:     type = p -> vtype;
                   1497:     charsp = NULL;
                   1498:     byvalue =  (p->opcode == OPCCALL);
                   1499: 
                   1500: /* Verify the actual parameters */
                   1501: 
                   1502:     if (p == (Exprp) NULL)
                   1503:        err ("putcall:  NULL call expression");
                   1504:     else if (p -> tag != TEXPR)
                   1505:        erri ("putcall:  expected TEXPR, got '%d'", p -> tag);
                   1506: 
                   1507: /* Find the argument list */
                   1508: 
                   1509:     if(p->rightp && p -> rightp -> tag == TLIST)
                   1510:        arglist = p->rightp->listblock.listp;
                   1511:     else
                   1512:        arglist = NULL;
                   1513: 
                   1514: /* Count the number of explicit arguments, including lengths of character
                   1515:    variables */
                   1516: 
                   1517:     for(cp = arglist ; cp ; cp = cp->nextp)
                   1518:        if(!byvalue) {
                   1519:            q = (expptr) cp->datap;
                   1520:            if( ISCONST(q) )
                   1521:            {
                   1522: 
                   1523: /* Even constants are passed by reference, so we need to put them in the
                   1524:    literal table */
                   1525: 
                   1526:                q = (expptr) putconst((Constp)q);
                   1527:                cp->datap = (char *) q;
                   1528:            }
                   1529: 
                   1530: /* Save the length expression of character variables (NOT character
                   1531:    procedures) for the end of the argument list */
                   1532: 
                   1533:            if( ISCHAR(q) &&
                   1534:                (q->headblock.vclass != CLPROC
                   1535:                || q->headblock.vstg == STGARG
                   1536:                        && q->tag == TADDR
                   1537:                        && q->addrblock.uname_tag == UNAM_NAME
                   1538:                        && q->addrblock.user.name->vprocclass == PTHISPROC))
                   1539:            {
                   1540:                p0 = cpexpr(q->headblock.vleng);
                   1541:                charsp = mkchain((char *)p0, charsp);
                   1542:                if (q->headblock.vclass == CLUNKNOWN
                   1543:                 && q->headblock.vstg == STGARG)
                   1544:                        q->addrblock.user.name->vpassed = 1;
                   1545:                else if (q->tag == TADDR
                   1546:                                && q->addrblock.uname_tag == UNAM_CONST)
                   1547:                        p0->constblock.Const.ci
                   1548:                                += q->addrblock.user.Const.ccp1.blanks;
                   1549:            }
                   1550:        }
                   1551:     charsp = revchain(charsp);
                   1552: 
                   1553: /* If the routine is a CHARACTER function ... */
                   1554: 
                   1555:     if(type == TYCHAR)
                   1556:     {
                   1557:        if( ISICON(p->vleng) )
                   1558:        {
                   1559: 
                   1560: /* Allocate a temporary to hold the return value of the function */
                   1561: 
                   1562:            fval = mktmp(TYCHAR, p->vleng);
                   1563:        }
                   1564:        else    {
                   1565:                err("adjustable character function");
                   1566:                if (temp)
                   1567:                        *temp = 0;
                   1568:                return 0;
                   1569:                }
                   1570:     }
                   1571: 
                   1572: /* If the routine is a COMPLEX function ... */
                   1573: 
                   1574:     else if( ISCOMPLEX(type) )
                   1575:        fval = mktmp(type, ENULL);
                   1576:     else
                   1577:        fval = NULL;
                   1578: 
                   1579: /* Write the function name, without taking its address */
                   1580: 
                   1581:     p -> leftp = putx(fixtype(putaddr(p->leftp)));
                   1582: 
                   1583:     if(fval)
                   1584:     {
                   1585:        chainp prepend;
                   1586: 
                   1587: /* Prepend a copy of the function return value buffer out as the first
                   1588:    argument. */
                   1589: 
                   1590:        prepend = mkchain((char *)putx(putaddr(cpexpr((expptr)fval))), arglist);
                   1591: 
                   1592: /* If it's a character function, also prepend the length of the result */
                   1593: 
                   1594:        if(type==TYCHAR)
                   1595:        {
                   1596: 
                   1597:            prepend->nextp = mkchain((char *)putx(mkconv(TYLENG,
                   1598:                                        p->vleng)), arglist);
                   1599:        }
                   1600:        if (!(q = p->rightp))
                   1601:                p->rightp = q = (expptr)mklist(CHNULL);
                   1602:        q->listblock.listp = prepend;
                   1603:     }
                   1604: 
                   1605: /* Scan through the fortran argument list */
                   1606: 
                   1607:     for(cp = arglist ; cp ; cp = cp->nextp)
                   1608:     {
                   1609:        q = (expptr) (cp->datap);
                   1610:        if (q == ENULL)
                   1611:            err ("putcall:  NULL argument");
                   1612: 
                   1613: /* call putaddr only when we've got a parameter for a C routine or a
                   1614:    memory resident parameter */
                   1615: 
                   1616:        if (q -> tag == TCONST && !byvalue)
                   1617:            q = (expptr) putconst ((Constp)q);
                   1618: 
                   1619:        if(q->tag==TADDR && (byvalue || q->addrblock.vstg!=STGREG) ) {
                   1620:                if (q->addrblock.parenused
                   1621:                 && !byvalue && q->headblock.vtype != TYCHAR)
                   1622:                        goto make_copy;
                   1623:                cp->datap = (char *)putaddr(q);
                   1624:                }
                   1625:        else if( ISCOMPLEX(q->headblock.vtype) )
                   1626:            cp -> datap = (char *) putx (fixtype(putcxop(q)));
                   1627:        else if (ISCHAR(q) )
                   1628:            cp -> datap = (char *) putx (fixtype((expptr)putchop(q)));
                   1629:        else if( ! ISERROR(q) )
                   1630:        {
                   1631:            if(byvalue
                   1632:            || q->tag == TEXPR && q->exprblock.opcode == OPCHARCAST)
                   1633:                cp -> datap = (char *) putx(q);
                   1634:            else {
                   1635:                expptr t, t1;
                   1636: 
                   1637: /* If we've got a register parameter, or (maybe?) a constant, save it in a
                   1638:    temporary first */
                   1639:  make_copy:
                   1640:                t = (expptr) mktmp(q->headblock.vtype, q->headblock.vleng);
                   1641: 
                   1642: /* Assign to temporary variables before invoking the subroutine or
                   1643:    function */
                   1644: 
                   1645:                t1 = putassign( cpexpr(t), q );
                   1646:                if (doin_setbound)
                   1647:                        t = mkexpr(OPCOMMA_ARG, t1, t);
                   1648:                else
                   1649:                        putout(t1);
                   1650:                cp -> datap = (char *) t;
                   1651:            } /* else */
                   1652:        } /* if !ISERROR(q) */
                   1653:     }
                   1654: 
                   1655: /* Now adjust the lengths of the CHARACTER parameters */
                   1656: 
                   1657:     for(cp = charsp ; cp ; cp = cp->nextp)
                   1658:        cp->datap = (char *)addrfix(putx(
                   1659:                        /* in case MAIN has a character*(*)... */
                   1660:                        (s = cp->datap) ? mkconv(TYLENG,(expptr)s)
                   1661:                                         : ICON(0)));
                   1662: 
                   1663: /* ... and add them to the end of the argument list */
                   1664: 
                   1665:     hookup (arglist, charsp);
                   1666: 
                   1667: /* Return the name of the temporary used to hold the results, if any was
                   1668:    necessary. */
                   1669: 
                   1670:     if (temp) *temp = fval;
                   1671:     else frexpr ((expptr)fval);
                   1672: 
                   1673:     saveargtypes(p);
                   1674: 
                   1675:     return (expptr) p;
                   1676: }
                   1677: 
                   1678: 
                   1679: 
                   1680: /* putmnmx -- Put min or max.   p   must point to an EXPR, not just a
                   1681:    CONST */
                   1682: 
                   1683: LOCAL expptr putmnmx(p)
                   1684: register expptr p;
                   1685: {
                   1686:        int op, op2, type;
                   1687:        expptr arg, qp, temp;
                   1688:        chainp p0, p1;
                   1689:        Addrp sp, tp;
                   1690:        char comment_buf[80];
                   1691:        char *what;
                   1692: 
                   1693:        if(p->tag != TEXPR)
                   1694:                badtag("putmnmx", p->tag);
                   1695: 
                   1696:        type = p->exprblock.vtype;
                   1697:        op = p->exprblock.opcode;
                   1698:        op2 = op == OPMIN ? OPMIN2 : OPMAX2;
                   1699:        p0 = p->exprblock.leftp->listblock.listp;
                   1700:        free( (charptr) (p->exprblock.leftp) );
                   1701:        free( (charptr) p );
                   1702: 
                   1703:        /* special case for two addressable operands */
                   1704: 
                   1705:        if (addressable((expptr)p0->datap)
                   1706:         && (p1 = p0->nextp)
                   1707:         && addressable((expptr)p1->datap)
                   1708:         && !p1->nextp) {
                   1709:                if (type == TYREAL && forcedouble)
                   1710:                        op2 = op == OPMIN ? OPDMIN : OPDMAX;
                   1711:                p = mkexpr(op2, mkconv(type, cpexpr((expptr)p0->datap)),
                   1712:                                mkconv(type, cpexpr((expptr)p1->datap)));
                   1713:                frchain(&p0);
                   1714:                return p;
                   1715:                }
                   1716: 
                   1717:        /* general case */
                   1718: 
                   1719:        sp = mktmp(type, ENULL);
                   1720: 
                   1721: /* We only need a second temporary if the arg list has an unaddressable
                   1722:    value */
                   1723: 
                   1724:        tp = (Addrp) NULL;
                   1725:        qp = ENULL;
                   1726:        for (p1 = p0 -> nextp; p1; p1 = p1 -> nextp)
                   1727:                if (!addressable ((expptr) p1 -> datap)) {
                   1728:                        tp = mktmp(type, ENULL);
                   1729:                        qp = mkexpr(op2, cpexpr((expptr)sp), cpexpr((expptr)tp));
                   1730:                        qp = fixexpr((Exprp)qp);
                   1731:                        break;
                   1732:                } /* if */
                   1733: 
                   1734: /* Now output the appropriate number of assignments and comparisons.  Min
                   1735:    and max are implemented by the simple O(n) algorithm:
                   1736: 
                   1737:        min (a, b, c, d) ==>
                   1738:        { <type> t1, t2;
                   1739: 
                   1740:            t1 = a;
                   1741:            t2 = b; t1 = (t1 < t2) ? t1 : t2;
                   1742:            t2 = c; t1 = (t1 < t2) ? t1 : t2;
                   1743:            t2 = d; t1 = (t1 < t2) ? t1 : t2;
                   1744:        }
                   1745: */
                   1746: 
                   1747:        if (!doin_setbound) {
                   1748:                switch(op) {
                   1749:                        case OPLT:
                   1750:                        case OPMIN:
                   1751:                        case OPDMIN:
                   1752:                        case OPMIN2:
                   1753:                                what = "IN";
                   1754:                                break;
                   1755:                        default:
                   1756:                                what = "AX";
                   1757:                        }
                   1758:                sprintf (comment_buf, "Computing M%s", what);
                   1759:                p1_comment (comment_buf);
                   1760:                }
                   1761: 
                   1762:        p1 = p0->nextp;
                   1763:        temp = (expptr)p0->datap;
                   1764:        if (addressable(temp) && addressable((expptr)p1->datap)) {
                   1765:                p = mkconv(type, cpexpr(temp));
                   1766:                arg = mkconv(type, cpexpr((expptr)p1->datap));
                   1767:                temp = mkexpr(op2, p, arg);
                   1768:                if (!ISCONST(temp))
                   1769:                        temp = fixexpr((Exprp)temp);
                   1770:                p1 = p1->nextp;
                   1771:                }
                   1772:        p = putassign (cpexpr((expptr)sp), temp);
                   1773: 
                   1774:        for(; p1 ; p1 = p1->nextp)
                   1775:        {
                   1776:                if (addressable ((expptr) p1 -> datap)) {
                   1777:                        arg = mkconv(type, cpexpr((expptr)p1->datap));
                   1778:                        temp = mkexpr(op2, cpexpr((expptr)sp), arg);
                   1779:                        temp = fixexpr((Exprp)temp);
                   1780:                } else {
                   1781:                        temp = (expptr) cpexpr (qp);
                   1782:                        p = mkexpr(OPCOMMA, p,
                   1783:                                putassign(cpexpr((expptr)tp), (expptr)p1->datap));
                   1784:                } /* else */
                   1785: 
                   1786:                if(p1->nextp)
                   1787:                        p = mkexpr(OPCOMMA, p,
                   1788:                                putassign(cpexpr((expptr)sp), temp));
                   1789:                else {
                   1790:                        if (type == TYREAL && forcedouble)
                   1791:                                temp->exprblock.opcode =
                   1792:                                        op == OPMIN ? OPDMIN : OPDMAX;
                   1793:                        if (doin_setbound)
                   1794:                                p = mkexpr(OPCOMMA, p, temp);
                   1795:                        else {
                   1796:                                putout (p);
                   1797:                                p = putx(temp);
                   1798:                                }
                   1799:                        if (qp)
                   1800:                                frexpr (qp);
                   1801:                } /* else */
                   1802:        } /* for */
                   1803: 
                   1804:        frchain( &p0 );
                   1805:        return p;
                   1806: }
                   1807: 
                   1808: 
                   1809:  void
                   1810: putwhile(p)
                   1811:  expptr p;
                   1812: {
                   1813:        long where;
                   1814:        int k, n;
                   1815: 
                   1816:        if (wh_next >= wh_last)
                   1817:                {
                   1818:                k = wh_last - wh_first;
                   1819:                n = k + 100;
                   1820:                wh_next = mem(n,0);
                   1821:                wh_last = wh_first + n;
                   1822:                if (k)
                   1823:                        memcpy(wh_next, wh_first, k);
                   1824:                wh_first =  wh_next;
                   1825:                wh_next += k;
                   1826:                wh_last = wh_first + n;
                   1827:                }
                   1828:        if( !ISLOGICAL((k = (p = fixtype(p))->headblock.vtype)))
                   1829:                {
                   1830:                if(k != TYERROR)
                   1831:                        err("non-logical expression in DO WHILE statement");
                   1832:                }
                   1833:        else    {
                   1834:                p1put(P1_WHILE1START);
                   1835:                where = ftell(pass1_file);
                   1836:                p = putx(p);
                   1837:                *wh_next++ = ftell(pass1_file) > where;
                   1838:                p1put(P1_WHILE2START);
                   1839:                p1_expr(p);
                   1840:                }
                   1841:        }

unix.superglobalmegacorp.com

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