Annotation of researchv10no/cmd/f2c/putpcc.c, revision 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.