Annotation of 43BSDReno/pgrm/f77/pass1.tahoe/expr.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char *sccsid[] = "@(#)expr.c    5.3 (Berkeley) 6/23/85";
                      9: #endif not lint
                     10: 
                     11: /*
                     12:  * expr.c
                     13:  *
                     14:  * Routines for handling expressions, f77 compiler pass 1.
                     15:  *
                     16:  * University of Utah CS Dept modification history:
                     17:  *
                     18:  * $Log:       expr.c,v $
                     19:  * Revision 1.3  86/02/26  17:13:37  rcs
                     20:  * Correct COFR 411.
                     21:  * P. Wong
                     22:  * 
                     23:  * Revision 3.16  85/06/21  16:38:09  donn
                     24:  * The fix to mkprim() didn't handle null substring parameters (sigh).
                     25:  * 
                     26:  * Revision 3.15  85/06/04  04:37:03  donn
                     27:  * Changed mkprim() to force substring parameters to be integral types.
                     28:  * 
                     29:  * Revision 3.14  85/06/04  03:41:52  donn
                     30:  * Change impldcl() to handle functions of type 'undefined'.
                     31:  * 
                     32:  * Revision 3.13  85/05/06  23:14:55  donn
                     33:  * Changed mkconv() so that it calls mkaltemp() instead of mktemp() to get
                     34:  * a temporary when converting character strings to integers; previously we
                     35:  * were having problems because mkconv() was called after tempalloc().
                     36:  * 
                     37:  * Revision 3.12  85/03/18  08:07:47  donn
                     38:  * Fixes to help out with short integers -- if integers are by default short,
                     39:  * then so are constants; and if addresses can't be stored in shorts, complain.
                     40:  * 
                     41:  * Revision 3.11  85/03/16  22:31:27  donn
                     42:  * Added hack to mkconv() to allow character values of length > 1 to be
                     43:  * converted to numeric types, for Helge Skrivervik.  Note that this does
                     44:  * not affect use of the intrinsic ichar() conversion.
                     45:  * 
                     46:  * Revision 3.10  85/01/15  21:06:47  donn
                     47:  * Changed mkconv() to comment on implicit conversions; added intrconv() for
                     48:  * use with explicit conversions by intrinsic functions.
                     49:  * 
                     50:  * Revision 3.9  85/01/11  21:05:49  donn
                     51:  * Added changes to implement SAVE statements.
                     52:  * 
                     53:  * Revision 3.8  84/12/17  02:21:06  donn
                     54:  * Added a test to prevent constant folding from being done on expressions
                     55:  * whose type is not known at that point in mkexpr().
                     56:  * 
                     57:  * Revision 3.7  84/12/11  21:14:17  donn
                     58:  * Removed obnoxious 'excess precision' warning.
                     59:  * 
                     60:  * Revision 3.6  84/11/23  01:00:36  donn
                     61:  * Added code to trim excess precision from single-precision constants, and
                     62:  * to warn the user when this occurs.
                     63:  * 
                     64:  * Revision 3.5  84/11/23  00:10:39  donn
                     65:  * Changed stfcall() to remark on argument type clashes in 'calls' to
                     66:  * statement functions.
                     67:  * 
                     68:  * Revision 3.4  84/11/22  21:21:17  donn
                     69:  * Fixed bug in fix to mkexpr() that caused IMPLICIT to affect intrinsics.
                     70:  * 
                     71:  * Revision 3.3  84/11/12  18:26:14  donn
                     72:  * Shuffled some code around so that the compiler remembers to free some vleng
                     73:  * structures which used to just sit around.
                     74:  * 
                     75:  * Revision 3.2  84/10/16  19:24:15  donn
                     76:  * Fix for Peter Montgomery's bug with -C and invalid subscripts -- prevent
                     77:  * core dumps by replacing bad subscripts with good ones.
                     78:  * 
                     79:  * Revision 3.1  84/10/13  01:31:32  donn
                     80:  * Merged Jerry Berkman's version into mine.
                     81:  * 
                     82:  * Revision 2.7  84/09/27  15:42:52  donn
                     83:  * The last fix for multiplying undeclared variables by 0 isn't sufficient,
                     84:  * since the type of the 0 may not be the (implicit) type of the variable.
                     85:  * I added a hack to check the implicit type of implicitly declared
                     86:  * variables...
                     87:  * 
                     88:  * Revision 2.6  84/09/14  19:34:03  donn
                     89:  * Problem noted by Mike Vevea -- mkexpr will sometimes attempt to convert
                     90:  * 0 to type UNKNOWN, which is illegal.  Fix is to use native type instead.
                     91:  * Not sure how correct (or important) this is...
                     92:  * 
                     93:  * Revision 2.5  84/08/05  23:05:27  donn
                     94:  * Added fixes to prevent fixexpr() from slicing and dicing complex conversions
                     95:  * with two operands.
                     96:  * 
                     97:  * Revision 2.4  84/08/05  17:34:48  donn
                     98:  * Added an optimization to mklhs() to detect substrings of the form ch(i:i)
                     99:  * and assign constant length 1 to them.
                    100:  * 
                    101:  * Revision 2.3  84/07/19  19:38:33  donn
                    102:  * Added a typecast to the last fix.  Somehow I missed it the first time...
                    103:  * 
                    104:  * Revision 2.2  84/07/19  17:19:57  donn
                    105:  * Caused OPPAREN expressions to inherit the length of their operands, so
                    106:  * that parenthesized character expressions work correctly.
                    107:  * 
                    108:  * Revision 2.1  84/07/19  12:03:02  donn
                    109:  * Changed comment headers for UofU.
                    110:  * 
                    111:  * Revision 1.2  84/04/06  20:12:17  donn
                    112:  * Fixed bug which caused programs with mixed-type multiplications involving
                    113:  * the constant 0 to choke the compiler.
                    114:  * 
                    115:  */
                    116: 
                    117: #include "defs.h"
                    118: 
                    119: 
                    120: /* little routines to create constant blocks */
                    121: 
                    122: Constp mkconst(t)
                    123: register int t;
                    124: {
                    125: register Constp p;
                    126: 
                    127: p = ALLOC(Constblock);
                    128: p->tag = TCONST;
                    129: p->vtype = t;
                    130: return(p);
                    131: }
                    132: 
                    133: 
                    134: expptr mklogcon(l)
                    135: register int l;
                    136: {
                    137: register Constp  p;
                    138: 
                    139: p = mkconst(TYLOGICAL);
                    140: p->const.ci = l;
                    141: return( (expptr) p );
                    142: }
                    143: 
                    144: 
                    145: 
                    146: expptr mkintcon(l)
                    147: ftnint l;
                    148: {
                    149: register Constp p;
                    150: int usetype;
                    151: 
                    152: if(tyint == TYSHORT)
                    153:   {
                    154:     short s = l;
                    155:     if(l != s)
                    156:       usetype = TYLONG;
                    157:     else
                    158:       usetype = TYSHORT;
                    159:   }
                    160: else
                    161:   usetype = tyint;
                    162: p = mkconst(usetype);
                    163: p->const.ci = l;
                    164: return( (expptr) p );
                    165: }
                    166: 
                    167: 
                    168: 
                    169: expptr mkaddcon(l)
                    170: register int l;
                    171: {
                    172: register Constp p;
                    173: 
                    174: p = mkconst(TYADDR);
                    175: p->const.ci = l;
                    176: return( (expptr) p );
                    177: }
                    178: 
                    179: 
                    180: 
                    181: expptr mkrealcon(t, d)
                    182: register int t;
                    183: double d;
                    184: {
                    185: register Constp p;
                    186: 
                    187: p = mkconst(t);
                    188: p->const.cd[0] = d;
                    189: return( (expptr) p );
                    190: }
                    191: 
                    192: expptr mkbitcon(shift, leng, s)
                    193: int shift;
                    194: register int leng;
                    195: register char *s;
                    196: {
                    197:   Constp p;
                    198:   register int i, j, k;
                    199:   register char *bp;
                    200:   int size;
                    201: 
                    202:   size = (shift*leng + BYTESIZE -1)/BYTESIZE;
                    203:   bp = (char *) ckalloc(size);
                    204: 
                    205:   i = 0;
                    206: 
                    207: #if (HERE == PDP11 || HERE == VAX)
                    208:   j = 0;
                    209: #else
                    210:   j = size;
                    211: #endif
                    212: 
                    213:   k = 0;
                    214: 
                    215:   while (leng > 0)
                    216:     {
                    217:       k |= (hextoi(s[--leng]) << i);
                    218:       i += shift;
                    219:       if (i >= BYTESIZE)
                    220:        {
                    221: #if (HERE == PDP11 || HERE == VAX)
                    222:          bp[j++] = k & MAXBYTE;
                    223: #else
                    224:          bp[--j] = k & MAXBYTE;
                    225: #endif
                    226:          k = k >> BYTESIZE;
                    227:          i -= BYTESIZE;
                    228:        }
                    229:     }
                    230: 
                    231:   if (k != 0)
                    232: #if (HERE == PDP11 || HERE == VAX)
                    233:     bp[j++] = k;
                    234: #else
                    235:     bp[--j] = k;
                    236: #endif
                    237: 
                    238:   p = mkconst(TYBITSTR);
                    239:   p->vleng = ICON(size);
                    240:   p->const.ccp = bp;
                    241: 
                    242:   return ((expptr) p);
                    243: }
                    244: 
                    245: 
                    246: 
                    247: expptr mkstrcon(l,v)
                    248: int l;
                    249: register char *v;
                    250: {
                    251: register Constp p;
                    252: register char *s;
                    253: 
                    254: p = mkconst(TYCHAR);
                    255: p->vleng = ICON(l);
                    256: p->const.ccp = s = (char *) ckalloc(l);
                    257: while(--l >= 0)
                    258:        *s++ = *v++;
                    259: return( (expptr) p );
                    260: }
                    261: 
                    262: 
                    263: expptr mkcxcon(realp,imagp)
                    264: register expptr realp, imagp;
                    265: {
                    266: int rtype, itype;
                    267: register Constp p;
                    268: 
                    269: rtype = realp->headblock.vtype;
                    270: itype = imagp->headblock.vtype;
                    271: 
                    272: if( ISCONST(realp) && ISNUMERIC(rtype) && ISCONST(imagp) && ISNUMERIC(itype) )
                    273:        {
                    274:        p = mkconst( (rtype==TYDREAL||itype==TYDREAL) ? TYDCOMPLEX : TYCOMPLEX);
                    275:        if( ISINT(rtype) )
                    276:                p->const.cd[0] = realp->constblock.const.ci;
                    277:        else    p->const.cd[0] = realp->constblock.const.cd[0];
                    278:        if( ISINT(itype) )
                    279:                p->const.cd[1] = imagp->constblock.const.ci;
                    280:        else    p->const.cd[1] = imagp->constblock.const.cd[0];
                    281:        }
                    282: else
                    283:        {
                    284:        err("invalid complex constant");
                    285:        p = (Constp) errnode();
                    286:        }
                    287: 
                    288: frexpr(realp);
                    289: frexpr(imagp);
                    290: return( (expptr) p );
                    291: }
                    292: 
                    293: 
                    294: expptr errnode()
                    295: {
                    296: struct Errorblock *p;
                    297: p = ALLOC(Errorblock);
                    298: p->tag = TERROR;
                    299: p->vtype = TYERROR;
                    300: return( (expptr) p );
                    301: }
                    302: 
                    303: 
                    304: 
                    305: 
                    306: 
                    307: expptr mkconv(t, p)
                    308: register int t;
                    309: register expptr p;
                    310: {
                    311: register expptr q;
                    312: Addrp r, s;
                    313: register int pt;
                    314: expptr opconv();
                    315: 
                    316: if(t==TYUNKNOWN || t==TYERROR)
                    317:        badtype("mkconv", t);
                    318: pt = p->headblock.vtype;
                    319: if(t == pt)
                    320:        return(p);
                    321: 
                    322: if( pt == TYCHAR && ISNUMERIC(t) )
                    323:        {
                    324:        warn("implicit conversion of character to numeric type");
                    325: 
                    326:        /*
                    327:         * Ugly kluge to copy character values into numerics.
                    328:         */
                    329:        s = mkaltemp(t, ENULL);
                    330:        r = (Addrp) cpexpr(s);
                    331:        r->vtype = TYCHAR;
                    332:        r->varleng = typesize[t];
                    333:        r->vleng = mkintcon(r->varleng);
                    334:        q = mkexpr(OPASSIGN, r, p);
                    335:        q = mkexpr(OPCOMMA, q, s);
                    336:        return(q);
                    337:        }
                    338: 
                    339: #if SZADDR > SZSHORT
                    340: if( pt == TYADDR && t == TYSHORT)
                    341:        {
                    342:        err("insufficient precision to hold address type");
                    343:        return( errnode() );
                    344:        }
                    345: #endif
                    346: if( pt == TYADDR && ISNUMERIC(t) )
                    347:        warn("implicit conversion of address to numeric type");
                    348: 
                    349: if( ISCONST(p) && pt!=TYADDR)
                    350:        {
                    351:        q = (expptr) mkconst(t);
                    352:        consconv(t, &(q->constblock.const),
                    353:                p->constblock.vtype, &(p->constblock.const) );
                    354:        frexpr(p);
                    355:        }
                    356: #if TARGET == PDP11
                    357: else if(ISINT(t) && pt==TYCHAR)
                    358:        {
                    359:        q = mkexpr(OPBITAND, opconv(p,TYSHORT), ICON(255));
                    360:        if(t == TYLONG)
                    361:                q = opconv(q, TYLONG);
                    362:        }
                    363: #endif
                    364: else
                    365:        q = opconv(p, t);
                    366: 
                    367: if(t == TYCHAR)
                    368:        q->constblock.vleng = ICON(1);
                    369: return(q);
                    370: }
                    371: 
                    372: 
                    373: 
                    374: /* intrinsic conversions */
                    375: expptr intrconv(t, p)
                    376: register int t;
                    377: register expptr p;
                    378: {
                    379: register expptr q;
                    380: register int pt;
                    381: expptr opconv();
                    382: 
                    383: if(t==TYUNKNOWN || t==TYERROR)
                    384:        badtype("intrconv", t);
                    385: pt = p->headblock.vtype;
                    386: if(t == pt)
                    387:        return(p);
                    388: 
                    389: else if( ISCONST(p) && pt!=TYADDR)
                    390:        {
                    391:        q = (expptr) mkconst(t);
                    392:        consconv(t, &(q->constblock.const),
                    393:                p->constblock.vtype, &(p->constblock.const) );
                    394:        frexpr(p);
                    395:        }
                    396: #if TARGET == PDP11
                    397: else if(ISINT(t) && pt==TYCHAR)
                    398:        {
                    399:        q = mkexpr(OPBITAND, opconv(p,TYSHORT), ICON(255));
                    400:        if(t == TYLONG)
                    401:                q = opconv(q, TYLONG);
                    402:        }
                    403: #endif
                    404: else
                    405:        q = opconv(p, t);
                    406: 
                    407: if(t == TYCHAR)
                    408:        q->constblock.vleng = ICON(1);
                    409: return(q);
                    410: }
                    411: 
                    412: 
                    413: 
                    414: expptr opconv(p, t)
                    415: expptr p;
                    416: int t;
                    417: {
                    418: register expptr q;
                    419: 
                    420: q = mkexpr(OPCONV, p, PNULL);
                    421: q->headblock.vtype = t;
                    422: return(q);
                    423: }
                    424: 
                    425: 
                    426: 
                    427: expptr addrof(p)
                    428: expptr p;
                    429: {
                    430: return( mkexpr(OPADDR, p, PNULL) );
                    431: }
                    432: 
                    433: 
                    434: 
                    435: tagptr cpexpr(p)
                    436: register tagptr p;
                    437: {
                    438: register tagptr e;
                    439: int tag;
                    440: register chainp ep, pp;
                    441: tagptr cpblock();
                    442: 
                    443: static int blksize[ ] =
                    444:        {       0,
                    445:                sizeof(struct Nameblock),
                    446:                sizeof(struct Constblock),
                    447:                sizeof(struct Exprblock),
                    448:                sizeof(struct Addrblock),
                    449:                sizeof(struct Tempblock),
                    450:                sizeof(struct Primblock),
                    451:                sizeof(struct Listblock),
                    452:                sizeof(struct Errorblock)
                    453:        };
                    454: 
                    455: if(p == NULL)
                    456:        return(NULL);
                    457: 
                    458: if( (tag = p->tag) == TNAME)
                    459:        return(p);
                    460: 
                    461: e = cpblock( blksize[p->tag] , p);
                    462: 
                    463: switch(tag)
                    464:        {
                    465:        case TCONST:
                    466:                if(e->constblock.vtype == TYCHAR)
                    467:                        {
                    468:                        e->constblock.const.ccp =
                    469:                                copyn(1+strlen(e->constblock.const.ccp),
                    470:                                        e->constblock.const.ccp);
                    471:                        e->constblock.vleng =
                    472:                                (expptr) cpexpr(e->constblock.vleng);
                    473:                        }
                    474:        case TERROR:
                    475:                break;
                    476: 
                    477:        case TEXPR:
                    478:                e->exprblock.leftp =  (expptr) cpexpr(p->exprblock.leftp);
                    479:                e->exprblock.rightp = (expptr) cpexpr(p->exprblock.rightp);
                    480:                break;
                    481: 
                    482:        case TLIST:
                    483:                if(pp = p->listblock.listp)
                    484:                        {
                    485:                        ep = e->listblock.listp =
                    486:                                mkchain( cpexpr(pp->datap), CHNULL);
                    487:                        for(pp = pp->nextp ; pp ; pp = pp->nextp)
                    488:                                ep = ep->nextp =
                    489:                                        mkchain( cpexpr(pp->datap), CHNULL);
                    490:                        }
                    491:                break;
                    492: 
                    493:        case TADDR:
                    494:                e->addrblock.vleng = (expptr)  cpexpr(e->addrblock.vleng);
                    495:                e->addrblock.memoffset = (expptr)cpexpr(e->addrblock.memoffset);
                    496:                e->addrblock.istemp = NO;
                    497:                break;
                    498: 
                    499:        case TTEMP:
                    500:                e->tempblock.vleng = (expptr)  cpexpr(e->tempblock.vleng);
                    501:                e->tempblock.istemp = NO;
                    502:                break;
                    503: 
                    504:        case TPRIM:
                    505:                e->primblock.argsp = (struct Listblock *)
                    506:                                        cpexpr(e->primblock.argsp);
                    507:                e->primblock.fcharp = (expptr) cpexpr(e->primblock.fcharp);
                    508:                e->primblock.lcharp = (expptr) cpexpr(e->primblock.lcharp);
                    509:                break;
                    510: 
                    511:        default:
                    512:                badtag("cpexpr", tag);
                    513:        }
                    514: 
                    515: return(e);
                    516: }
                    517: 
                    518: frexpr(p)
                    519: register tagptr p;
                    520: {
                    521: register chainp q;
                    522: 
                    523: if(p == NULL)
                    524:        return;
                    525: 
                    526: switch(p->tag)
                    527:        {
                    528:        case TCONST:
                    529:                switch (p->constblock.vtype)
                    530:                        {
                    531:                        case TYBITSTR:
                    532:                        case TYCHAR:
                    533:                        case TYHOLLERITH:
                    534:                                free( (charptr) (p->constblock.const.ccp) );
                    535:                                frexpr(p->constblock.vleng);
                    536:                        }
                    537:                break;
                    538: 
                    539:        case TADDR:
                    540:                if (!optimflag && p->addrblock.istemp)
                    541:                        {
                    542:                        frtemp(p);
                    543:                        return;
                    544:                        }
                    545:                frexpr(p->addrblock.vleng);
                    546:                frexpr(p->addrblock.memoffset);
                    547:                break;
                    548: 
                    549:        case TTEMP:
                    550:                frexpr(p->tempblock.vleng);
                    551:                break;
                    552: 
                    553:        case TERROR:
                    554:                break;
                    555: 
                    556:        case TNAME:
                    557:                return;
                    558: 
                    559:        case TPRIM:
                    560:                frexpr(p->primblock.argsp);
                    561:                frexpr(p->primblock.fcharp);
                    562:                frexpr(p->primblock.lcharp);
                    563:                break;
                    564: 
                    565:        case TEXPR:
                    566:                frexpr(p->exprblock.leftp);
                    567:                if(p->exprblock.rightp)
                    568:                        frexpr(p->exprblock.rightp);
                    569:                break;
                    570: 
                    571:        case TLIST:
                    572:                for(q = p->listblock.listp ; q ; q = q->nextp)
                    573:                        frexpr(q->datap);
                    574:                frchain( &(p->listblock.listp) );
                    575:                break;
                    576: 
                    577:        default:
                    578:                badtag("frexpr", p->tag);
                    579:        }
                    580: 
                    581: free( (charptr) p );
                    582: }
                    583: 
                    584: /* fix up types in expression; replace subtrees and convert
                    585:    names to address blocks */
                    586: 
                    587: expptr fixtype(p)
                    588: register tagptr p;
                    589: {
                    590: 
                    591: if(p == 0)
                    592:        return(0);
                    593: 
                    594: switch(p->tag)
                    595:        {
                    596:        case TCONST:
                    597:                return( (expptr) p );
                    598: 
                    599:        case TADDR:
                    600:                p->addrblock.memoffset = fixtype(p->addrblock.memoffset);
                    601:                return( (expptr) p);
                    602: 
                    603:        case TTEMP:
                    604:                return( (expptr) p);
                    605: 
                    606:        case TERROR:
                    607:                return( (expptr) p);
                    608: 
                    609:        default:
                    610:                badtag("fixtype", p->tag);
                    611: 
                    612:        case TEXPR:
                    613:                return( fixexpr(p) );
                    614: 
                    615:        case TLIST:
                    616:                return( (expptr) p );
                    617: 
                    618:        case TPRIM:
                    619:                if(p->primblock.argsp && p->primblock.namep->vclass!=CLVAR)
                    620:                        {
                    621:                        if(p->primblock.namep->vtype == TYSUBR)
                    622:                                {
                    623:                                err("function invocation of subroutine");
                    624:                                return( errnode() );
                    625:                                }
                    626:                        else
                    627:                                return( mkfunct(p) );
                    628:                        }
                    629:                else    return( mklhs(p) );
                    630:        }
                    631: }
                    632: 
                    633: 
                    634: 
                    635: 
                    636: 
                    637: /* special case tree transformations and cleanups of expression trees */
                    638: 
                    639: expptr fixexpr(p)
                    640: register Exprp p;
                    641: {
                    642: expptr lp;
                    643: register expptr rp;
                    644: register expptr q;
                    645: int opcode, ltype, rtype, ptype, mtype;
                    646: expptr lconst, rconst;
                    647: expptr mkpower();
                    648: 
                    649: if( ISERROR(p) )
                    650:        return( (expptr) p );
                    651: else if(p->tag != TEXPR)
                    652:        badtag("fixexpr", p->tag);
                    653: opcode = p->opcode;
                    654: if (ISCONST(p->leftp))
                    655:        lconst = (expptr) cpexpr(p->leftp);
                    656: else
                    657:        lconst = NULL;
                    658: if (p->rightp && ISCONST(p->rightp))
                    659:        rconst = (expptr) cpexpr(p->rightp);
                    660: else
                    661:        rconst = NULL;
                    662: lp = p->leftp = fixtype(p->leftp);
                    663: ltype = lp->headblock.vtype;
                    664: if(opcode==OPASSIGN && lp->tag!=TADDR && lp->tag!=TTEMP)
                    665:        {
                    666:        err("left side of assignment must be variable");
                    667:        frexpr(p);
                    668:        return( errnode() );
                    669:        }
                    670: 
                    671: if(p->rightp)
                    672:        {
                    673:        rp = p->rightp = fixtype(p->rightp);
                    674:        rtype = rp->headblock.vtype;
                    675:        }
                    676: else
                    677:        {
                    678:        rp = NULL;
                    679:        rtype = 0;
                    680:        }
                    681: 
                    682: if(ltype==TYERROR || rtype==TYERROR)
                    683:        {
                    684:        frexpr(p);
                    685:        frexpr(lconst);
                    686:        frexpr(rconst);
                    687:        return( errnode() );
                    688:        }
                    689: 
                    690: /* force folding if possible */
                    691: if( ISCONST(lp) && (rp==NULL || ISCONST(rp)) )
                    692:        {
                    693:        q = mkexpr(opcode, lp, rp);
                    694:        if( ISCONST(q) )
                    695:                {
                    696:                frexpr(lconst);
                    697:                frexpr(rconst);
                    698:                return(q);
                    699:                }
                    700:        free( (charptr) q );    /* constants did not fold */
                    701:        }
                    702: 
                    703: if( (ptype = cktype(opcode, ltype, rtype)) == TYERROR)
                    704:        {
                    705:        frexpr(p);
                    706:        frexpr(lconst);
                    707:        frexpr(rconst);
                    708:        return( errnode() );
                    709:        }
                    710: 
                    711: switch(opcode)
                    712:        {
                    713:        case OPCONCAT:
                    714:                if(p->vleng == NULL)
                    715:                        p->vleng = mkexpr(OPPLUS,
                    716:                                cpexpr(lp->headblock.vleng),
                    717:                                cpexpr(rp->headblock.vleng) );
                    718:                break;
                    719: 
                    720:        case OPASSIGN:
                    721:        case OPPLUSEQ:
                    722:        case OPSTAREQ:
                    723:                if(ltype == rtype)
                    724:                        break;
                    725: #if TARGET == VAX
                    726:                if( ! rconst && ISREAL(ltype) && ISREAL(rtype) )
                    727:                        break;
                    728: #endif
                    729:                if( ISCOMPLEX(ltype) || ISCOMPLEX(rtype) )
                    730:                        break;
                    731:                if( ONEOF(ltype, MSKADDR|MSKINT) && ONEOF(rtype, MSKADDR|MSKINT)
                    732: #if FAMILY==PCC
                    733:                    && typesize[ltype]>=typesize[rtype] )
                    734: #else
                    735:                    && typesize[ltype]==typesize[rtype] )
                    736: #endif
                    737:                        break;
                    738:                if (rconst)
                    739:                        {
                    740:                        p->rightp = fixtype( mkconv(ptype, cpexpr(rconst)) );
                    741:                        frexpr(rp);
                    742:                        }
                    743:                else
                    744:                        p->rightp = fixtype(mkconv(ptype, rp));
                    745:                break;
                    746: 
                    747:        case OPSLASH:
                    748:                if( ISCOMPLEX(rtype) )
                    749:                        {
                    750:                        p = (Exprp) call2(ptype,
                    751:                                ptype==TYCOMPLEX? "c_div" : "z_div",
                    752:                                mkconv(ptype, lp), mkconv(ptype, rp) );
                    753:                        break;
                    754:                        }
                    755:        case OPPLUS:
                    756:        case OPMINUS:
                    757:        case OPSTAR:
                    758:        case OPMOD:
                    759: #if TARGET == VAX
                    760:                if(ptype==TYDREAL && ( (ltype==TYREAL && ! lconst ) ||
                    761:                    (rtype==TYREAL && ! rconst ) ))
                    762:                        break;
                    763: #endif
                    764:                if( ISCOMPLEX(ptype) )
                    765:                        break;
                    766:                if(ltype != ptype)
                    767:                        if (lconst)
                    768:                                {
                    769:                                p->leftp = fixtype(mkconv(ptype,
                    770:                                                cpexpr(lconst)));
                    771:                                frexpr(lp);
                    772:                                }
                    773:                        else
                    774:                                p->leftp = fixtype(mkconv(ptype,lp));
                    775:                if(rtype != ptype)
                    776:                        if (rconst)
                    777:                                {
                    778:                                p->rightp = fixtype(mkconv(ptype,
                    779:                                                cpexpr(rconst)));
                    780:                                frexpr(rp);
                    781:                                }
                    782:                        else
                    783:                                p->rightp = fixtype(mkconv(ptype,rp));
                    784:                break;
                    785: 
                    786:        case OPPOWER:
                    787:                return( mkpower(p) );
                    788: 
                    789:        case OPLT:
                    790:        case OPLE:
                    791:        case OPGT:
                    792:        case OPGE:
                    793:        case OPEQ:
                    794:        case OPNE:
                    795:                if(ltype == rtype)
                    796:                        break;
                    797:                mtype = cktype(OPMINUS, ltype, rtype);
                    798: #if TARGET == VAX
                    799:                if(mtype==TYDREAL && ( (ltype==TYREAL && ! lconst) ||
                    800:                    (rtype==TYREAL && ! rconst) ))
                    801:                        break;
                    802: #endif
                    803:                if( ISCOMPLEX(mtype) )
                    804:                        break;
                    805:                if(ltype != mtype)
                    806:                        if (lconst)
                    807:                                {
                    808:                                p->leftp = fixtype(mkconv(mtype,
                    809:                                                cpexpr(lconst)));
                    810:                                frexpr(lp);
                    811:                                }
                    812:                        else
                    813:                                p->leftp = fixtype(mkconv(mtype,lp));
                    814:                if(rtype != mtype)
                    815:                        if (rconst)
                    816:                                {
                    817:                                p->rightp = fixtype(mkconv(mtype,
                    818:                                                cpexpr(rconst)));
                    819:                                frexpr(rp);
                    820:                                }
                    821:                        else
                    822:                                p->rightp = fixtype(mkconv(mtype,rp));
                    823:                break;
                    824: 
                    825: 
                    826:        case OPCONV:
                    827:                if(ISCOMPLEX(p->vtype))
                    828:                        {
                    829:                        ptype = cktype(OPCONV, p->vtype, ltype);
                    830:                        if(p->rightp)
                    831:                                ptype = cktype(OPCONV, ptype, rtype);
                    832:                        break;
                    833:                        }
                    834:                ptype = cktype(OPCONV, p->vtype, ltype);
                    835:                if(lp->tag==TEXPR && lp->exprblock.opcode==OPCOMMA)
                    836:                        {
                    837:                        lp->exprblock.rightp =
                    838:                                fixtype( mkconv(ptype, lp->exprblock.rightp) );
                    839:                        free( (charptr) p );
                    840:                        p = (Exprp) lp;
                    841:                        }
                    842:                break;
                    843: 
                    844:        case OPADDR:
                    845:                if(lp->tag==TEXPR && lp->exprblock.opcode==OPADDR)
                    846:                        fatal("addr of addr");
                    847:                break;
                    848: 
                    849:        case OPCOMMA:
                    850:        case OPQUEST:
                    851:        case OPCOLON:
                    852:                break;
                    853: 
                    854:        case OPPAREN:
                    855:                p->vleng = (expptr) cpexpr( lp->headblock.vleng );
                    856:                break;
                    857: 
                    858:        case OPMIN:
                    859:        case OPMAX:
                    860:                ptype = p->vtype;
                    861:                break;
                    862: 
                    863:        default:
                    864:                break;
                    865:        }
                    866: 
                    867: p->vtype = ptype;
                    868: frexpr(lconst);
                    869: frexpr(rconst);
                    870: return((expptr) p);
                    871: }
                    872: 
                    873: #if SZINT < SZLONG
                    874: /*
                    875:    for efficient subscripting, replace long ints by shorts
                    876:    in easy places
                    877: */
                    878: 
                    879: expptr shorten(p)
                    880: register expptr p;
                    881: {
                    882: register expptr q;
                    883: 
                    884: if(p->headblock.vtype != TYLONG)
                    885:        return(p);
                    886: 
                    887: switch(p->tag)
                    888:        {
                    889:        case TERROR:
                    890:        case TLIST:
                    891:                return(p);
                    892: 
                    893:        case TCONST:
                    894:        case TADDR:
                    895:                return( mkconv(TYINT,p) );
                    896: 
                    897:        case TEXPR:
                    898:                break;
                    899: 
                    900:        default:
                    901:                badtag("shorten", p->tag);
                    902:        }
                    903: 
                    904: switch(p->exprblock.opcode)
                    905:        {
                    906:        case OPPLUS:
                    907:        case OPMINUS:
                    908:        case OPSTAR:
                    909:                q = shorten( cpexpr(p->exprblock.rightp) );
                    910:                if(q->headblock.vtype == TYINT)
                    911:                        {
                    912:                        p->exprblock.leftp = shorten(p->exprblock.leftp);
                    913:                        if(p->exprblock.leftp->headblock.vtype == TYLONG)
                    914:                                frexpr(q);
                    915:                        else
                    916:                                {
                    917:                                frexpr(p->exprblock.rightp);
                    918:                                p->exprblock.rightp = q;
                    919:                                p->exprblock.vtype = TYINT;
                    920:                                }
                    921:                        }
                    922:                break;
                    923: 
                    924:        case OPNEG:
                    925:        case OPPAREN:
                    926:                p->exprblock.leftp = shorten(p->exprblock.leftp);
                    927:                if(p->exprblock.leftp->headblock.vtype == TYINT)
                    928:                        p->exprblock.vtype = TYINT;
                    929:                break;
                    930: 
                    931:        case OPCALL:
                    932:        case OPCCALL:
                    933:                p = mkconv(TYINT,p);
                    934:                break;
                    935:        default:
                    936:                break;
                    937:        }
                    938: 
                    939: return(p);
                    940: }
                    941: #endif
                    942: /* fix an argument list, taking due care for special first level cases */
                    943: 
                    944: fixargs(doput, p0)
                    945: int doput;     /* doput is true if the function is not intrinsic;
                    946:                   was used to decide whether to do a putconst,
                    947:                   but this is no longer done here (Feb82)*/
                    948: struct Listblock *p0;
                    949: {
                    950: register chainp p;
                    951: register tagptr q, t;
                    952: register int qtag;
                    953: int nargs;
                    954: Addrp mkscalar();
                    955: 
                    956: nargs = 0;
                    957: if(p0)
                    958:     for(p = p0->listp ; p ; p = p->nextp)
                    959:        {
                    960:        ++nargs;
                    961:        q = p->datap;
                    962:        qtag = q->tag;
                    963:        if(qtag == TCONST)
                    964:                {
                    965: 
                    966: /*
                    967:                if(q->constblock.vtype == TYSHORT)
                    968:                        q = (tagptr) mkconv(tyint, q);
                    969: */  
                    970:                p->datap = q ;
                    971:                }
                    972:        else if(qtag==TPRIM && q->primblock.argsp==0 &&
                    973:                q->primblock.namep->vclass==CLPROC)
                    974:                        p->datap = (tagptr) mkaddr(q->primblock.namep);
                    975:        else if(qtag==TPRIM && q->primblock.argsp==0 &&
                    976:                q->primblock.namep->vdim!=NULL)
                    977:                        p->datap = (tagptr) mkscalar(q->primblock.namep);
                    978:        else if(qtag==TPRIM && q->primblock.argsp==0 &&
                    979:                q->primblock.namep->vdovar && 
                    980:                (t = (tagptr) memversion(q->primblock.namep)) )
                    981:                        p->datap = (tagptr) fixtype(t);
                    982:        else
                    983:                p->datap = (tagptr) fixtype(q);
                    984:        }
                    985: return(nargs);
                    986: }
                    987: 
                    988: 
                    989: Addrp mkscalar(np)
                    990: register Namep np;
                    991: {
                    992: register Addrp ap;
                    993: 
                    994: vardcl(np);
                    995: ap = mkaddr(np);
                    996: 
                    997: #if TARGET == VAX || TARGET == TAHOE
                    998:        /* on the VAX, prolog causes array arguments
                    999:           to point at the (0,...,0) element, except when
                   1000:           subscript checking is on
                   1001:        */
                   1002: #ifdef SDB
                   1003:        if( !checksubs && !sdbflag && np->vstg==STGARG)
                   1004: #else
                   1005:        if( !checksubs && np->vstg==STGARG)
                   1006: #endif
                   1007:                {
                   1008:                register struct Dimblock *dp;
                   1009:                dp = np->vdim;
                   1010:                frexpr(ap->memoffset);
                   1011:                ap->memoffset = mkexpr(OPSTAR,
                   1012:                                (np->vtype==TYCHAR ?
                   1013:                                        cpexpr(np->vleng) :
                   1014:                                        (tagptr)ICON(typesize[np->vtype]) ),
                   1015:                                cpexpr(dp->baseoffset) );
                   1016:                }
                   1017: #endif
                   1018: return(ap);
                   1019: }
                   1020: 
                   1021: 
                   1022: 
                   1023: 
                   1024: 
                   1025: expptr mkfunct(p)
                   1026: register struct Primblock *p;
                   1027: {
                   1028: struct Entrypoint *ep;
                   1029: Addrp ap;
                   1030: struct Extsym *extp;
                   1031: register Namep np;
                   1032: register expptr q;
                   1033: expptr intrcall(), stfcall();
                   1034: int k, nargs;
                   1035: int class;
                   1036: 
                   1037: if(p->tag != TPRIM)
                   1038:        return( errnode() );
                   1039: 
                   1040: np = p->namep;
                   1041: class = np->vclass;
                   1042: 
                   1043: if(class == CLUNKNOWN)
                   1044:        {
                   1045:        np->vclass = class = CLPROC;
                   1046:        if(np->vstg == STGUNKNOWN)
                   1047:                {
                   1048:                if(np->vtype!=TYSUBR && (k = intrfunct(np->varname)) )
                   1049:                        {
                   1050:                        np->vstg = STGINTR;
                   1051:                        np->vardesc.varno = k;
                   1052:                        np->vprocclass = PINTRINSIC;
                   1053:                        }
                   1054:                else
                   1055:                        {
                   1056:                        extp = mkext( varunder(VL,np->varname) );
                   1057:                        if(extp->extstg == STGCOMMON)
                   1058:                                warn("conflicting declarations", np->varname);
                   1059:                        extp->extstg = STGEXT;
                   1060:                        np->vstg = STGEXT;
                   1061:                        np->vardesc.varno = extp - extsymtab;
                   1062:                        np->vprocclass = PEXTERNAL;
                   1063:                        }
                   1064:                }
                   1065:        else if(np->vstg==STGARG)
                   1066:                {
                   1067:                if(np->vtype!=TYCHAR && !ftn66flag)
                   1068:                    warn("Dummy procedure not declared EXTERNAL. Code may be wrong.");
                   1069:                np->vprocclass = PEXTERNAL;
                   1070:                }
                   1071:        }
                   1072: 
                   1073: if(class != CLPROC)
                   1074:        fatali("invalid class code %d for function", class);
                   1075: if(p->fcharp || p->lcharp)
                   1076:        {
                   1077:        err("no substring of function call");
                   1078:        goto error;
                   1079:        }
                   1080: impldcl(np);
                   1081: nargs = fixargs( np->vprocclass!=PINTRINSIC,  p->argsp);
                   1082: 
                   1083: switch(np->vprocclass)
                   1084:        {
                   1085:        case PEXTERNAL:
                   1086:                ap = mkaddr(np);
                   1087:        call:
                   1088:                q = mkexpr(OPCALL, ap, p->argsp);
                   1089:                if( (q->exprblock.vtype = np->vtype) == TYUNKNOWN)
                   1090:                        {
                   1091:                        err("attempt to use untyped function");
                   1092:                        goto error;
                   1093:                        }
                   1094:                if(np->vleng)
                   1095:                        q->exprblock.vleng = (expptr) cpexpr(np->vleng);
                   1096:                break;
                   1097: 
                   1098:        case PINTRINSIC:
                   1099:                q = intrcall(np, p->argsp, nargs);
                   1100:                break;
                   1101: 
                   1102:        case PSTFUNCT:
                   1103:                q = stfcall(np, p->argsp);
                   1104:                break;
                   1105: 
                   1106:        case PTHISPROC:
                   1107:                warn("recursive call");
                   1108:                for(ep = entries ; ep ; ep = ep->entnextp)
                   1109:                        if(ep->enamep == np)
                   1110:                                break;
                   1111:                if(ep == NULL)
                   1112:                        fatal("mkfunct: impossible recursion");
                   1113:                ap = builtin(np->vtype, varstr(XL, ep->entryname->extname) );
                   1114:                goto call;
                   1115: 
                   1116:        default:
                   1117:                fatali("mkfunct: impossible vprocclass %d",
                   1118:                        (int) (np->vprocclass) );
                   1119:        }
                   1120: free( (charptr) p );
                   1121: return(q);
                   1122: 
                   1123: error:
                   1124:        frexpr(p);
                   1125:        return( errnode() );
                   1126: }
                   1127: 
                   1128: 
                   1129: 
                   1130: LOCAL expptr stfcall(np, actlist)
                   1131: Namep np;
                   1132: struct Listblock *actlist;
                   1133: {
                   1134: register chainp actuals;
                   1135: int nargs;
                   1136: chainp oactp, formals;
                   1137: int type;
                   1138: expptr q, rhs, ap;
                   1139: Namep tnp;
                   1140: register struct Rplblock *rp;
                   1141: struct Rplblock *tlist;
                   1142: 
                   1143: if(actlist)
                   1144:        {
                   1145:        actuals = actlist->listp;
                   1146:        free( (charptr) actlist);
                   1147:        }
                   1148: else
                   1149:        actuals = NULL;
                   1150: oactp = actuals;
                   1151: 
                   1152: nargs = 0;
                   1153: tlist = NULL;
                   1154: if( (type = np->vtype) == TYUNKNOWN)
                   1155:        {
                   1156:        err("attempt to use untyped statement function");
                   1157:        q = errnode();
                   1158:        goto ret;
                   1159:        }
                   1160: formals = (chainp) (np->varxptr.vstfdesc->datap);
                   1161: rhs = (expptr) (np->varxptr.vstfdesc->nextp);
                   1162: 
                   1163: /* copy actual arguments into temporaries */
                   1164: while(actuals!=NULL && formals!=NULL)
                   1165:        {
                   1166:        rp = ALLOC(Rplblock);
                   1167:        rp->rplnp = tnp = (Namep) (formals->datap);
                   1168:        ap = fixtype(actuals->datap);
                   1169:        if(tnp->vtype==ap->headblock.vtype && tnp->vtype!=TYCHAR
                   1170:           && (ap->tag==TCONST || ap->tag==TADDR || ap->tag==TTEMP) )
                   1171:                {
                   1172:                rp->rplvp = (expptr) ap;
                   1173:                rp->rplxp = NULL;
                   1174:                rp->rpltag = ap->tag;
                   1175:                }
                   1176:        else    {
                   1177:                rp->rplvp = (expptr) mktemp(tnp->vtype, tnp->vleng);
                   1178:                rp->rplxp = fixtype( mkexpr(OPASSIGN, cpexpr(rp->rplvp), ap) );
                   1179:                if( (rp->rpltag = rp->rplxp->tag) == TERROR)
                   1180:                        err("disagreement of argument types in statement function call");
                   1181:                else if(tnp->vtype!=ap->headblock.vtype)
                   1182:                        warn("argument type mismatch in statement function");
                   1183:                }
                   1184:        rp->rplnextp = tlist;
                   1185:        tlist = rp;
                   1186:        actuals = actuals->nextp;
                   1187:        formals = formals->nextp;
                   1188:        ++nargs;
                   1189:        }
                   1190: 
                   1191: if(actuals!=NULL || formals!=NULL)
                   1192:        err("statement function definition and argument list differ");
                   1193: 
                   1194: /*
                   1195:    now push down names involved in formal argument list, then
                   1196:    evaluate rhs of statement function definition in this environment
                   1197: */
                   1198: 
                   1199: if(tlist)      /* put tlist in front of the rpllist */
                   1200:        {
                   1201:        for(rp = tlist; rp->rplnextp; rp = rp->rplnextp)
                   1202:                ;
                   1203:        rp->rplnextp = rpllist;
                   1204:        rpllist = tlist;
                   1205:        }
                   1206: 
                   1207: q = (expptr) mkconv(type, fixtype(cpexpr(rhs)) );
                   1208: 
                   1209: /* now generate the tree ( t1=a1, (t2=a2,... , f))))) */
                   1210: while(--nargs >= 0)
                   1211:        {
                   1212:        if(rpllist->rplxp)
                   1213:                q = mkexpr(OPCOMMA, rpllist->rplxp, q);
                   1214:        rp = rpllist->rplnextp;
                   1215:        frexpr(rpllist->rplvp);
                   1216:        free(rpllist);
                   1217:        rpllist = rp;
                   1218:        }
                   1219: 
                   1220: ret:
                   1221:        frchain( &oactp );
                   1222:        return(q);
                   1223: }
                   1224: 
                   1225: 
                   1226: 
                   1227: 
                   1228: Addrp mkplace(np)
                   1229: register Namep np;
                   1230: {
                   1231: register Addrp s;
                   1232: register struct Rplblock *rp;
                   1233: int regn;
                   1234: 
                   1235: /* is name on the replace list? */
                   1236: 
                   1237: for(rp = rpllist ; rp ; rp = rp->rplnextp)
                   1238:        {
                   1239:        if(np == rp->rplnp)
                   1240:                {
                   1241:                if(rp->rpltag == TNAME)
                   1242:                        {
                   1243:                        np = (Namep) (rp->rplvp);
                   1244:                        break;
                   1245:                        }
                   1246:                else    return( (Addrp) cpexpr(rp->rplvp) );
                   1247:                }
                   1248:        }
                   1249: 
                   1250: /* is variable a DO index in a register ? */
                   1251: 
                   1252: if(np->vdovar && ( (regn = inregister(np)) >= 0) )
                   1253:        if(np->vtype == TYERROR)
                   1254:                return( (Addrp) errnode() );
                   1255:        else
                   1256:                {
                   1257:                s = ALLOC(Addrblock);
                   1258:                s->tag = TADDR;
                   1259:                s->vstg = STGREG;
                   1260:                s->vtype = TYIREG;
                   1261:                s->issaved = np->vsave;
                   1262:                s->memno = regn;
                   1263:                s->memoffset = ICON(0);
                   1264:                return(s);
                   1265:                }
                   1266: 
                   1267: vardcl(np);
                   1268: return(mkaddr(np));
                   1269: }
                   1270: 
                   1271: 
                   1272: 
                   1273: 
                   1274: expptr mklhs(p)
                   1275: register struct Primblock *p;
                   1276: {
                   1277: expptr suboffset();
                   1278: register Addrp s;
                   1279: Namep np;
                   1280: 
                   1281: if(p->tag != TPRIM)
                   1282:        return( (expptr) p );
                   1283: np = p->namep;
                   1284: 
                   1285: s = mkplace(np);
                   1286: if(s->tag!=TADDR || s->vstg==STGREG)
                   1287:        {
                   1288:        free( (charptr) p );
                   1289:        return( (expptr) s );
                   1290:        }
                   1291: 
                   1292: /* compute the address modified by subscripts */
                   1293: 
                   1294: s->memoffset = mkexpr(OPPLUS, s->memoffset, suboffset(p) );
                   1295: frexpr(p->argsp);
                   1296: p->argsp = NULL;
                   1297: 
                   1298: /* now do substring part */
                   1299: 
                   1300: if(p->fcharp || p->lcharp)
                   1301:        {
                   1302:        if(np->vtype != TYCHAR)
                   1303:                errstr("substring of noncharacter %s", varstr(VL,np->varname));
                   1304:        else    {
                   1305:                if(p->lcharp == NULL)
                   1306:                        p->lcharp = (expptr) cpexpr(s->vleng);
                   1307:                frexpr(s->vleng);
                   1308:                if(p->fcharp)
                   1309:                        {
                   1310:                        if(p->fcharp->tag == TPRIM && p->lcharp->tag == TPRIM
                   1311:                        && p->fcharp->primblock.namep == p->lcharp->primblock.namep)
                   1312:                                /* A trivial optimization -- upper == lower */
                   1313:                                s->vleng = ICON(1);
                   1314:                        else
                   1315:                                s->vleng = mkexpr(OPMINUS, p->lcharp,
                   1316:                                        mkexpr(OPMINUS, p->fcharp, ICON(1) ));
                   1317:                        }
                   1318:                else
                   1319:                        s->vleng = p->lcharp;
                   1320:                }
                   1321:        }
                   1322: 
                   1323: s->vleng = fixtype( s->vleng );
                   1324: s->memoffset = fixtype( s->memoffset );
                   1325: free( (charptr) p );
                   1326: return( (expptr) s );
                   1327: }
                   1328: 
                   1329: 
                   1330: 
                   1331: 
                   1332: 
                   1333: deregister(np)
                   1334: Namep np;
                   1335: {
                   1336: if(nregvar>0 && regnamep[nregvar-1]==np)
                   1337:        {
                   1338:        --nregvar;
                   1339: #if FAMILY == DMR
                   1340:        putnreg();
                   1341: #endif
                   1342:        }
                   1343: }
                   1344: 
                   1345: 
                   1346: 
                   1347: 
                   1348: Addrp memversion(np)
                   1349: register Namep np;
                   1350: {
                   1351: register Addrp s;
                   1352: 
                   1353: if(np->vdovar==NO || (inregister(np)<0) )
                   1354:        return(NULL);
                   1355: np->vdovar = NO;
                   1356: s = mkplace(np);
                   1357: np->vdovar = YES;
                   1358: return(s);
                   1359: }
                   1360: 
                   1361: 
                   1362: 
                   1363: inregister(np)
                   1364: register Namep np;
                   1365: {
                   1366: register int i;
                   1367: 
                   1368: for(i = 0 ; i < nregvar ; ++i)
                   1369:        if(regnamep[i] == np)
                   1370:                return( regnum[i] );
                   1371: return(-1);
                   1372: }
                   1373: 
                   1374: 
                   1375: 
                   1376: 
                   1377: enregister(np)
                   1378: Namep np;
                   1379: {
                   1380: if( inregister(np) >= 0)
                   1381:        return(YES);
                   1382: if(nregvar >= maxregvar)
                   1383:        return(NO);
                   1384: vardcl(np);
                   1385: if( ONEOF(np->vtype, MSKIREG) )
                   1386:        {
                   1387:        regnamep[nregvar++] = np;
                   1388:        if(nregvar > highregvar)
                   1389:                highregvar = nregvar;
                   1390: #if FAMILY == DMR
                   1391:        putnreg();
                   1392: #endif
                   1393:        return(YES);
                   1394:        }
                   1395: else
                   1396:        return(NO);
                   1397: }
                   1398: 
                   1399: 
                   1400: 
                   1401: 
                   1402: expptr suboffset(p)
                   1403: register struct Primblock *p;
                   1404: {
                   1405: int n;
                   1406: expptr size;
                   1407: expptr oftwo();
                   1408: chainp cp;
                   1409: expptr offp, prod;
                   1410: expptr subcheck();
                   1411: struct Dimblock *dimp;
                   1412: expptr sub[MAXDIM+1];
                   1413: register Namep np;
                   1414: 
                   1415: np = p->namep;
                   1416: offp = ICON(0);
                   1417: n = 0;
                   1418: if(p->argsp)
                   1419:        for(cp = p->argsp->listp ; cp ; ++n, cp = cp->nextp)
                   1420:                {
                   1421:                sub[n] = fixtype(cpexpr(cp->datap));
                   1422:                if ( ! ISINT(sub[n]->headblock.vtype)) {
                   1423:                        errstr("%s: non-integer subscript expression",
                   1424:                                varstr(VL, np->varname) );
                   1425:                        /* Provide a substitute -- go on to find more errors */
                   1426:                        frexpr(sub[n]);
                   1427:                        sub[n] = ICON(1);
                   1428:                }
                   1429:                if(n > maxdim)
                   1430:                        {
                   1431:                           char str[28+VL];
                   1432:                           sprintf(str, "%s: more than %d subscripts",
                   1433:                                varstr(VL, np->varname), maxdim );
                   1434:                           err( str );
                   1435:                        break;
                   1436:                        }
                   1437:                }
                   1438: 
                   1439: dimp = np->vdim;
                   1440: if(n>0 && dimp==NULL)
                   1441:        errstr("%s: subscripts on scalar variable", 
                   1442:                varstr(VL, np->varname), maxdim );
                   1443: else if(dimp && dimp->ndim!=n)
                   1444:        errstr("wrong number of subscripts on %s",
                   1445:                varstr(VL, np->varname) );
                   1446: else if(n > 0)
                   1447:        {
                   1448:        prod = sub[--n];
                   1449:        while( --n >= 0)
                   1450:                prod = mkexpr(OPPLUS, sub[n],
                   1451:                        mkexpr(OPSTAR, prod, cpexpr(dimp->dims[n].dimsize)) );
                   1452: #if TARGET == VAX || TARGET == TAHOE
                   1453: #ifdef SDB
                   1454:        if(checksubs || np->vstg!=STGARG || sdbflag)
                   1455: #else
                   1456:        if(checksubs || np->vstg!=STGARG)
                   1457: #endif
                   1458:                prod = mkexpr(OPMINUS, prod, cpexpr(dimp->baseoffset));
                   1459: #else
                   1460:        prod = mkexpr(OPMINUS, prod, cpexpr(dimp->baseoffset));
                   1461: #endif
                   1462:        if(checksubs)
                   1463:                prod = subcheck(np, prod);
                   1464:        size = np->vtype == TYCHAR ?
                   1465:                (expptr) cpexpr(np->vleng) : ICON(typesize[np->vtype]);
                   1466:        if (!oftwo(size))
                   1467:                prod = mkexpr(OPSTAR, prod, size);
                   1468:        else
                   1469:                prod = mkexpr(OPLSHIFT,prod,oftwo(size));
                   1470: 
                   1471:        offp = mkexpr(OPPLUS, offp, prod);
                   1472:        }
                   1473: 
                   1474: if(p->fcharp && np->vtype==TYCHAR)
                   1475:        offp = mkexpr(OPPLUS, offp, mkexpr(OPMINUS, cpexpr(p->fcharp), ICON(1) ));
                   1476: 
                   1477: return(offp);
                   1478: }
                   1479: 
                   1480: 
                   1481: 
                   1482: 
                   1483: expptr subcheck(np, p)
                   1484: Namep np;
                   1485: register expptr p;
                   1486: {
                   1487: struct Dimblock *dimp;
                   1488: expptr t, checkvar, checkcond, badcall;
                   1489: 
                   1490: dimp = np->vdim;
                   1491: if(dimp->nelt == NULL)
                   1492:        return(p);      /* don't check arrays with * bounds */
                   1493: checkvar = NULL;
                   1494: checkcond = NULL;
                   1495: if( ISICON(p) )
                   1496:        {
                   1497:        if(p->constblock.const.ci < 0)
                   1498:                goto badsub;
                   1499:        if( ISICON(dimp->nelt) )
                   1500:                if(p->constblock.const.ci < dimp->nelt->constblock.const.ci)
                   1501:                        return(p);
                   1502:                else
                   1503:                        goto badsub;
                   1504:        }
                   1505: if(p->tag==TADDR && p->addrblock.vstg==STGREG)
                   1506:        {
                   1507:        checkvar = (expptr) cpexpr(p);
                   1508:        t = p;
                   1509:        }
                   1510: else   {
                   1511:        checkvar = (expptr) mktemp(p->headblock.vtype, ENULL);
                   1512:        t = mkexpr(OPASSIGN, cpexpr(checkvar), p);
                   1513:        }
                   1514: checkcond = mkexpr(OPLT, t, cpexpr(dimp->nelt) );
                   1515: if( ! ISICON(p) )
                   1516:        checkcond = mkexpr(OPAND, checkcond,
                   1517:                        mkexpr(OPLE, ICON(0), cpexpr(checkvar)) );
                   1518: 
                   1519: badcall = call4(p->headblock.vtype, "s_rnge",
                   1520:                mkstrcon(VL, np->varname),
                   1521:                mkconv(TYLONG,  cpexpr(checkvar)),
                   1522:                mkstrcon(XL, procname),
                   1523:                ICON(lineno) );
                   1524: badcall->exprblock.opcode = OPCCALL;
                   1525: p = mkexpr(OPQUEST, checkcond,
                   1526:        mkexpr(OPCOLON, checkvar, badcall));
                   1527: 
                   1528: return(p);
                   1529: 
                   1530: badsub:
                   1531:        frexpr(p);
                   1532:        errstr("subscript on variable %s out of range", varstr(VL,np->varname));
                   1533:        return ( ICON(0) );
                   1534: }
                   1535: 
                   1536: 
                   1537: 
                   1538: 
                   1539: Addrp mkaddr(p)
                   1540: register Namep p;
                   1541: {
                   1542: struct Extsym *extp;
                   1543: register Addrp t;
                   1544: Addrp intraddr();
                   1545: 
                   1546: switch( p->vstg)
                   1547:        {
                   1548:        case STGUNKNOWN:
                   1549:                if(p->vclass != CLPROC)
                   1550:                        break;
                   1551:                extp = mkext( varunder(VL, p->varname) );
                   1552:                extp->extstg = STGEXT;
                   1553:                p->vstg = STGEXT;
                   1554:                p->vardesc.varno = extp - extsymtab;
                   1555:                p->vprocclass = PEXTERNAL;
                   1556: 
                   1557:        case STGCOMMON:
                   1558:        case STGEXT:
                   1559:        case STGBSS:
                   1560:        case STGINIT:
                   1561:        case STGEQUIV:
                   1562:        case STGARG:
                   1563:        case STGLENG:
                   1564:        case STGAUTO:
                   1565:                t = ALLOC(Addrblock);
                   1566:                t->tag = TADDR;
                   1567:                if(p->vclass==CLPROC && p->vprocclass==PTHISPROC)
                   1568:                        t->vclass = CLVAR;
                   1569:                else
                   1570:                        t->vclass = p->vclass;
                   1571:                t->vtype = p->vtype;
                   1572:                t->vstg = p->vstg;
                   1573:                t->memno = p->vardesc.varno;
                   1574:                t->issaved = p->vsave;
                   1575:                 if(p->vdim) t->isarray = YES;
                   1576:                t->memoffset = ICON(p->voffset);
                   1577:                if(p->vleng)
                   1578:                        {
                   1579:                        t->vleng = (expptr) cpexpr(p->vleng);
                   1580:                        if( ISICON(t->vleng) )
                   1581:                                t->varleng = t->vleng->constblock.const.ci;
                   1582:                        }
                   1583:                if (p->vstg == STGBSS)
                   1584:                        t->varsize = p->varsize;
                   1585:                else if (p->vstg == STGEQUIV)
                   1586:                        t->varsize = eqvclass[t->memno].eqvleng;
                   1587:                return(t);
                   1588: 
                   1589:        case STGINTR:
                   1590:                return( intraddr(p) );
                   1591: 
                   1592:        }
                   1593: /*debug*/fprintf(diagfile,"mkaddr. vtype=%d, vclass=%d\n", p->vtype, p->vclass);
                   1594: badstg("mkaddr", p->vstg);
                   1595: /* NOTREACHED */
                   1596: }
                   1597: 
                   1598: 
                   1599: 
                   1600: 
                   1601: Addrp mkarg(type, argno)
                   1602: int type, argno;
                   1603: {
                   1604: register Addrp p;
                   1605: 
                   1606: p = ALLOC(Addrblock);
                   1607: p->tag = TADDR;
                   1608: p->vtype = type;
                   1609: p->vclass = CLVAR;
                   1610: p->vstg = (type==TYLENG ? STGLENG : STGARG);
                   1611: p->memno = argno;
                   1612: return(p);
                   1613: }
                   1614: 
                   1615: 
                   1616: 
                   1617: 
                   1618: expptr mkprim(v, args, substr)
                   1619: register union
                   1620:        {
                   1621:        struct Paramblock paramblock;
                   1622:        struct Nameblock nameblock;
                   1623:        struct Headblock headblock;
                   1624:        } *v;
                   1625: struct Listblock *args;
                   1626: chainp substr;
                   1627: {
                   1628: register struct Primblock *p;
                   1629: 
                   1630: if(v->headblock.vclass == CLPARAM)
                   1631:        {
                   1632:        if(args || substr)
                   1633:                {
                   1634:                errstr("no qualifiers on parameter name %s",
                   1635:                        varstr(VL,v->paramblock.varname));
                   1636:                frexpr(args);
                   1637:                if(substr)
                   1638:                        {
                   1639:                        frexpr(substr->datap);
                   1640:                        frexpr(substr->nextp->datap);
                   1641:                        frchain(&substr);
                   1642:                        }
                   1643:                frexpr(v);
                   1644:                return( errnode() );
                   1645:                }
                   1646:        return( (expptr) cpexpr(v->paramblock.paramval) );
                   1647:        }
                   1648: 
                   1649: p = ALLOC(Primblock);
                   1650: p->tag = TPRIM;
                   1651: p->vtype = v->nameblock.vtype;
                   1652: p->namep = (Namep) v;
                   1653: p->argsp = args;
                   1654: if(substr)
                   1655:        {
                   1656:        p->fcharp = (expptr) substr->datap;
                   1657:        if (p->fcharp != ENULL && ! ISINT(p->fcharp->headblock.vtype))
                   1658:                p->fcharp = mkconv(TYINT, p->fcharp);
                   1659:        p->lcharp = (expptr) substr->nextp->datap;
                   1660:        if (p->lcharp != ENULL && ! ISINT(p->lcharp->headblock.vtype))
                   1661:                p->lcharp = mkconv(TYINT, p->lcharp);
                   1662:        frchain(&substr);
                   1663:        }
                   1664: return( (expptr) p);
                   1665: }
                   1666: 
                   1667: 
                   1668: 
                   1669: vardcl(v)
                   1670: register Namep v;
                   1671: {
                   1672: int nelt;
                   1673: struct Dimblock *t;
                   1674: Addrp p;
                   1675: expptr neltp;
                   1676: int eltsize;
                   1677: int varsize;
                   1678: int tsize;
                   1679: int align;
                   1680: 
                   1681: if(v->vdcldone)
                   1682:        return;
                   1683: if(v->vclass == CLNAMELIST)
                   1684:        return;
                   1685: 
                   1686: if(v->vtype == TYUNKNOWN)
                   1687:        impldcl(v);
                   1688: if(v->vclass == CLUNKNOWN)
                   1689:        v->vclass = CLVAR;
                   1690: else if(v->vclass!=CLVAR && v->vprocclass!=PTHISPROC)
                   1691:        {
                   1692:        dclerr("used both as variable and non-variable", v);
                   1693:        return;
                   1694:        }
                   1695: if(v->vstg==STGUNKNOWN)
                   1696:        v->vstg = implstg[ letter(v->varname[0]) ];
                   1697: 
                   1698: switch(v->vstg)
                   1699:        {
                   1700:        case STGBSS:
                   1701:                v->vardesc.varno = ++lastvarno;
                   1702:                if (v->vclass != CLVAR)
                   1703:                        break;
                   1704:                nelt = 1;
                   1705:                t = v->vdim;
                   1706:                if (t)
                   1707:                        {
                   1708:                        neltp = t->nelt;
                   1709:                        if (neltp && ISICON(neltp))
                   1710:                                nelt = neltp->constblock.const.ci;
                   1711:                        else
                   1712:                                dclerr("improperly dimensioned array", v);
                   1713:                        }
                   1714: 
                   1715:                if (v->vtype == TYCHAR)
                   1716:                        {
                   1717:                        v->vleng = fixtype(v->vleng);
                   1718:                        if (v->vleng == NULL)
                   1719:                                eltsize = typesize[TYCHAR];
                   1720:                        else if (ISICON(v->vleng))
                   1721:                                eltsize = typesize[TYCHAR] *
                   1722:                                        v->vleng->constblock.const.ci;
                   1723:                        else if (v->vleng->tag != TERROR)
                   1724:                                {
                   1725:                                errstr("nonconstant string length on %s",
                   1726:                                        varstr(VL, v->varname));
                   1727:                                eltsize = 0;
                   1728:                                }
                   1729:                        }
                   1730:                else
                   1731:                        eltsize = typesize[v->vtype];
                   1732: 
                   1733:                v->varsize = nelt * eltsize;
                   1734:                break;
                   1735:        case STGAUTO:
                   1736:                if(v->vclass==CLPROC && v->vprocclass==PTHISPROC)
                   1737:                        break;
                   1738:                nelt = 1;
                   1739:                if(t = v->vdim)
                   1740:                        if( (neltp = t->nelt) && ISCONST(neltp) )
                   1741:                                nelt = neltp->constblock.const.ci;
                   1742:                        else
                   1743:                                dclerr("adjustable automatic array", v);
                   1744:                p = autovar(nelt, v->vtype, v->vleng);
                   1745:                v->vardesc.varno = p->memno;
                   1746:                v->voffset = p->memoffset->constblock.const.ci;
                   1747:                frexpr(p);
                   1748:                break;
                   1749: 
                   1750:        default:
                   1751:                break;
                   1752:        }
                   1753: v->vdcldone = YES;
                   1754: }
                   1755: 
                   1756: 
                   1757: 
                   1758: 
                   1759: impldcl(p)
                   1760: register Namep p;
                   1761: {
                   1762: register int k;
                   1763: int type, leng;
                   1764: 
                   1765: if(p->vdcldone || (p->vclass==CLPROC && p->vprocclass==PINTRINSIC) )
                   1766:        return;
                   1767: if(p->vtype == TYUNKNOWN)
                   1768:        {
                   1769:        k = letter(p->varname[0]);
                   1770:        type = impltype[ k ];
                   1771:        leng = implleng[ k ];
                   1772:        if(type == TYUNKNOWN)
                   1773:                {
                   1774:                if(p->vclass == CLPROC)
                   1775:                        dclerr("attempt to use function of undefined type", p);
                   1776:                else
                   1777:                        dclerr("attempt to use undefined variable", p);
                   1778:                type = TYERROR;
                   1779:                leng = 1;
                   1780:                }
                   1781:        settype(p, type, leng);
                   1782:        }
                   1783: }
                   1784: 
                   1785: 
                   1786: 
                   1787: 
                   1788: LOCAL letter(c)
                   1789: register int c;
                   1790: {
                   1791: if( isupper(c) )
                   1792:        c = tolower(c);
                   1793: return(c - 'a');
                   1794: }
                   1795: 
                   1796: #define ICONEQ(z, c)  (ISICON(z) && z->constblock.const.ci==c)
                   1797: #define COMMUTE        { e = lp;  lp = rp;  rp = e; }
                   1798: 
                   1799: 
                   1800: expptr mkexpr(opcode, lp, rp)
                   1801: int opcode;
                   1802: register expptr lp, rp;
                   1803: {
                   1804: register expptr e, e1;
                   1805: int etype;
                   1806: int ltype, rtype;
                   1807: int ltag, rtag;
                   1808: expptr q, q1;
                   1809: expptr fold();
                   1810: int k;
                   1811: 
                   1812: ltype = lp->headblock.vtype;
                   1813: ltag = lp->tag;
                   1814: if(rp && opcode!=OPCALL && opcode!=OPCCALL)
                   1815:        {
                   1816:        rtype = rp->headblock.vtype;
                   1817:        rtag = rp->tag;
                   1818:        }
                   1819: else   {
                   1820:        rtype = 0;
                   1821:        rtag = 0;
                   1822:        }
                   1823: 
                   1824: /*
                   1825:  * Yuck.  Why can't we fold constants AFTER
                   1826:  * variables are implicitly declared???
                   1827:  */
                   1828: if(ltype == TYUNKNOWN && ltag == TPRIM && lp->primblock.argsp == NULL)
                   1829:        {
                   1830:        k = letter(lp->primblock.namep->varname[0]);
                   1831:        ltype = impltype[ k ];
                   1832:        }
                   1833: if(rtype == TYUNKNOWN && rtag == TPRIM && rp->primblock.argsp == NULL)
                   1834:        {
                   1835:        k = letter(rp->primblock.namep->varname[0]);
                   1836:        rtype = impltype[ k ];
                   1837:        }
                   1838: 
                   1839: etype = cktype(opcode, ltype, rtype);
                   1840: if(etype == TYERROR)
                   1841:        goto error;
                   1842: 
                   1843: if(etype != TYUNKNOWN)
                   1844: switch(opcode)
                   1845:        {
                   1846:        /* check for multiplication by 0 and 1 and addition to 0 */
                   1847: 
                   1848:        case OPSTAR:
                   1849:                if( ISCONST(lp) )
                   1850:                        COMMUTE
                   1851: 
                   1852:                if( ISICON(rp) )
                   1853:                        {
                   1854:                        if(rp->constblock.const.ci == 0)
                   1855:                                {
                   1856:                                if(etype == TYUNKNOWN)
                   1857:                                        break;
                   1858:                                rp = mkconv(etype, rp);
                   1859:                                goto retright;
                   1860:                                }
                   1861:                        if ((lp->tag == TEXPR) &&
                   1862:                            ((lp->exprblock.opcode == OPPLUS) ||
                   1863:                             (lp->exprblock.opcode == OPMINUS)) &&
                   1864:                            ISCONST(lp->exprblock.rightp) &&
                   1865:                            ISINT(lp->exprblock.rightp->constblock.vtype))
                   1866:                                {
                   1867:                                q1 = mkexpr(OPSTAR, lp->exprblock.rightp,
                   1868:                                           cpexpr(rp));
                   1869:                                q = mkexpr(OPSTAR, lp->exprblock.leftp, rp);
                   1870:                                q = mkexpr(lp->exprblock.opcode, q, q1);
                   1871:                                free ((char *) lp);
                   1872:                                return q;
                   1873:                                }
                   1874:                        else
                   1875:                                goto mulop;
                   1876:                        }
                   1877:                break;
                   1878: 
                   1879:        case OPSLASH:
                   1880:        case OPMOD:
                   1881:                if( ICONEQ(rp, 0) )
                   1882:                        {
                   1883:                        err("attempted division by zero");
                   1884:                        rp = ICON(1);
                   1885:                        break;
                   1886:                        }
                   1887:                if(opcode == OPMOD)
                   1888:                        break;
                   1889: 
                   1890: 
                   1891:        mulop:
                   1892:                if( ISICON(rp) )
                   1893:                        {
                   1894:                        if(rp->constblock.const.ci == 1)
                   1895:                                goto retleft;
                   1896: 
                   1897:                        if(rp->constblock.const.ci == -1)
                   1898:                                {
                   1899:                                frexpr(rp);
                   1900:                                return( mkexpr(OPNEG, lp, PNULL) );
                   1901:                                }
                   1902:                        }
                   1903: 
                   1904:                if( ISSTAROP(lp) && ISICON(lp->exprblock.rightp) )
                   1905:                        {
                   1906:                        if(opcode == OPSTAR)
                   1907:                                e = mkexpr(OPSTAR, lp->exprblock.rightp, rp);
                   1908:                        else  if(ISICON(rp) &&
                   1909:                                (lp->exprblock.rightp->constblock.const.ci %
                   1910:                                        rp->constblock.const.ci) == 0)
                   1911:                                e = mkexpr(OPSLASH, lp->exprblock.rightp, rp);
                   1912:                        else    break;
                   1913: 
                   1914:                        e1 = lp->exprblock.leftp;
                   1915:                        free( (charptr) lp );
                   1916:                        return( mkexpr(OPSTAR, e1, e) );
                   1917:                        }
                   1918:                break;
                   1919: 
                   1920: 
                   1921:        case OPPLUS:
                   1922:                if( ISCONST(lp) )
                   1923:                        COMMUTE
                   1924:                goto addop;
                   1925: 
                   1926:        case OPMINUS:
                   1927:                if( ICONEQ(lp, 0) )
                   1928:                        {
                   1929:                        frexpr(lp);
                   1930:                        return( mkexpr(OPNEG, rp, ENULL) );
                   1931:                        }
                   1932: 
                   1933:                if( ISCONST(rp) )
                   1934:                        {
                   1935:                        opcode = OPPLUS;
                   1936:                        consnegop(rp);
                   1937:                        }
                   1938: 
                   1939:        addop:
                   1940:                if( ISICON(rp) )
                   1941:                        {
                   1942:                        if(rp->constblock.const.ci == 0)
                   1943:                                goto retleft;
                   1944:                        if( ISPLUSOP(lp) && ISICON(lp->exprblock.rightp) )
                   1945:                                {
                   1946:                                e = mkexpr(OPPLUS, lp->exprblock.rightp, rp);
                   1947:                                e1 = lp->exprblock.leftp;
                   1948:                                free( (charptr) lp );
                   1949:                                return( mkexpr(OPPLUS, e1, e) );
                   1950:                                }
                   1951:                        }
                   1952:                break;
                   1953: 
                   1954: 
                   1955:        case OPPOWER:
                   1956:                break;
                   1957: 
                   1958:        case OPNEG:
                   1959:                if(ltag==TEXPR && lp->exprblock.opcode==OPNEG)
                   1960:                        {
                   1961:                        e = lp->exprblock.leftp;
                   1962:                        free( (charptr) lp );
                   1963:                        return(e);
                   1964:                        }
                   1965:                break;
                   1966: 
                   1967:        case OPNOT:
                   1968:                if(ltag==TEXPR && lp->exprblock.opcode==OPNOT)
                   1969:                        {
                   1970:                        e = lp->exprblock.leftp;
                   1971:                        free( (charptr) lp );
                   1972:                        return(e);
                   1973:                        }
                   1974:                break;
                   1975: 
                   1976:        case OPCALL:
                   1977:        case OPCCALL:
                   1978:                etype = ltype;
                   1979:                if(rp!=NULL && rp->listblock.listp==NULL)
                   1980:                        {
                   1981:                        free( (charptr) rp );
                   1982:                        rp = NULL;
                   1983:                        }
                   1984:                break;
                   1985: 
                   1986:        case OPAND:
                   1987:        case OPOR:
                   1988:                if( ISCONST(lp) )
                   1989:                        COMMUTE
                   1990: 
                   1991:                if( ISCONST(rp) )
                   1992:                        {
                   1993:                        if(rp->constblock.const.ci == 0)
                   1994:                                if(opcode == OPOR)
                   1995:                                        goto retleft;
                   1996:                                else
                   1997:                                        goto retright;
                   1998:                        else if(opcode == OPOR)
                   1999:                                goto retright;
                   2000:                        else
                   2001:                                goto retleft;
                   2002:                        }
                   2003:        case OPLSHIFT:
                   2004:                if (ISICON(rp))
                   2005:                        {
                   2006:                        if (rp->constblock.const.ci == 0)
                   2007:                                goto retleft;
                   2008:                        if ((lp->tag == TEXPR) &&
                   2009:                            ((lp->exprblock.opcode == OPPLUS) ||
                   2010:                             (lp->exprblock.opcode == OPMINUS)) &&
                   2011:                            ISICON(lp->exprblock.rightp))
                   2012:                                {
                   2013:                                q1 = mkexpr(OPLSHIFT, lp->exprblock.rightp,
                   2014:                                        cpexpr(rp));
                   2015:                                q = mkexpr(OPLSHIFT, lp->exprblock.leftp, rp);
                   2016:                                q = mkexpr(lp->exprblock.opcode, q, q1);
                   2017:                                free((char *) lp);
                   2018:                                return q;
                   2019:                                }
                   2020:                        }
                   2021: 
                   2022:        case OPEQV:
                   2023:        case OPNEQV:
                   2024: 
                   2025:        case OPBITAND:
                   2026:        case OPBITOR:
                   2027:        case OPBITXOR:
                   2028:        case OPBITNOT:
                   2029:        case OPRSHIFT:
                   2030: 
                   2031:        case OPLT:
                   2032:        case OPGT:
                   2033:        case OPLE:
                   2034:        case OPGE:
                   2035:        case OPEQ:
                   2036:        case OPNE:
                   2037: 
                   2038:        case OPCONCAT:
                   2039:                break;
                   2040:        case OPMIN:
                   2041:        case OPMAX:
                   2042: 
                   2043:        case OPASSIGN:
                   2044:        case OPPLUSEQ:
                   2045:        case OPSTAREQ:
                   2046: 
                   2047:        case OPCONV:
                   2048:        case OPADDR:
                   2049: 
                   2050:        case OPCOMMA:
                   2051:        case OPQUEST:
                   2052:        case OPCOLON:
                   2053: 
                   2054:        case OPPAREN:
                   2055:                break;
                   2056: 
                   2057:        default:
                   2058:                badop("mkexpr", opcode);
                   2059:        }
                   2060: 
                   2061: e = (expptr) ALLOC(Exprblock);
                   2062: e->exprblock.tag = TEXPR;
                   2063: e->exprblock.opcode = opcode;
                   2064: e->exprblock.vtype = etype;
                   2065: e->exprblock.leftp = lp;
                   2066: e->exprblock.rightp = rp;
                   2067: if(ltag==TCONST && (rp==0 || rtag==TCONST) )
                   2068:        e = fold(e);
                   2069: return(e);
                   2070: 
                   2071: retleft:
                   2072:        frexpr(rp);
                   2073:        return(lp);
                   2074: 
                   2075: retright:
                   2076:        frexpr(lp);
                   2077:        return(rp);
                   2078: 
                   2079: error:
                   2080:        frexpr(lp);
                   2081:        if(rp && opcode!=OPCALL && opcode!=OPCCALL)
                   2082:                frexpr(rp);
                   2083:        return( errnode() );
                   2084: }
                   2085: 
                   2086: #define ERR(s)   { errs = s; goto error; }
                   2087: 
                   2088: cktype(op, lt, rt)
                   2089: register int op, lt, rt;
                   2090: {
                   2091: char *errs;
                   2092: 
                   2093: if(lt==TYERROR || rt==TYERROR)
                   2094:        goto error1;
                   2095: 
                   2096: if(lt==TYUNKNOWN)
                   2097:        return(TYUNKNOWN);
                   2098: if(rt==TYUNKNOWN)
                   2099:        if (op!=OPNOT && op!=OPBITNOT && op!=OPNEG && op!=OPCALL &&
                   2100:            op!=OPCCALL && op!=OPADDR && op!=OPPAREN)
                   2101:                return(TYUNKNOWN);
                   2102: 
                   2103: switch(op)
                   2104:        {
                   2105:        case OPPLUS:
                   2106:        case OPMINUS:
                   2107:        case OPSTAR:
                   2108:        case OPSLASH:
                   2109:        case OPPOWER:
                   2110:        case OPMOD:
                   2111:                if( ISNUMERIC(lt) && ISNUMERIC(rt) )
                   2112:                        return( maxtype(lt, rt) );
                   2113:                ERR("nonarithmetic operand of arithmetic operator")
                   2114: 
                   2115:        case OPNEG:
                   2116:                if( ISNUMERIC(lt) )
                   2117:                        return(lt);
                   2118:                ERR("nonarithmetic operand of negation")
                   2119: 
                   2120:        case OPNOT:
                   2121:                if(lt == TYLOGICAL)
                   2122:                        return(TYLOGICAL);
                   2123:                ERR("NOT of nonlogical")
                   2124: 
                   2125:        case OPAND:
                   2126:        case OPOR:
                   2127:        case OPEQV:
                   2128:        case OPNEQV:
                   2129:                if(lt==TYLOGICAL && rt==TYLOGICAL)
                   2130:                        return(TYLOGICAL);
                   2131:                ERR("nonlogical operand of logical operator")
                   2132: 
                   2133:        case OPLT:
                   2134:        case OPGT:
                   2135:        case OPLE:
                   2136:        case OPGE:
                   2137:        case OPEQ:
                   2138:        case OPNE:
                   2139:                if(lt==TYCHAR || rt==TYCHAR || lt==TYLOGICAL || rt==TYLOGICAL)
                   2140:                        {
                   2141:                        if(lt != rt)
                   2142:                                ERR("illegal comparison")
                   2143:                        }
                   2144: 
                   2145:                else if( ISCOMPLEX(lt) || ISCOMPLEX(rt) )
                   2146:                        {
                   2147:                        if(op!=OPEQ && op!=OPNE)
                   2148:                                ERR("order comparison of complex data")
                   2149:                        }
                   2150: 
                   2151:                else if( ! ISNUMERIC(lt) || ! ISNUMERIC(rt) )
                   2152:                        ERR("comparison of nonarithmetic data")
                   2153:                return(TYLOGICAL);
                   2154: 
                   2155:        case OPCONCAT:
                   2156:                if(lt==TYCHAR && rt==TYCHAR)
                   2157:                        return(TYCHAR);
                   2158:                ERR("concatenation of nonchar data")
                   2159: 
                   2160:        case OPCALL:
                   2161:        case OPCCALL:
                   2162:                return(lt);
                   2163: 
                   2164:        case OPADDR:
                   2165:                return(TYADDR);
                   2166: 
                   2167:        case OPCONV:
                   2168:                if(ISCOMPLEX(lt))
                   2169:                        {
                   2170:                        if(ISNUMERIC(rt))
                   2171:                                return(lt);
                   2172:                        ERR("impossible conversion")
                   2173:                        }
                   2174:                if(rt == 0)
                   2175:                        return(0);
                   2176:                if(lt==TYCHAR && ISINT(rt) )
                   2177:                        return(TYCHAR);
                   2178:        case OPASSIGN:
                   2179:        case OPPLUSEQ:
                   2180:        case OPSTAREQ:
                   2181:                if( ISINT(lt) && rt==TYCHAR)
                   2182:                        return(lt);
                   2183:                if(lt==TYCHAR || rt==TYCHAR || lt==TYLOGICAL || rt==TYLOGICAL)
                   2184:                        if(op!=OPASSIGN || lt!=rt)
                   2185:                                {
                   2186: /* debug fprintf(diagfile, " lt=%d, rt=%d, op=%d\n", lt, rt, op); */
                   2187: /* debug fatal("impossible conversion.  possible compiler bug"); */
                   2188:                                ERR("impossible conversion")
                   2189:                                }
                   2190:                return(lt);
                   2191: 
                   2192:        case OPMIN:
                   2193:        case OPMAX:
                   2194:        case OPBITOR:
                   2195:        case OPBITAND:
                   2196:        case OPBITXOR:
                   2197:        case OPBITNOT:
                   2198:        case OPLSHIFT:
                   2199:        case OPRSHIFT:
                   2200:        case OPPAREN:
                   2201:                return(lt);
                   2202: 
                   2203:        case OPCOMMA:
                   2204:        case OPQUEST:
                   2205:        case OPCOLON:
                   2206:                return(rt);
                   2207: 
                   2208:        default:
                   2209:                badop("cktype", op);
                   2210:        }
                   2211: error: err(errs);
                   2212: error1:        return(TYERROR);
                   2213: }
                   2214: 
                   2215: LOCAL expptr fold(e)
                   2216: register expptr e;
                   2217: {
                   2218: Constp p;
                   2219: register expptr lp, rp;
                   2220: int etype, mtype, ltype, rtype, opcode;
                   2221: int i, ll, lr;
                   2222: char *q, *s;
                   2223: union Constant lcon, rcon;
                   2224: 
                   2225: opcode = e->exprblock.opcode;
                   2226: etype = e->exprblock.vtype;
                   2227: 
                   2228: lp = e->exprblock.leftp;
                   2229: ltype = lp->headblock.vtype;
                   2230: rp = e->exprblock.rightp;
                   2231: 
                   2232: if(rp == 0)
                   2233:        switch(opcode)
                   2234:                {
                   2235:                case OPNOT:
                   2236:                        lp->constblock.const.ci = ! lp->constblock.const.ci;
                   2237:                        return(lp);
                   2238: 
                   2239:                case OPBITNOT:
                   2240:                        lp->constblock.const.ci = ~ lp->constblock.const.ci;
                   2241:                        return(lp);
                   2242: 
                   2243:                case OPNEG:
                   2244:                        consnegop(lp);
                   2245:                        return(lp);
                   2246: 
                   2247:                case OPCONV:
                   2248:                case OPADDR:
                   2249:                case OPPAREN:
                   2250:                        return(e);
                   2251: 
                   2252:                default:
                   2253:                        badop("fold", opcode);
                   2254:                }
                   2255: 
                   2256: rtype = rp->headblock.vtype;
                   2257: 
                   2258: p = ALLOC(Constblock);
                   2259: p->tag = TCONST;
                   2260: p->vtype = etype;
                   2261: p->vleng = e->exprblock.vleng;
                   2262: 
                   2263: switch(opcode)
                   2264:        {
                   2265:        case OPCOMMA:
                   2266:        case OPQUEST:
                   2267:        case OPCOLON:
                   2268:                return(e);
                   2269: 
                   2270:        case OPAND:
                   2271:                p->const.ci = lp->constblock.const.ci &&
                   2272:                                rp->constblock.const.ci;
                   2273:                break;
                   2274: 
                   2275:        case OPOR:
                   2276:                p->const.ci = lp->constblock.const.ci ||
                   2277:                                rp->constblock.const.ci;
                   2278:                break;
                   2279: 
                   2280:        case OPEQV:
                   2281:                p->const.ci = lp->constblock.const.ci ==
                   2282:                                rp->constblock.const.ci;
                   2283:                break;
                   2284: 
                   2285:        case OPNEQV:
                   2286:                p->const.ci = lp->constblock.const.ci !=
                   2287:                                rp->constblock.const.ci;
                   2288:                break;
                   2289: 
                   2290:        case OPBITAND:
                   2291:                p->const.ci = lp->constblock.const.ci &
                   2292:                                rp->constblock.const.ci;
                   2293:                break;
                   2294: 
                   2295:        case OPBITOR:
                   2296:                p->const.ci = lp->constblock.const.ci |
                   2297:                                rp->constblock.const.ci;
                   2298:                break;
                   2299: 
                   2300:        case OPBITXOR:
                   2301:                p->const.ci = lp->constblock.const.ci ^
                   2302:                                rp->constblock.const.ci;
                   2303:                break;
                   2304: 
                   2305:        case OPLSHIFT:
                   2306:                p->const.ci = lp->constblock.const.ci <<
                   2307:                                rp->constblock.const.ci;
                   2308:                break;
                   2309: 
                   2310:        case OPRSHIFT:
                   2311:                p->const.ci = lp->constblock.const.ci >>
                   2312:                                rp->constblock.const.ci;
                   2313:                break;
                   2314: 
                   2315:        case OPCONCAT:
                   2316:                ll = lp->constblock.vleng->constblock.const.ci;
                   2317:                lr = rp->constblock.vleng->constblock.const.ci;
                   2318:                p->const.ccp = q = (char *) ckalloc(ll+lr);
                   2319:                p->vleng = ICON(ll+lr);
                   2320:                s = lp->constblock.const.ccp;
                   2321:                for(i = 0 ; i < ll ; ++i)
                   2322:                        *q++ = *s++;
                   2323:                s = rp->constblock.const.ccp;
                   2324:                for(i = 0; i < lr; ++i)
                   2325:                        *q++ = *s++;
                   2326:                break;
                   2327: 
                   2328: 
                   2329:        case OPPOWER:
                   2330:                if( ! ISINT(rtype) )
                   2331:                        return(e);
                   2332:                conspower(&(p->const), lp, rp->constblock.const.ci);
                   2333:                break;
                   2334: 
                   2335: 
                   2336:        default:
                   2337:                if(ltype == TYCHAR)
                   2338:                        {
                   2339:                        lcon.ci = cmpstr(lp->constblock.const.ccp,
                   2340:                                        rp->constblock.const.ccp,
                   2341:                                        lp->constblock.vleng->constblock.const.ci,
                   2342:                                        rp->constblock.vleng->constblock.const.ci);
                   2343:                        rcon.ci = 0;
                   2344:                        mtype = tyint;
                   2345:                        }
                   2346:                else    {
                   2347:                        mtype = maxtype(ltype, rtype);
                   2348:                        consconv(mtype, &lcon, ltype, &(lp->constblock.const) );
                   2349:                        consconv(mtype, &rcon, rtype, &(rp->constblock.const) );
                   2350:                        }
                   2351:                consbinop(opcode, mtype, &(p->const), &lcon, &rcon);
                   2352:                break;
                   2353:        }
                   2354: 
                   2355: frexpr(e);
                   2356: return( (expptr) p );
                   2357: }
                   2358: 
                   2359: 
                   2360: 
                   2361: /* assign constant l = r , doing coercion */
                   2362: 
                   2363: consconv(lt, lv, rt, rv)
                   2364: int lt, rt;
                   2365: register union Constant *lv, *rv;
                   2366: {
                   2367: switch(lt)
                   2368:        {
                   2369:        case TYCHAR:
                   2370:                *(lv->ccp = (char *) ckalloc(1)) = rv->ci;
                   2371:                break;
                   2372: 
                   2373:        case TYSHORT:
                   2374:        case TYLONG:
                   2375:                if(rt == TYCHAR)
                   2376:                        lv->ci = rv->ccp[0];
                   2377:                else if( ISINT(rt) )
                   2378:                        lv->ci = rv->ci;
                   2379:                else    lv->ci = rv->cd[0];
                   2380:                break;
                   2381: 
                   2382:        case TYCOMPLEX:
                   2383:        case TYDCOMPLEX:
                   2384:                switch(rt)
                   2385:                        {
                   2386:                        case TYSHORT:
                   2387:                        case TYLONG:
                   2388:                                /* fall through and do real assignment of
                   2389:                                   first element
                   2390:                                */
                   2391:                        case TYREAL:
                   2392:                        case TYDREAL:
                   2393:                                lv->cd[1] = 0; break;
                   2394:                        case TYCOMPLEX:
                   2395:                        case TYDCOMPLEX:
                   2396:                                lv->cd[1] = rv->cd[1]; break;
                   2397:                        }
                   2398: 
                   2399:        case TYREAL:
                   2400:        case TYDREAL:
                   2401:                if( ISINT(rt) )
                   2402:                        lv->cd[0] = rv->ci;
                   2403:                else    lv->cd[0] = rv->cd[0];
                   2404:                if( lt == TYREAL)
                   2405:                        {
                   2406:                        float f = lv->cd[0];
                   2407:                        lv->cd[0] = f;
                   2408:                        }
                   2409:                break;
                   2410: 
                   2411:        case TYLOGICAL:
                   2412:                lv->ci = rv->ci;
                   2413:                break;
                   2414:        }
                   2415: }
                   2416: 
                   2417: 
                   2418: 
                   2419: consnegop(p)
                   2420: register Constp p;
                   2421: {
                   2422: switch(p->vtype)
                   2423:        {
                   2424:        case TYSHORT:
                   2425:        case TYLONG:
                   2426:                p->const.ci = - p->const.ci;
                   2427:                break;
                   2428: 
                   2429:        case TYCOMPLEX:
                   2430:        case TYDCOMPLEX:
                   2431:                p->const.cd[1] = - p->const.cd[1];
                   2432:                /* fall through and do the real parts */
                   2433:        case TYREAL:
                   2434:        case TYDREAL:
                   2435:                p->const.cd[0] = - p->const.cd[0];
                   2436:                break;
                   2437:        default:
                   2438:                badtype("consnegop", p->vtype);
                   2439:        }
                   2440: }
                   2441: 
                   2442: 
                   2443: 
                   2444: LOCAL conspower(powp, ap, n)
                   2445: register union Constant *powp;
                   2446: Constp ap;
                   2447: ftnint n;
                   2448: {
                   2449: register int type;
                   2450: union Constant x;
                   2451: 
                   2452: switch(type = ap->vtype)       /* pow = 1 */ 
                   2453:        {
                   2454:        case TYSHORT:
                   2455:        case TYLONG:
                   2456:                powp->ci = 1;
                   2457:                break;
                   2458:        case TYCOMPLEX:
                   2459:        case TYDCOMPLEX:
                   2460:                powp->cd[1] = 0;
                   2461:        case TYREAL:
                   2462:        case TYDREAL:
                   2463:                powp->cd[0] = 1;
                   2464:                break;
                   2465:        default:
                   2466:                badtype("conspower", type);
                   2467:        }
                   2468: 
                   2469: if(n == 0)
                   2470:        return;
                   2471: if(n < 0)
                   2472:        {
                   2473:        if( ISINT(type) )
                   2474:                {
                   2475:                if (ap->const.ci == 0)
                   2476:                        err("zero raised to a negative power");
                   2477:                else if (ap->const.ci == 1)
                   2478:                        return;
                   2479:                else if (ap->const.ci == -1)
                   2480:                        {
                   2481:                        if (n < -2)
                   2482:                                n = n + 2;
                   2483:                        n = -n;
                   2484:                        if (n % 2 == 1)
                   2485:                                powp->ci = -1;
                   2486:                        }
                   2487:                else
                   2488:                        powp->ci = 0;
                   2489:                return;
                   2490:                }
                   2491:        n = - n;
                   2492:        consbinop(OPSLASH, type, &x, powp, &(ap->const));
                   2493:        }
                   2494: else
                   2495:        consbinop(OPSTAR, type, &x, powp, &(ap->const));
                   2496: 
                   2497: for( ; ; )
                   2498:        {
                   2499:        if(n & 01)
                   2500:                consbinop(OPSTAR, type, powp, powp, &x);
                   2501:        if(n >>= 1)
                   2502:                consbinop(OPSTAR, type, &x, &x, &x);
                   2503:        else
                   2504:                break;
                   2505:        }
                   2506: }
                   2507: 
                   2508: 
                   2509: 
                   2510: /* do constant operation cp = a op b */
                   2511: 
                   2512: 
                   2513: LOCAL consbinop(opcode, type, cp, ap, bp)
                   2514: int opcode, type;
                   2515: register union Constant *ap, *bp, *cp;
                   2516: {
                   2517: int k;
                   2518: double temp;
                   2519: 
                   2520: switch(opcode)
                   2521:        {
                   2522:        case OPPLUS:
                   2523:                switch(type)
                   2524:                        {
                   2525:                        case TYSHORT:
                   2526:                        case TYLONG:
                   2527:                                cp->ci = ap->ci + bp->ci;
                   2528:                                break;
                   2529:                        case TYCOMPLEX:
                   2530:                        case TYDCOMPLEX:
                   2531:                                cp->cd[1] = ap->cd[1] + bp->cd[1];
                   2532:                        case TYREAL:
                   2533:                        case TYDREAL:
                   2534:                                cp->cd[0] = ap->cd[0] + bp->cd[0];
                   2535:                                break;
                   2536:                        }
                   2537:                break;
                   2538: 
                   2539:        case OPMINUS:
                   2540:                switch(type)
                   2541:                        {
                   2542:                        case TYSHORT:
                   2543:                        case TYLONG:
                   2544:                                cp->ci = ap->ci - bp->ci;
                   2545:                                break;
                   2546:                        case TYCOMPLEX:
                   2547:                        case TYDCOMPLEX:
                   2548:                                cp->cd[1] = ap->cd[1] - bp->cd[1];
                   2549:                        case TYREAL:
                   2550:                        case TYDREAL:
                   2551:                                cp->cd[0] = ap->cd[0] - bp->cd[0];
                   2552:                                break;
                   2553:                        }
                   2554:                break;
                   2555: 
                   2556:        case OPSTAR:
                   2557:                switch(type)
                   2558:                        {
                   2559:                        case TYSHORT:
                   2560:                        case TYLONG:
                   2561:                                cp->ci = ap->ci * bp->ci;
                   2562:                                break;
                   2563:                        case TYREAL:
                   2564:                        case TYDREAL:
                   2565:                                cp->cd[0] = ap->cd[0] * bp->cd[0];
                   2566:                                break;
                   2567:                        case TYCOMPLEX:
                   2568:                        case TYDCOMPLEX:
                   2569:                                temp = ap->cd[0] * bp->cd[0] -
                   2570:                                            ap->cd[1] * bp->cd[1] ;
                   2571:                                cp->cd[1] = ap->cd[0] * bp->cd[1] +
                   2572:                                            ap->cd[1] * bp->cd[0] ;
                   2573:                                cp->cd[0] = temp;
                   2574:                                break;
                   2575:                        }
                   2576:                break;
                   2577:        case OPSLASH:
                   2578:                switch(type)
                   2579:                        {
                   2580:                        case TYSHORT:
                   2581:                        case TYLONG:
                   2582:                                cp->ci = ap->ci / bp->ci;
                   2583:                                break;
                   2584:                        case TYREAL:
                   2585:                        case TYDREAL:
                   2586:                                cp->cd[0] = ap->cd[0] / bp->cd[0];
                   2587:                                break;
                   2588:                        case TYCOMPLEX:
                   2589:                        case TYDCOMPLEX:
                   2590:                                zdiv(cp,ap,bp);
                   2591:                                break;
                   2592:                        }
                   2593:                break;
                   2594: 
                   2595:        case OPMOD:
                   2596:                if( ISINT(type) )
                   2597:                        {
                   2598:                        cp->ci = ap->ci % bp->ci;
                   2599:                        break;
                   2600:                        }
                   2601:                else
                   2602:                        fatal("inline mod of noninteger");
                   2603: 
                   2604:        default:          /* relational ops */
                   2605:                switch(type)
                   2606:                        {
                   2607:                        case TYSHORT:
                   2608:                        case TYLONG:
                   2609:                                if(ap->ci < bp->ci)
                   2610:                                        k = -1;
                   2611:                                else if(ap->ci == bp->ci)
                   2612:                                        k = 0;
                   2613:                                else    k = 1;
                   2614:                                break;
                   2615:                        case TYREAL:
                   2616:                        case TYDREAL:
                   2617:                                if(ap->cd[0] < bp->cd[0])
                   2618:                                        k = -1;
                   2619:                                else if(ap->cd[0] == bp->cd[0])
                   2620:                                        k = 0;
                   2621:                                else    k = 1;
                   2622:                                break;
                   2623:                        case TYCOMPLEX:
                   2624:                        case TYDCOMPLEX:
                   2625:                                if(ap->cd[0] == bp->cd[0] &&
                   2626:                                   ap->cd[1] == bp->cd[1] )
                   2627:                                        k = 0;
                   2628:                                else    k = 1;
                   2629:                                break;
                   2630:                        }
                   2631: 
                   2632:                switch(opcode)
                   2633:                        {
                   2634:                        case OPEQ:
                   2635:                                cp->ci = (k == 0);
                   2636:                                break;
                   2637:                        case OPNE:
                   2638:                                cp->ci = (k != 0);
                   2639:                                break;
                   2640:                        case OPGT:
                   2641:                                cp->ci = (k == 1);
                   2642:                                break;
                   2643:                        case OPLT:
                   2644:                                cp->ci = (k == -1);
                   2645:                                break;
                   2646:                        case OPGE:
                   2647:                                cp->ci = (k >= 0);
                   2648:                                break;
                   2649:                        case OPLE:
                   2650:                                cp->ci = (k <= 0);
                   2651:                                break;
                   2652:                        default:
                   2653:                                badop ("consbinop", opcode);
                   2654:                        }
                   2655:                break;
                   2656:        }
                   2657: }
                   2658: 
                   2659: 
                   2660: 
                   2661: 
                   2662: conssgn(p)
                   2663: register expptr p;
                   2664: {
                   2665: if( ! ISCONST(p) )
                   2666:        fatal( "sgn(nonconstant)" );
                   2667: 
                   2668: switch(p->headblock.vtype)
                   2669:        {
                   2670:        case TYSHORT:
                   2671:        case TYLONG:
                   2672:                if(p->constblock.const.ci > 0) return(1);
                   2673:                if(p->constblock.const.ci < 0) return(-1);
                   2674:                return(0);
                   2675: 
                   2676:        case TYREAL:
                   2677:        case TYDREAL:
                   2678:                if(p->constblock.const.cd[0] > 0) return(1);
                   2679:                if(p->constblock.const.cd[0] < 0) return(-1);
                   2680:                return(0);
                   2681: 
                   2682:        case TYCOMPLEX:
                   2683:        case TYDCOMPLEX:
                   2684:                return(p->constblock.const.cd[0]!=0 || p->constblock.const.cd[1]!=0);
                   2685: 
                   2686:        default:
                   2687:                badtype( "conssgn", p->constblock.vtype);
                   2688:        }
                   2689: /* NOTREACHED */
                   2690: }
                   2691: 
                   2692: char *powint[ ] = { "pow_ii", "pow_ri", "pow_di", "pow_ci", "pow_zi" };
                   2693: 
                   2694: 
                   2695: LOCAL expptr mkpower(p)
                   2696: register expptr p;
                   2697: {
                   2698: register expptr q, lp, rp;
                   2699: int ltype, rtype, mtype;
                   2700: 
                   2701: lp = p->exprblock.leftp;
                   2702: rp = p->exprblock.rightp;
                   2703: ltype = lp->headblock.vtype;
                   2704: rtype = rp->headblock.vtype;
                   2705: 
                   2706: if(ISICON(rp))
                   2707:        {
                   2708:        if(rp->constblock.const.ci == 0)
                   2709:                {
                   2710:                frexpr(p);
                   2711:                if( ISINT(ltype) )
                   2712:                        return( ICON(1) );
                   2713:                else
                   2714:                        {
                   2715:                        expptr pp;
                   2716:                        pp = mkconv(ltype, ICON(1));
                   2717:                        return( pp );
                   2718:                        }
                   2719:                }
                   2720:        if(rp->constblock.const.ci < 0)
                   2721:                {
                   2722:                if( ISINT(ltype) )
                   2723:                        {
                   2724:                        frexpr(p);
                   2725:                        err("integer**negative");
                   2726:                        return( errnode() );
                   2727:                        }
                   2728:                rp->constblock.const.ci = - rp->constblock.const.ci;
                   2729:                p->exprblock.leftp = lp = fixexpr(mkexpr(OPSLASH, ICON(1), lp));
                   2730:                }
                   2731:        if(rp->constblock.const.ci == 1)
                   2732:                {
                   2733:                frexpr(rp);
                   2734:                free( (charptr) p );
                   2735:                return(lp);
                   2736:                }
                   2737: 
                   2738:        if( ONEOF(ltype, MSKINT|MSKREAL) )
                   2739:                {
                   2740:                p->exprblock.vtype = ltype;
                   2741:                return(p);
                   2742:                }
                   2743:        }
                   2744: if( ISINT(rtype) )
                   2745:        {
                   2746:        if(ltype==TYSHORT && rtype==TYSHORT && (!ISCONST(lp) || tyint==TYSHORT) )
                   2747:                q = call2(TYSHORT, "pow_hh", lp, rp);
                   2748:        else    {
                   2749:                if(ltype == TYSHORT)
                   2750:                        {
                   2751:                        ltype = TYLONG;
                   2752:                        lp = mkconv(TYLONG,lp);
                   2753:                        }
                   2754:                q = call2(ltype, powint[ltype-TYLONG], lp, mkconv(TYLONG, rp));
                   2755:                }
                   2756:        }
                   2757: else if( ISREAL( (mtype = maxtype(ltype,rtype)) ))
                   2758:        q = call2(mtype, "pow_dd", mkconv(TYDREAL,lp), mkconv(TYDREAL,rp));
                   2759: else   {
                   2760:        q  = call2(TYDCOMPLEX, "pow_zz",
                   2761:                mkconv(TYDCOMPLEX,lp), mkconv(TYDCOMPLEX,rp));
                   2762:        if(mtype == TYCOMPLEX)
                   2763:                q = mkconv(TYCOMPLEX, q);
                   2764:        }
                   2765: free( (charptr) p );
                   2766: return(q);
                   2767: }
                   2768: 
                   2769: 
                   2770: 
                   2771: /* Complex Division.  Same code as in Runtime Library
                   2772: */
                   2773: 
                   2774: struct dcomplex { double dreal, dimag; };
                   2775: 
                   2776: 
                   2777: LOCAL zdiv(c, a, b)
                   2778: register struct dcomplex *a, *b, *c;
                   2779: {
                   2780: double ratio, den;
                   2781: double abr, abi;
                   2782: 
                   2783: if( (abr = b->dreal) < 0.)
                   2784:        abr = - abr;
                   2785: if( (abi = b->dimag) < 0.)
                   2786:        abi = - abi;
                   2787: if( abr <= abi )
                   2788:        {
                   2789:        if(abi == 0)
                   2790:                fatal("complex division by zero");
                   2791:        ratio = b->dreal / b->dimag ;
                   2792:        den = b->dimag * (1 + ratio*ratio);
                   2793:        c->dreal = (a->dreal*ratio + a->dimag) / den;
                   2794:        c->dimag = (a->dimag*ratio - a->dreal) / den;
                   2795:        }
                   2796: 
                   2797: else
                   2798:        {
                   2799:        ratio = b->dimag / b->dreal ;
                   2800:        den = b->dreal * (1 + ratio*ratio);
                   2801:        c->dreal = (a->dreal + a->dimag*ratio) / den;
                   2802:        c->dimag = (a->dimag - a->dreal*ratio) / den;
                   2803:        }
                   2804: 
                   2805: }
                   2806: 
                   2807: expptr oftwo(e)
                   2808: expptr e;
                   2809: {
                   2810:        int val,res;
                   2811: 
                   2812:        if (! ISCONST (e))
                   2813:                return (0);
                   2814: 
                   2815:        val = e->constblock.const.ci;
                   2816:        switch (val)
                   2817:                {
                   2818:                case 2:         res = 1; break;
                   2819:                case 4:         res = 2; break;
                   2820:                case 8:         res = 3; break;
                   2821:                case 16:        res = 4; break;
                   2822:                case 32:        res = 5; break;
                   2823:                case 64:        res = 6; break;
                   2824:                case 128:       res = 7; break;
                   2825:                case 256:       res = 8; break;
                   2826:                default:        return (0);
                   2827:                }
                   2828:        return (ICON (res));
                   2829: }

unix.superglobalmegacorp.com

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