Annotation of 3BSD/cmd/f77/expr.c, revision 1.1.1.1

1.1       root        1: #include "defs"
                      2: 
                      3: /* little routines to create constant blocks */
                      4: 
                      5: struct Constblock *mkconst(t)
                      6: register int t;
                      7: {
                      8: register struct Constblock *p;
                      9: 
                     10: p = ALLOC(Constblock);
                     11: p->tag = TCONST;
                     12: p->vtype = t;
                     13: return(p);
                     14: }
                     15: 
                     16: 
                     17: struct Constblock *mklogcon(l)
                     18: register int l;
                     19: {
                     20: register struct Constblock * p;
                     21: 
                     22: p = mkconst(TYLOGICAL);
                     23: p->const.ci = l;
                     24: return(p);
                     25: }
                     26: 
                     27: 
                     28: 
                     29: struct Constblock *mkintcon(l)
                     30: ftnint l;
                     31: {
                     32: register struct Constblock *p;
                     33: 
                     34: p = mkconst(TYLONG);
                     35: p->const.ci = l;
                     36: #ifdef MAXSHORT
                     37:        if(l >= -MAXSHORT   &&   l <= MAXSHORT)
                     38:                p->vtype = TYSHORT;
                     39: #endif
                     40: return(p);
                     41: }
                     42: 
                     43: 
                     44: 
                     45: struct Constblock *mkaddcon(l)
                     46: register int l;
                     47: {
                     48: register struct Constblock *p;
                     49: 
                     50: p = mkconst(TYADDR);
                     51: p->const.ci = l;
                     52: return(p);
                     53: }
                     54: 
                     55: 
                     56: 
                     57: struct Constblock *mkrealcon(t, d)
                     58: register int t;
                     59: double d;
                     60: {
                     61: register struct Constblock *p;
                     62: 
                     63: p = mkconst(t);
                     64: p->const.cd[0] = d;
                     65: return(p);
                     66: }
                     67: 
                     68: 
                     69: struct Constblock *mkbitcon(shift, leng, s)
                     70: int shift;
                     71: int leng;
                     72: char *s;
                     73: {
                     74: register struct Constblock *p;
                     75: 
                     76: p = mkconst(TYUNKNOWN);
                     77: p->const.ci = 0;
                     78: while(--leng >= 0)
                     79:        if(*s != ' ')
                     80:                p->const.ci = (p->const.ci << shift) | hextoi(*s++);
                     81: return(p);
                     82: }
                     83: 
                     84: 
                     85: 
                     86: 
                     87: 
                     88: struct Constblock *mkstrcon(l,v)
                     89: int l;
                     90: register char *v;
                     91: {
                     92: register struct Constblock *p;
                     93: register char *s;
                     94: 
                     95: p = mkconst(TYCHAR);
                     96: p->vleng = ICON(l);
                     97: p->const.ccp = s = (char *) ckalloc(l);
                     98: while(--l >= 0)
                     99:        *s++ = *v++;
                    100: return(p);
                    101: }
                    102: 
                    103: 
                    104: struct Constblock *mkcxcon(realp,imagp)
                    105: register expptr realp, imagp;
                    106: {
                    107: int rtype, itype;
                    108: register struct Constblock *p;
                    109: 
                    110: rtype = realp->headblock.vtype;
                    111: itype = imagp->headblock.vtype;
                    112: 
                    113: if( ISCONST(realp) && ISNUMERIC(rtype) && ISCONST(imagp) && ISNUMERIC(itype) )
                    114:        {
                    115:        p = mkconst( (rtype==TYDREAL||itype==TYDREAL) ? TYDCOMPLEX : TYCOMPLEX );
                    116:        if( ISINT(rtype) )
                    117:                p->const.cd[0] = realp->constblock.const.ci;
                    118:        else    p->const.cd[0] = realp->constblock.const.cd[0];
                    119:        if( ISINT(itype) )
                    120:                p->const.cd[1] = imagp->constblock.const.ci;
                    121:        else    p->const.cd[1] = imagp->constblock.const.cd[0];
                    122:        }
                    123: else
                    124:        {
                    125:        err("invalid complex constant");
                    126:        p = errnode();
                    127:        }
                    128: 
                    129: frexpr(realp);
                    130: frexpr(imagp);
                    131: return(p);
                    132: }
                    133: 
                    134: 
                    135: struct Errorblock *errnode()
                    136: {
                    137: struct Errorblock *p;
                    138: p = ALLOC(Errorblock);
                    139: p->tag = TERROR;
                    140: p->vtype = TYERROR;
                    141: return(p);
                    142: }
                    143: 
                    144: 
                    145: 
                    146: 
                    147: 
                    148: expptr mkconv(t, p)
                    149: register int t;
                    150: register expptr p;
                    151: {
                    152: register expptr q;
                    153: register int pt;
                    154: expptr opconv();
                    155: 
                    156: if(t==TYUNKNOWN || t==TYERROR)
                    157:        fatali("mkconv of impossible type %d", t);
                    158: pt = p->headblock.vtype;
                    159: if(t == pt)
                    160:        return(p);
                    161: 
                    162: else if( ISCONST(p) && pt!=TYADDR)
                    163:        {
                    164:        q = mkconst(t);
                    165:        consconv(t, &(q->constblock.const),
                    166:                p->constblock.vtype, &(p->constblock.const) );
                    167:        frexpr(p);
                    168:        }
                    169: #if TARGET == PDP11
                    170:        else if(ISINT(t) && pt==TYCHAR)
                    171:                {
                    172:                q = mkexpr(OPBITAND, opconv(p,TYSHORT), ICON(255));
                    173:                if(t == TYLONG)
                    174:                        q = opconv(q, TYLONG);
                    175:                }
                    176: #endif
                    177: else
                    178:        q = opconv(p, t);
                    179: 
                    180: if(t == TYCHAR)
                    181:        q->constblock.vleng = ICON(1);
                    182: return(q);
                    183: }
                    184: 
                    185: 
                    186: 
                    187: expptr opconv(p, t)
                    188: expptr p;
                    189: int t;
                    190: {
                    191: register expptr q;
                    192: 
                    193: q = mkexpr(OPCONV, p, 0);
                    194: q->headblock.vtype = t;
                    195: return(q);
                    196: }
                    197: 
                    198: 
                    199: 
                    200: struct Exprblock *addrof(p)
                    201: expptr p;
                    202: {
                    203: return( mkexpr(OPADDR, p, NULL) );
                    204: }
                    205: 
                    206: 
                    207: 
                    208: tagptr cpexpr(p)
                    209: register tagptr p;
                    210: {
                    211: register tagptr e;
                    212: int tag;
                    213: register chainp ep, pp;
                    214: ptr cpblock();
                    215: 
                    216: static int blksize[ ] =
                    217:        {       0,
                    218:                sizeof(struct Nameblock),
                    219:                sizeof(struct Constblock),
                    220:                sizeof(struct Exprblock),
                    221:                sizeof(struct Addrblock),
                    222:                sizeof(struct Primblock),
                    223:                sizeof(struct Listblock),
                    224:                sizeof(struct Errorblock)
                    225:        };
                    226: 
                    227: if(p == NULL)
                    228:        return(NULL);
                    229: 
                    230: if( (tag = p->headblock.tag) == TNAME)
                    231:        return(p);
                    232: 
                    233: e = cpblock( blksize[p->headblock.tag] , p);
                    234: 
                    235: switch(tag)
                    236:        {
                    237:        case TCONST:
                    238:                if(e->constblock.vtype == TYCHAR)
                    239:                        {
                    240:                        e->constblock.const.ccp =
                    241:                                copyn(1+strlen(e->constblock.const.ccp),
                    242:                                        e->constblock.const.ccp);
                    243:                        e->constblock.vleng = cpexpr(e->constblock.vleng);
                    244:                        }
                    245:        case TERROR:
                    246:                break;
                    247: 
                    248:        case TEXPR:
                    249:                e->exprblock.leftp = cpexpr(p->exprblock.leftp);
                    250:                e->exprblock.rightp = cpexpr(p->exprblock.rightp);
                    251:                break;
                    252: 
                    253:        case TLIST:
                    254:                if(pp = p->listblock.listp)
                    255:                        {
                    256:                        ep = e->listblock.listp = mkchain( cpexpr(pp->datap), NULL);
                    257:                        for(pp = pp->nextp ; pp ; pp = pp->nextp)
                    258:                                ep = ep->nextp = mkchain( cpexpr(pp->datap), NULL);
                    259:                        }
                    260:                break;
                    261: 
                    262:        case TADDR:
                    263:                e->addrblock.vleng = cpexpr(e->addrblock.vleng);
                    264:                e->addrblock.memoffset = cpexpr(e->addrblock.memoffset);
                    265:                e->addrblock.istemp = NO;
                    266:                break;
                    267: 
                    268:        case TPRIM:
                    269:                e->primblock.argsp = cpexpr(e->primblock.argsp);
                    270:                e->primblock.fcharp = cpexpr(e->primblock.fcharp);
                    271:                e->primblock.lcharp = cpexpr(e->primblock.lcharp);
                    272:                break;
                    273: 
                    274:        default:
                    275:                fatali("cpexpr: impossible tag %d", tag);
                    276:        }
                    277: 
                    278: return(e);
                    279: }
                    280: 
                    281: frexpr(p)
                    282: register tagptr p;
                    283: {
                    284: register chainp q;
                    285: 
                    286: if(p == NULL)
                    287:        return;
                    288: 
                    289: switch(p->headblock.tag)
                    290:        {
                    291:        case TCONST:
                    292:                if( ISCHAR(p) )
                    293:                        {
                    294:                        free(p->constblock.const.ccp);
                    295:                        frexpr(p->constblock.vleng);
                    296:                        }
                    297:                break;
                    298: 
                    299:        case TADDR:
                    300:                if(p->addrblock.istemp)
                    301:                        {
                    302:                        frtemp(p);
                    303:                        return;
                    304:                        }
                    305:                frexpr(p->addrblock.vleng);
                    306:                frexpr(p->addrblock.memoffset);
                    307:                break;
                    308: 
                    309:        case TERROR:
                    310:                break;
                    311: 
                    312:        case TNAME:
                    313:                return;
                    314: 
                    315:        case TPRIM:
                    316:                frexpr(p->primblock.argsp);
                    317:                frexpr(p->primblock.fcharp);
                    318:                frexpr(p->primblock.lcharp);
                    319:                break;
                    320: 
                    321:        case TEXPR:
                    322:                frexpr(p->exprblock.leftp);
                    323:                if(p->exprblock.rightp)
                    324:                        frexpr(p->exprblock.rightp);
                    325:                break;
                    326: 
                    327:        case TLIST:
                    328:                for(q = p->listblock.listp ; q ; q = q->nextp)
                    329:                        frexpr(q->datap);
                    330:                frchain( &(p->listblock.listp) );
                    331:                break;
                    332: 
                    333:        default:
                    334:                fatali("frexpr: impossible tag %d", p->headblock.tag);
                    335:        }
                    336: 
                    337: free(p);
                    338: }
                    339: 
                    340: /* fix up types in expression; replace subtrees and convert
                    341:    names to address blocks */
                    342: 
                    343: expptr fixtype(p)
                    344: register tagptr p;
                    345: {
                    346: 
                    347: if(p == 0)
                    348:        return(0);
                    349: 
                    350: switch(p->headblock.tag)
                    351:        {
                    352:        case TCONST:
                    353:                if( ! ONEOF(p->constblock.vtype,MSKINT|MSKLOGICAL|MSKADDR) )
                    354:                        p = putconst(p);
                    355:                return(p);
                    356: 
                    357:        case TADDR:
                    358:                p->addrblock.memoffset = fixtype(p->addrblock.memoffset);
                    359:                return(p);
                    360: 
                    361:        case TERROR:
                    362:                return(p);
                    363: 
                    364:        default:
                    365:                fatali("fixtype: impossible tag %d", p->headblock.tag);
                    366: 
                    367:        case TEXPR:
                    368:                return( fixexpr(p) );
                    369: 
                    370:        case TLIST:
                    371:                return( p );
                    372: 
                    373:        case TPRIM:
                    374:                if(p->primblock.argsp && p->primblock.namep->vclass!=CLVAR)
                    375:                        return( mkfunct(p) );
                    376:                else    return( mklhs(p) );
                    377:        }
                    378: }
                    379: 
                    380: 
                    381: 
                    382: 
                    383: 
                    384: /* special case tree transformations and cleanups of expression trees */
                    385: 
                    386: expptr fixexpr(p)
                    387: register struct Exprblock *p;
                    388: {
                    389: expptr lp;
                    390: register expptr rp;
                    391: register expptr q;
                    392: int opcode, ltype, rtype, ptype, mtype;
                    393: expptr mkpower();
                    394: 
                    395: if(p->tag == TERROR)
                    396:        return(p);
                    397: else if(p->tag != TEXPR)
                    398:        fatali("fixexpr: invalid tag %d", p->tag);
                    399: opcode = p->opcode;
                    400: lp = p->leftp = fixtype(p->leftp);
                    401: ltype = lp->headblock.vtype;
                    402: if(opcode==OPASSIGN && lp->headblock.tag!=TADDR)
                    403:        {
                    404:        err("left side of assignment must be variable");
                    405:        frexpr(p);
                    406:        return( errnode() );
                    407:        }
                    408: 
                    409: if(p->rightp)
                    410:        {
                    411:        rp = p->rightp = fixtype(p->rightp);
                    412:        rtype = rp->headblock.vtype;
                    413:        }
                    414: else
                    415:        {
                    416:        rp = NULL;
                    417:        rtype = 0;
                    418:        }
                    419: 
                    420: /* force folding if possible */
                    421: if( ISCONST(lp) && (rp==NULL || ISCONST(rp)) )
                    422:        {
                    423:        q = mkexpr(opcode, lp, rp);
                    424:        if( ISCONST(q) )
                    425:                return(q);
                    426:        free(q);        /* constants did not fold */
                    427:        }
                    428: 
                    429: if( (ptype = cktype(opcode, ltype, rtype)) == TYERROR)
                    430:        {
                    431:        frexpr(p);
                    432:        return( errnode() );
                    433:        }
                    434: 
                    435: switch(opcode)
                    436:        {
                    437:        case OPCONCAT:
                    438:                if(p->vleng == NULL)
                    439:                        p->vleng = mkexpr(OPPLUS,
                    440:                                cpexpr(lp->headblock.vleng),
                    441:                                cpexpr(rp->headblock.vleng) );
                    442:                break;
                    443: 
                    444:        case OPASSIGN:
                    445:        case OPPLUSEQ:
                    446:        case OPSTAREQ:
                    447:                if(ltype == rtype)
                    448:                        break;
                    449:                if( ! ISCONST(rp) && ISREAL(ltype) && ISREAL(rtype) )
                    450:                        break;
                    451:                if( ISCOMPLEX(ltype) || ISCOMPLEX(rtype) )
                    452:                        break;
                    453:                if( ONEOF(ltype, MSKADDR|MSKINT) && ONEOF(rtype, MSKADDR|MSKINT)
                    454: #if FAMILY==PCC
                    455:                    && typesize[ltype]>=typesize[rtype] )
                    456: #else
                    457:                    && typesize[ltype]==typesize[rtype] )
                    458: #endif
                    459:                        break;
                    460:                p->rightp = fixtype( mkconv(ptype, rp) );
                    461:                break;
                    462: 
                    463:        case OPSLASH:
                    464:                if( ISCOMPLEX(rtype) )
                    465:                        {
                    466:                        p = call2(ptype, ptype==TYCOMPLEX? "c_div" : "z_div",
                    467:                                mkconv(ptype, lp), mkconv(ptype, rp) );
                    468:                        break;
                    469:                        }
                    470:        case OPPLUS:
                    471:        case OPMINUS:
                    472:        case OPSTAR:
                    473:        case OPMOD:
                    474:                if(ptype==TYDREAL && ( (ltype==TYREAL && ! ISCONST(lp) ) ||
                    475:                    (rtype==TYREAL && ! ISCONST(rp) ) ))
                    476:                        break;
                    477:                if( ISCOMPLEX(ptype) )
                    478:                        break;
                    479:                if(ltype != ptype)
                    480:                        p->leftp = fixtype(mkconv(ptype,lp));
                    481:                if(rtype != ptype)
                    482:                        p->rightp = fixtype(mkconv(ptype,rp));
                    483:                break;
                    484: 
                    485:        case OPPOWER:
                    486:                return( mkpower(p) );
                    487: 
                    488:        case OPLT:
                    489:        case OPLE:
                    490:        case OPGT:
                    491:        case OPGE:
                    492:        case OPEQ:
                    493:        case OPNE:
                    494:                if(ltype == rtype)
                    495:                        break;
                    496:                mtype = cktype(OPMINUS, ltype, rtype);
                    497:                if(mtype==TYDREAL && ( (ltype==TYREAL && ! ISCONST(lp)) ||
                    498:                    (rtype==TYREAL && ! ISCONST(rp)) ))
                    499:                        break;
                    500:                if( ISCOMPLEX(mtype) )
                    501:                        break;
                    502:                if(ltype != mtype)
                    503:                        p->leftp = fixtype(mkconv(mtype,lp));
                    504:                if(rtype != mtype)
                    505:                        p->rightp = fixtype(mkconv(mtype,rp));
                    506:                break;
                    507: 
                    508: 
                    509:        case OPCONV:
                    510:                ptype = cktype(OPCONV, p->vtype, ltype);
                    511:                if(lp->headblock.tag==TEXPR && lp->exprblock.opcode==OPCOMMA)
                    512:                        {
                    513:                        lp->exprblock.rightp = fixtype( mkconv(ptype, lp->exprblock.rightp) );
                    514:                        free(p);
                    515:                        p = lp;
                    516:                        }
                    517:                break;
                    518: 
                    519:        case OPADDR:
                    520:                if(lp->headblock.tag==TEXPR && lp->exprblock.opcode==OPADDR)
                    521:                        fatal("addr of addr");
                    522:                break;
                    523: 
                    524:        case OPCOMMA:
                    525:        case OPQUEST:
                    526:        case OPCOLON:
                    527:                break;
                    528: 
                    529:        case OPMIN:
                    530:        case OPMAX:
                    531:                ptype = p->vtype;
                    532:                break;
                    533: 
                    534:        default:
                    535:                break;
                    536:        }
                    537: 
                    538: p->vtype = ptype;
                    539: return(p);
                    540: }
                    541: 
                    542: #if SZINT < SZLONG
                    543: /*
                    544:    for efficient subscripting, replace long ints by shorts
                    545:    in easy places
                    546: */
                    547: 
                    548: expptr shorten(p)
                    549: register expptr p;
                    550: {
                    551: register expptr q;
                    552: 
                    553: if(p->headblock.vtype != TYLONG)
                    554:        return(p);
                    555: 
                    556: switch(p->headblock.tag)
                    557:        {
                    558:        case TERROR:
                    559:        case TLIST:
                    560:                return(p);
                    561: 
                    562:        case TCONST:
                    563:        case TADDR:
                    564:                return( mkconv(TYINT,p) );
                    565: 
                    566:        case TEXPR:
                    567:                break;
                    568: 
                    569:        default:
                    570:                fatali("shorten: invalid tag %d", p->headblock.tag);
                    571:        }
                    572: 
                    573: switch(p->exprblock.opcode)
                    574:        {
                    575:        case OPPLUS:
                    576:        case OPMINUS:
                    577:        case OPSTAR:
                    578:                q = shorten( cpexpr(p->exprblock.rightp) );
                    579:                if(q->headblock.vtype == TYINT)
                    580:                        {
                    581:                        p->exprblock.leftp = shorten(p->exprblock.leftp);
                    582:                        if(p->exprblock.leftp->headblock.vtype == TYLONG)
                    583:                                frexpr(q);
                    584:                        else
                    585:                                {
                    586:                                frexpr(p->exprblock.rightp);
                    587:                                p->exprblock.rightp = q;
                    588:                                p->exprblock.vtype = TYINT;
                    589:                                }
                    590:                        }
                    591:                break;
                    592: 
                    593:        case OPNEG:
                    594:                p->exprblock.leftp = shorten(p->exprblock.leftp);
                    595:                if(p->exprblock.leftp->headblock.vtype == TYINT)
                    596:                        p->exprblock.vtype = TYINT;
                    597:                break;
                    598: 
                    599:        case OPCALL:
                    600:        case OPCCALL:
                    601:                p = mkconv(TYINT,p);
                    602:                break;
                    603:        default:
                    604:                break;
                    605:        }
                    606: 
                    607: return(p);
                    608: }
                    609: #endif
                    610: 
                    611: fixargs(doput, p0)
                    612: int doput;
                    613: struct Listblock *p0;
                    614: {
                    615: register chainp p;
                    616: register tagptr q, t;
                    617: register int qtag;
                    618: int nargs;
                    619: struct Addrblock *mkscalar();
                    620: 
                    621: nargs = 0;
                    622: if(p0)
                    623:     for(p = p0->listp ; p ; p = p->nextp)
                    624:        {
                    625:        ++nargs;
                    626:        q = p->datap;
                    627:        qtag = q->headblock.tag;
                    628:        if(qtag == TCONST)
                    629:                {
                    630:                if(q->constblock.vtype == TYSHORT)
                    631:                        q = mkconv(tyint, q);
                    632:                if(doput)
                    633:                        p->datap = putconst(q);
                    634:                else
                    635:                        p->datap = q;
                    636:                }
                    637:        else if(qtag==TPRIM && q->primblock.argsp==0 && q->primblock.namep->vclass==CLPROC)
                    638:                p->datap = mkaddr(q->primblock.namep);
                    639:        else if(qtag==TPRIM && q->primblock.argsp==0 && q->primblock.namep->vdim!=NULL)
                    640:                p->datap = mkscalar(q->primblock.namep);
                    641:        else if(qtag==TPRIM && q->primblock.argsp==0 && q->primblock.namep->vdovar && 
                    642:                (t = memversion(q->primblock.namep)) )
                    643:                        p->datap = fixtype(t);
                    644:        else    p->datap = fixtype(q);
                    645:        }
                    646: return(nargs);
                    647: }
                    648: 
                    649: 
                    650: struct Addrblock *mkscalar(np)
                    651: register struct Nameblock *np;
                    652: {
                    653: register struct Addrblock *ap;
                    654: register struct Dimblock *dp;
                    655: 
                    656: vardcl(np);
                    657: ap = mkaddr(np);
                    658: 
                    659: #if TARGET == VAX
                    660:        /* on the VAX, prolog causes array arguments
                    661:           to point at the (0,...,0) element, except when
                    662:           subscript checking is on
                    663:        */
                    664:        if( !checksubs && np->vstg==STGARG)
                    665:                {
                    666:                dp = np->vdim;
                    667:                frexpr(ap->memoffset);
                    668:                ap->memoffset = mkexpr(OPSTAR,
                    669:                                (np->vtype==TYCHAR ?
                    670:                                        cpexpr(np->vleng) :
                    671:                                        (tagptr)ICON(typesize[np->vtype]) ),
                    672:                                cpexpr(dp->baseoffset) );
                    673:                }
                    674: #endif
                    675: return(ap);
                    676: }
                    677: 
                    678: 
                    679: 
                    680: 
                    681: 
                    682: expptr mkfunct(p)
                    683: register struct Primblock * p;
                    684: {
                    685: struct Entrypoint *ep;
                    686: struct Addrblock *ap;
                    687: struct Extsym *extp;
                    688: register struct Nameblock *np;
                    689: register struct Exprblock *q;
                    690: struct Exprblock *intrcall(), *stfcall();
                    691: int k, nargs;
                    692: int class;
                    693: 
                    694: np = p->namep;
                    695: class = np->vclass;
                    696: 
                    697: if(class == CLUNKNOWN)
                    698:        {
                    699:        np->vclass = class = CLPROC;
                    700:        if(np->vstg == STGUNKNOWN)
                    701:                {
                    702:                if(k = intrfunct(np->varname))
                    703:                        {
                    704:                        np->vstg = STGINTR;
                    705:                        np->vardesc.varno = k;
                    706:                        np->vprocclass = PINTRINSIC;
                    707:                        }
                    708:                else
                    709:                        {
                    710:                        extp = mkext( varunder(VL,np->varname) );
                    711:                        extp->extstg = STGEXT;
                    712:                        np->vstg = STGEXT;
                    713:                        np->vardesc.varno = extp - extsymtab;
                    714:                        np->vprocclass = PEXTERNAL;
                    715:                        }
                    716:                }
                    717:        else if(np->vstg==STGARG)
                    718:                {
                    719:                if(np->vtype!=TYCHAR && !ftn66flag)
                    720:                    warn("Dummy procedure not declared EXTERNAL. Code may be wrong.");
                    721:                np->vprocclass = PEXTERNAL;
                    722:                }
                    723:        }
                    724: 
                    725: if(class != CLPROC)
                    726:        fatali("invalid class code %d for function", class);
                    727: if(p->fcharp || p->lcharp)
                    728:        {
                    729:        err("no substring of function call");
                    730:        goto error;
                    731:        }
                    732: impldcl(np);
                    733: nargs = fixargs( np->vprocclass!=PINTRINSIC,  p->argsp);
                    734: 
                    735: switch(np->vprocclass)
                    736:        {
                    737:        case PEXTERNAL:
                    738:                ap = mkaddr(np);
                    739:        call:
                    740:                q = mkexpr(OPCALL, ap, p->argsp);
                    741:                if( (q->vtype = np->vtype) == TYUNKNOWN)
                    742:                        {
                    743:                        err("attempt to use untyped function");
                    744:                        goto error;
                    745:                        }
                    746:                if(np->vleng)
                    747:                        q->vleng = cpexpr(np->vleng);
                    748:                break;
                    749: 
                    750:        case PINTRINSIC:
                    751:                q = intrcall(np, p->argsp, nargs);
                    752:                break;
                    753: 
                    754:        case PSTFUNCT:
                    755:                q = stfcall(np, p->argsp);
                    756:                break;
                    757: 
                    758:        case PTHISPROC:
                    759:                warn("recursive call");
                    760:                for(ep = entries ; ep ; ep = ep->nextp)
                    761:                        if(ep->enamep == np)
                    762:                                break;
                    763:                if(ep == NULL)
                    764:                        fatal("mkfunct: impossible recursion");
                    765:                ap = builtin(np->vtype, varstr(XL, ep->entryname->extname) );
                    766:                goto call;
                    767: 
                    768:        default:
                    769:                fatali("mkfunct: impossible vprocclass %d", np->vprocclass);
                    770:        }
                    771: free(p);
                    772: return(q);
                    773: 
                    774: error:
                    775:        frexpr(p);
                    776:        return( errnode() );
                    777: }
                    778: 
                    779: 
                    780: 
                    781: LOCAL struct Exprblock *stfcall(np, actlist)
                    782: struct Nameblock *np;
                    783: struct Listblock *actlist;
                    784: {
                    785: register chainp actuals;
                    786: int nargs;
                    787: chainp oactp, formals;
                    788: int type;
                    789: struct Exprblock *q, *rhs;
                    790: expptr ap;
                    791: register struct Rplblock *rp;
                    792: struct Rplblock *tlist;
                    793: 
                    794: if(actlist)
                    795:        {
                    796:        actuals = actlist->listp;
                    797:        free(actlist);
                    798:        }
                    799: else
                    800:        actuals = NULL;
                    801: oactp = actuals;
                    802: 
                    803: nargs = 0;
                    804: tlist = NULL;
                    805: if( (type = np->vtype) == TYUNKNOWN)
                    806:        {
                    807:        err("attempt to use untyped statement function");
                    808:        q = errnode();
                    809:        goto ret;
                    810:        }
                    811: formals = np->vardesc.vstfdesc->datap;
                    812: rhs = np->vardesc.vstfdesc->nextp;
                    813: 
                    814: /* copy actual arguments into temporaries */
                    815: while(actuals!=NULL && formals!=NULL)
                    816:        {
                    817:        rp = ALLOC(Rplblock);
                    818:        rp->rplnp = q = formals->datap;
                    819:        ap = fixtype(actuals->datap);
                    820:        if(q->vtype==ap->headblock.vtype && q->vtype!=TYCHAR
                    821:           && (ap->headblock.tag==TCONST || ap->headblock.tag==TADDR) )
                    822:                {
                    823:                rp->rplvp = ap;
                    824:                rp->rplxp = NULL;
                    825:                rp->rpltag = ap->headblock.tag;
                    826:                }
                    827:        else    {
                    828:                rp->rplvp = mktemp(q->vtype, q->vleng);
                    829:                rp->rplxp = fixtype( mkexpr(OPASSIGN, cpexpr(rp->rplvp), ap) );
                    830:                if( (rp->rpltag = rp->rplxp->tag) == TERROR)
                    831:                        err("disagreement of argument types in statement function call");
                    832:                }
                    833:        rp->nextp = tlist;
                    834:        tlist = rp;
                    835:        actuals = actuals->nextp;
                    836:        formals = formals->nextp;
                    837:        ++nargs;
                    838:        }
                    839: 
                    840: if(actuals!=NULL || formals!=NULL)
                    841:        err("statement function definition and argument list differ");
                    842: 
                    843: /*
                    844:    now push down names involved in formal argument list, then
                    845:    evaluate rhs of statement function definition in this environment
                    846: */
                    847: rpllist = hookup(tlist, rpllist);
                    848: q = mkconv(type, fixtype(cpexpr(rhs)) );
                    849: 
                    850: /* now generate the tree ( t1=a1, (t2=a2,... , f))))) */
                    851: while(--nargs >= 0)
                    852:        {
                    853:        if(rpllist->rplxp)
                    854:                q = mkexpr(OPCOMMA, rpllist->rplxp, q);
                    855:        rp = rpllist->nextp;
                    856:        frexpr(rpllist->rplvp);
                    857:        free(rpllist);
                    858:        rpllist = rp;
                    859:        }
                    860: 
                    861: ret:
                    862:        frchain( &oactp );
                    863:        return(q);
                    864: }
                    865: 
                    866: 
                    867: 
                    868: 
                    869: struct Addrblock *mklhs(p)
                    870: register struct Primblock * p;
                    871: {
                    872: register struct Addrblock *s;
                    873: expptr suboffset();
                    874: struct Nameblock *np;
                    875: register struct Rplblock *rp;
                    876: int regn;
                    877: 
                    878: /* first fixup name */
                    879: 
                    880: if(p->tag != TPRIM)
                    881:        return(p);
                    882: np = p->namep;
                    883: 
                    884: /* is name on the replace list? */
                    885: 
                    886: for(rp = rpllist ; rp ; rp = rp->nextp)
                    887:        {
                    888:        if(np == rp->rplnp)
                    889:                {
                    890:                if(rp->rpltag == TNAME)
                    891:                        {
                    892:                        np = p->namep = rp->rplvp;
                    893:                        break;
                    894:                        }
                    895:                else    return( cpexpr(rp->rplvp) );
                    896:                }
                    897:        }
                    898: 
                    899: /* is variable a DO index in a register ? */
                    900: 
                    901: if(np->vdovar && ( (regn = inregister(np)) >= 0) )
                    902:        if(np->vtype == TYERROR)
                    903:                return( errnode() );
                    904:        else
                    905:                {
                    906:                s = ALLOC(Addrblock);
                    907:                s->tag = TADDR;
                    908:                s->vstg = STGREG;
                    909:                s->vtype = TYIREG;
                    910:                s->memno = regn;
                    911:                s->memoffset = ICON(0);
                    912:                return(s);
                    913:                }
                    914: 
                    915: vardcl(np);
                    916: s = mkaddr(np);
                    917: s->memoffset = mkexpr(OPPLUS, s->memoffset, suboffset(p) );
                    918: frexpr(p->argsp);
                    919: p->argsp = NULL;
                    920: 
                    921: /* now do substring part */
                    922: 
                    923: if(p->fcharp || p->lcharp)
                    924:        {
                    925:        if(np->vtype != TYCHAR)
                    926:                errstr("substring of noncharacter %s", varstr(VL,np->varname));
                    927:        else    {
                    928:                if(p->lcharp == NULL)
                    929:                        p->lcharp = cpexpr(s->vleng);
                    930:                if(p->fcharp)
                    931:                        s->vleng = mkexpr(OPMINUS, p->lcharp,
                    932:                                mkexpr(OPMINUS, p->fcharp, ICON(1) ));
                    933:                else    {
                    934:                        frexpr(s->vleng);
                    935:                        s->vleng = p->lcharp;
                    936:                        }
                    937:                }
                    938:        }
                    939: 
                    940: s->vleng = fixtype( s->vleng );
                    941: s->memoffset = fixtype( s->memoffset );
                    942: free(p);
                    943: return(s);
                    944: }
                    945: 
                    946: 
                    947: 
                    948: 
                    949: 
                    950: deregister(np)
                    951: struct Nameblock *np;
                    952: {
                    953: if(nregvar>0 && regnamep[nregvar-1]==np)
                    954:        {
                    955:        --nregvar;
                    956: #if FAMILY == DMR
                    957:        putnreg();
                    958: #endif
                    959:        }
                    960: }
                    961: 
                    962: 
                    963: 
                    964: 
                    965: struct Addrblock *memversion(np)
                    966: register struct Nameblock *np;
                    967: {
                    968: register struct Addrblock *s;
                    969: 
                    970: if(np->vdovar==NO || (inregister(np)<0) )
                    971:        return(NULL);
                    972: np->vdovar = NO;
                    973: s = mklhs( mkprim(np, 0,0,0) );
                    974: np->vdovar = YES;
                    975: return(s);
                    976: }
                    977: 
                    978: 
                    979: 
                    980: inregister(np)
                    981: register struct Nameblock *np;
                    982: {
                    983: register int i;
                    984: 
                    985: for(i = 0 ; i < nregvar ; ++i)
                    986:        if(regnamep[i] == np)
                    987:                return( regnum[i] );
                    988: return(-1);
                    989: }
                    990: 
                    991: 
                    992: 
                    993: 
                    994: enregister(np)
                    995: struct Nameblock *np;
                    996: {
                    997: if( inregister(np) >= 0)
                    998:        return(YES);
                    999: if(nregvar >= maxregvar)
                   1000:        return(NO);
                   1001: vardcl(np);
                   1002: if( ONEOF(np->vtype, MSKIREG) )
                   1003:        {
                   1004:        regnamep[nregvar++] = np;
                   1005:        if(nregvar > highregvar)
                   1006:                highregvar = nregvar;
                   1007: #if FAMILY == DMR
                   1008:        putnreg();
                   1009: #endif
                   1010:        return(YES);
                   1011:        }
                   1012: else
                   1013:        return(NO);
                   1014: }
                   1015: 
                   1016: 
                   1017: 
                   1018: 
                   1019: expptr suboffset(p)
                   1020: register struct Primblock *p;
                   1021: {
                   1022: int n;
                   1023: expptr size;
                   1024: chainp cp;
                   1025: expptr offp, prod;
                   1026: expptr subcheck();
                   1027: struct Dimblock *dimp;
                   1028: expptr sub[MAXDIM+1];
                   1029: register struct Nameblock *np;
                   1030: 
                   1031: np = p->namep;
                   1032: offp = ICON(0);
                   1033: n = 0;
                   1034: if(p->argsp)
                   1035:        for(cp = p->argsp->listp ; cp ; cp = cp->nextp)
                   1036:                {
                   1037:                sub[n++] = fixtype(cpexpr(cp->datap));
                   1038:                if(n > maxdim)
                   1039:                        {
                   1040:                        erri("more than %d subscripts", maxdim);
                   1041:                        break;
                   1042:                        }
                   1043:                }
                   1044: 
                   1045: dimp = np->vdim;
                   1046: if(n>0 && dimp==NULL)
                   1047:        err("subscripts on scalar variable");
                   1048: else if(dimp && dimp->ndim!=n)
                   1049:        errstr("wrong number of subscripts on %s",
                   1050:                varstr(VL, np->varname) );
                   1051: else if(n > 0)
                   1052:        {
                   1053:        prod = sub[--n];
                   1054:        while( --n >= 0)
                   1055:                prod = mkexpr(OPPLUS, sub[n],
                   1056:                        mkexpr(OPSTAR, prod, cpexpr(dimp->dims[n].dimsize)) );
                   1057: #if TARGET == VAX
                   1058:        if(checksubs || np->vstg!=STGARG)
                   1059:                prod = mkexpr(OPMINUS, prod, cpexpr(dimp->baseoffset));
                   1060: #else
                   1061:        prod = mkexpr(OPMINUS, prod, cpexpr(dimp->baseoffset));
                   1062: #endif
                   1063:        if(checksubs)
                   1064:                prod = subcheck(np, prod);
                   1065:        if(np->vtype == TYCHAR)
                   1066:                size = cpexpr(np->vleng);
                   1067:        else    size = ICON( typesize[np->vtype] );
                   1068:        prod = mkexpr(OPSTAR, prod, size);
                   1069:        offp = mkexpr(OPPLUS, offp, prod);
                   1070:        }
                   1071: 
                   1072: if(p->fcharp && np->vtype==TYCHAR)
                   1073:        offp = mkexpr(OPPLUS, offp, mkexpr(OPMINUS, cpexpr(p->fcharp), ICON(1) ));
                   1074: 
                   1075: return(offp);
                   1076: }
                   1077: 
                   1078: 
                   1079: 
                   1080: 
                   1081: expptr subcheck(np, p)
                   1082: struct Nameblock *np;
                   1083: register expptr p;
                   1084: {
                   1085: struct Dimblock *dimp;
                   1086: expptr t, checkvar, checkcond, badcall;
                   1087: 
                   1088: dimp = np->vdim;
                   1089: if(dimp->nelt == NULL)
                   1090:        return(p);      /* don't check arrays with * bounds */
                   1091: checkvar = NULL;
                   1092: checkcond = NULL;
                   1093: if( ISICON(p) )
                   1094:        {
                   1095:        if(p->constblock.const.ci < 0)
                   1096:                goto badsub;
                   1097:        if( ISICON(dimp->nelt) )
                   1098:                if(p->constblock.const.ci < dimp->nelt->constblock.const.ci)
                   1099:                        return(p);
                   1100:                else
                   1101:                        goto badsub;
                   1102:        }
                   1103: if(p->headblock.tag==TADDR && p->addrblock.vstg==STGREG)
                   1104:        {
                   1105:        checkvar = cpexpr(p);
                   1106:        t = p;
                   1107:        }
                   1108: else   {
                   1109:        checkvar = mktemp(p->headblock.vtype, NULL);
                   1110:        t = mkexpr(OPASSIGN, cpexpr(checkvar), p);
                   1111:        }
                   1112: checkcond = mkexpr(OPLT, t, cpexpr(dimp->nelt) );
                   1113: if( ! ISICON(p) )
                   1114:        checkcond = mkexpr(OPAND, checkcond,
                   1115:                        mkexpr(OPLE, ICON(0), cpexpr(checkvar)) );
                   1116: 
                   1117: badcall = call4(p->headblock.vtype, "s_rnge", mkstrcon(VL, np->varname),
                   1118:                mkconv(TYLONG,  cpexpr(checkvar)),
                   1119:                mkstrcon(XL, procname), ICON(lineno));
                   1120: badcall->exprblock.opcode = OPCCALL;
                   1121: p = mkexpr(OPQUEST, checkcond,
                   1122:        mkexpr(OPCOLON, checkvar, badcall));
                   1123: 
                   1124: return(p);
                   1125: 
                   1126: badsub:
                   1127:        frexpr(p);
                   1128:        errstr("subscript on variable %s out of range", varstr(VL,np->varname));
                   1129:        return ( ICON(0) );
                   1130: }
                   1131: 
                   1132: 
                   1133: 
                   1134: 
                   1135: struct Addrblock *mkaddr(p)
                   1136: register struct Nameblock *p;
                   1137: {
                   1138: struct Extsym *extp;
                   1139: register struct Addrblock *t;
                   1140: struct Addrblock *intraddr();
                   1141: 
                   1142: switch( p->vstg)
                   1143:        {
                   1144:        case STGUNKNOWN:
                   1145:                if(p->vclass != CLPROC)
                   1146:                        break;
                   1147:                extp = mkext( varunder(VL, p->varname) );
                   1148:                extp->extstg = STGEXT;
                   1149:                p->vstg = STGEXT;
                   1150:                p->vardesc.varno = extp - extsymtab;
                   1151:                p->vprocclass = PEXTERNAL;
                   1152: 
                   1153:        case STGCOMMON:
                   1154:        case STGEXT:
                   1155:        case STGBSS:
                   1156:        case STGINIT:
                   1157:        case STGEQUIV:
                   1158:        case STGARG:
                   1159:        case STGLENG:
                   1160:        case STGAUTO:
                   1161:                t = ALLOC(Addrblock);
                   1162:                t->tag = TADDR;
                   1163:                if(p->vclass==CLPROC && p->vprocclass==PTHISPROC)
                   1164:                        t->vclass = CLVAR;
                   1165:                else
                   1166:                        t->vclass = p->vclass;
                   1167:                t->vtype = p->vtype;
                   1168:                t->vstg = p->vstg;
                   1169:                t->memno = p->vardesc.varno;
                   1170:                t->memoffset = ICON(p->voffset);
                   1171:                if(p->vleng)
                   1172:                        t->vleng = cpexpr(p->vleng);
                   1173:                return(t);
                   1174: 
                   1175:        case STGINTR:
                   1176:                return( intraddr(p) );
                   1177: 
                   1178:        }
                   1179: /*debug*/ fprintf(diagfile, "mkaddr. vtype=%d, vclass=%d\n", p->vtype, p->vclass);
                   1180: fatali("mkaddr: impossible storage tag %d", p->vstg);
                   1181: /* NOTREACHED */
                   1182: }
                   1183: 
                   1184: 
                   1185: 
                   1186: 
                   1187: mkarg(type, argno)
                   1188: int type, argno;
                   1189: {
                   1190: register struct Addrblock *p;
                   1191: 
                   1192: p = ALLOC(Addrblock);
                   1193: p->tag = TADDR;
                   1194: p->vtype = type;
                   1195: p->vclass = CLVAR;
                   1196: p->vstg = (type==TYLENG ? STGLENG : STGARG);
                   1197: p->memno = argno;
                   1198: return(p);
                   1199: }
                   1200: 
                   1201: 
                   1202: 
                   1203: 
                   1204: tagptr mkprim(v, args, lstr, rstr)
                   1205: register union
                   1206:        {
                   1207:        struct Paramblock paramblock;
                   1208:        struct Nameblock nameblock;
                   1209:        struct Headblock headblock;
                   1210:        } *v;
                   1211: struct Listblock *args;
                   1212: expptr lstr, rstr;
                   1213: {
                   1214: register struct Primblock *p;
                   1215: 
                   1216: if(v->headblock.vclass == CLPARAM)
                   1217:        {
                   1218:        if(args || lstr || rstr)
                   1219:                {
                   1220:                errstr("no qualifiers on parameter name %s",
                   1221:                        varstr(VL,v->paramblock.varname));
                   1222:                frexpr(args);
                   1223:                frexpr(lstr);
                   1224:                frexpr(rstr);
                   1225:                frexpr(v);
                   1226:                return( errnode() );
                   1227:                }
                   1228:        return( cpexpr(v->paramblock.paramval) );
                   1229:        }
                   1230: 
                   1231: p = ALLOC(Primblock);
                   1232: p->tag = TPRIM;
                   1233: p->vtype = v->nameblock.vtype;
                   1234: p->namep = v;
                   1235: p->argsp = args;
                   1236: p->fcharp = lstr;
                   1237: p->lcharp = rstr;
                   1238: return(p);
                   1239: }
                   1240: 
                   1241: 
                   1242: 
                   1243: vardcl(v)
                   1244: register struct Nameblock *v;
                   1245: {
                   1246: int nelt;
                   1247: struct Dimblock *t;
                   1248: struct Addrblock *p;
                   1249: expptr neltp;
                   1250: 
                   1251: if(v->vdcldone) return;
                   1252: 
                   1253: if(v->vtype == TYUNKNOWN)
                   1254:        impldcl(v);
                   1255: if(v->vclass == CLUNKNOWN)
                   1256:        v->vclass = CLVAR;
                   1257: else if(v->vclass!=CLVAR && v->vprocclass!=PTHISPROC)
                   1258:        {
                   1259:        dclerr("used as variable", v);
                   1260:        return;
                   1261:        }
                   1262: if(v->vstg==STGUNKNOWN)
                   1263:        v->vstg = implstg[ letter(v->varname[0]) ];
                   1264: 
                   1265: switch(v->vstg)
                   1266:        {
                   1267:        case STGBSS:
                   1268:                v->vardesc.varno = ++lastvarno;
                   1269:                break;
                   1270:        case STGAUTO:
                   1271:                if(v->vclass==CLPROC && v->vprocclass==PTHISPROC)
                   1272:                        break;
                   1273:                nelt = 1;
                   1274:                if(t = v->vdim)
                   1275:                        if( (neltp = t->nelt) && ISCONST(neltp) )
                   1276:                                nelt = neltp->constblock.const.ci;
                   1277:                        else
                   1278:                                dclerr("adjustable automatic array", v);
                   1279:                p = autovar(nelt, v->vtype, v->vleng);
                   1280:                v->voffset = p->memoffset->constblock.const.ci;
                   1281:                frexpr(p);
                   1282:                break;
                   1283: 
                   1284:        default:
                   1285:                break;
                   1286:        }
                   1287: v->vdcldone = YES;
                   1288: }
                   1289: 
                   1290: 
                   1291: 
                   1292: 
                   1293: impldcl(p)
                   1294: register struct Nameblock *p;
                   1295: {
                   1296: register int k;
                   1297: int type, leng;
                   1298: 
                   1299: if(p->vdcldone || (p->vclass==CLPROC && p->vprocclass==PINTRINSIC) )
                   1300:        return;
                   1301: if(p->vtype == TYUNKNOWN)
                   1302:        {
                   1303:        k = letter(p->varname[0]);
                   1304:        type = impltype[ k ];
                   1305:        leng = implleng[ k ];
                   1306:        if(type == TYUNKNOWN)
                   1307:                {
                   1308:                if(p->vclass == CLPROC)
                   1309:                        return;
                   1310:                dclerr("attempt to use undefined variable", p);
                   1311:                type = TYERROR;
                   1312:                leng = 1;
                   1313:                }
                   1314:        settype(p, type, leng);
                   1315:        }
                   1316: }
                   1317: 
                   1318: 
                   1319: 
                   1320: 
                   1321: LOCAL letter(c)
                   1322: register int c;
                   1323: {
                   1324: if( isupper(c) )
                   1325:        c = tolower(c);
                   1326: return(c - 'a');
                   1327: }
                   1328: 
                   1329: #define ICONEQ(z, c)  (ISICON(z) && z->constblock.const.ci==c)
                   1330: #define COMMUTE        { e = lp;  lp = rp;  rp = e; }
                   1331: 
                   1332: 
                   1333: expptr mkexpr(opcode, lp, rp)
                   1334: int opcode;
                   1335: register expptr lp, rp;
                   1336: {
                   1337: register struct Exprblock *e, *e1;
                   1338: int etype;
                   1339: int ltype, rtype;
                   1340: int ltag, rtag;
                   1341: expptr fold();
                   1342: 
                   1343: ltype = lp->headblock.vtype;
                   1344: ltag = lp->headblock.tag;
                   1345: if(rp && opcode!=OPCALL && opcode!=OPCCALL)
                   1346:        {
                   1347:        rtype = rp->headblock.vtype;
                   1348:        rtag = rp->headblock.tag;
                   1349:        }
                   1350: else  rtype = 0;
                   1351: 
                   1352: etype = cktype(opcode, ltype, rtype);
                   1353: if(etype == TYERROR)
                   1354:        goto error;
                   1355: 
                   1356: switch(opcode)
                   1357:        {
                   1358:        /* check for multiplication by 0 and 1 and addition to 0 */
                   1359: 
                   1360:        case OPSTAR:
                   1361:                if( ISCONST(lp) )
                   1362:                        COMMUTE
                   1363: 
                   1364:                if( ISICON(rp) )
                   1365:                        {
                   1366:                        if(rp->constblock.const.ci == 0)
                   1367:                                goto retright;
                   1368:                        goto mulop;
                   1369:                        }
                   1370:                break;
                   1371: 
                   1372:        case OPSLASH:
                   1373:        case OPMOD:
                   1374:                if( ICONEQ(rp, 0) )
                   1375:                        {
                   1376:                        err("attempted division by zero");
                   1377:                        rp = ICON(1);
                   1378:                        break;
                   1379:                        }
                   1380:                if(opcode == OPMOD)
                   1381:                        break;
                   1382: 
                   1383: 
                   1384:        mulop:
                   1385:                if( ISICON(rp) )
                   1386:                        {
                   1387:                        if(rp->constblock.const.ci == 1)
                   1388:                                goto retleft;
                   1389: 
                   1390:                        if(rp->constblock.const.ci == -1)
                   1391:                                {
                   1392:                                frexpr(rp);
                   1393:                                return( mkexpr(OPNEG, lp, 0) );
                   1394:                                }
                   1395:                        }
                   1396: 
                   1397:                if( ISSTAROP(lp) && ISICON(lp->exprblock.rightp) )
                   1398:                        {
                   1399:                        if(opcode == OPSTAR)
                   1400:                                e = mkexpr(OPSTAR, lp->exprblock.rightp, rp);
                   1401:                        else  if(ISICON(rp) &&
                   1402:                                (lp->exprblock.rightp->constblock.const.ci %
                   1403:                                        rp->constblock.const.ci) == 0)
                   1404:                                e = mkexpr(OPSLASH, lp->exprblock.rightp, rp);
                   1405:                        else    break;
                   1406: 
                   1407:                        e1 = lp->exprblock.leftp;
                   1408:                        free(lp);
                   1409:                        return( mkexpr(OPSTAR, e1, e) );
                   1410:                        }
                   1411:                break;
                   1412: 
                   1413: 
                   1414:        case OPPLUS:
                   1415:                if( ISCONST(lp) )
                   1416:                        COMMUTE
                   1417:                goto addop;
                   1418: 
                   1419:        case OPMINUS:
                   1420:                if( ICONEQ(lp, 0) )
                   1421:                        {
                   1422:                        frexpr(lp);
                   1423:                        return( mkexpr(OPNEG, rp, 0) );
                   1424:                        }
                   1425: 
                   1426:                if( ISCONST(rp) )
                   1427:                        {
                   1428:                        opcode = OPPLUS;
                   1429:                        consnegop(rp);
                   1430:                        }
                   1431: 
                   1432:        addop:
                   1433:                if( ISICON(rp) )
                   1434:                        {
                   1435:                        if(rp->constblock.const.ci == 0)
                   1436:                                goto retleft;
                   1437:                        if( ISPLUSOP(lp) && ISICON(lp->exprblock.rightp) )
                   1438:                                {
                   1439:                                e = mkexpr(OPPLUS, lp->exprblock.rightp, rp);
                   1440:                                e1 = lp->exprblock.leftp;
                   1441:                                free(lp);
                   1442:                                return( mkexpr(OPPLUS, e1, e) );
                   1443:                                }
                   1444:                        }
                   1445:                break;
                   1446: 
                   1447: 
                   1448:        case OPPOWER:
                   1449:                break;
                   1450: 
                   1451:        case OPNEG:
                   1452:                if(ltag==TEXPR && lp->exprblock.opcode==OPNEG)
                   1453:                        {
                   1454:                        e = lp->exprblock.leftp;
                   1455:                        free(lp);
                   1456:                        return(e);
                   1457:                        }
                   1458:                break;
                   1459: 
                   1460:        case OPNOT:
                   1461:                if(ltag==TEXPR && lp->exprblock.opcode==OPNOT)
                   1462:                        {
                   1463:                        e = lp->exprblock.leftp;
                   1464:                        free(lp);
                   1465:                        return(e);
                   1466:                        }
                   1467:                break;
                   1468: 
                   1469:        case OPCALL:
                   1470:        case OPCCALL:
                   1471:                etype = ltype;
                   1472:                if(rp!=NULL && rp->listblock.listp==NULL)
                   1473:                        {
                   1474:                        free(rp);
                   1475:                        rp = NULL;
                   1476:                        }
                   1477:                break;
                   1478: 
                   1479:        case OPAND:
                   1480:        case OPOR:
                   1481:                if( ISCONST(lp) )
                   1482:                        COMMUTE
                   1483: 
                   1484:                if( ISCONST(rp) )
                   1485:                        {
                   1486:                        if(rp->constblock.const.ci == 0)
                   1487:                                if(opcode == OPOR)
                   1488:                                        goto retleft;
                   1489:                                else
                   1490:                                        goto retright;
                   1491:                        else if(opcode == OPOR)
                   1492:                                goto retright;
                   1493:                        else
                   1494:                                goto retleft;
                   1495:                        }
                   1496:        case OPEQV:
                   1497:        case OPNEQV:
                   1498: 
                   1499:        case OPBITAND:
                   1500:        case OPBITOR:
                   1501:        case OPBITXOR:
                   1502:        case OPBITNOT:
                   1503:        case OPLSHIFT:
                   1504:        case OPRSHIFT:
                   1505: 
                   1506:        case OPLT:
                   1507:        case OPGT:
                   1508:        case OPLE:
                   1509:        case OPGE:
                   1510:        case OPEQ:
                   1511:        case OPNE:
                   1512: 
                   1513:        case OPCONCAT:
                   1514:                break;
                   1515:        case OPMIN:
                   1516:        case OPMAX:
                   1517: 
                   1518:        case OPASSIGN:
                   1519:        case OPPLUSEQ:
                   1520:        case OPSTAREQ:
                   1521: 
                   1522:        case OPCONV:
                   1523:        case OPADDR:
                   1524: 
                   1525:        case OPCOMMA:
                   1526:        case OPQUEST:
                   1527:        case OPCOLON:
                   1528:                break;
                   1529: 
                   1530:        default:
                   1531:                fatali("mkexpr: impossible opcode %d", opcode);
                   1532:        }
                   1533: 
                   1534: e = ALLOC(Exprblock);
                   1535: e->tag = TEXPR;
                   1536: e->opcode = opcode;
                   1537: e->vtype = etype;
                   1538: e->leftp = lp;
                   1539: e->rightp = rp;
                   1540: if(ltag==TCONST && (rp==0 || rtag==TCONST) )
                   1541:        e = fold(e);
                   1542: return(e);
                   1543: 
                   1544: retleft:
                   1545:        frexpr(rp);
                   1546:        return(lp);
                   1547: 
                   1548: retright:
                   1549:        frexpr(lp);
                   1550:        return(rp);
                   1551: 
                   1552: error:
                   1553:        frexpr(lp);
                   1554:        if(rp && opcode!=OPCALL && opcode!=OPCCALL)
                   1555:                frexpr(rp);
                   1556:        return( errnode() );
                   1557: }
                   1558: 
                   1559: #define ERR(s)   { errs = s; goto error; }
                   1560: 
                   1561: cktype(op, lt, rt)
                   1562: register int op, lt, rt;
                   1563: {
                   1564: char *errs;
                   1565: 
                   1566: if(lt==TYERROR || rt==TYERROR)
                   1567:        goto error1;
                   1568: 
                   1569: if(lt==TYUNKNOWN)
                   1570:        return(TYUNKNOWN);
                   1571: if(rt==TYUNKNOWN)
                   1572:        if(op!=OPNOT && op!=OPBITNOT && op!=OPNEG && op!=OPCALL && op!=OPCCALL && op!=OPADDR)
                   1573:                return(TYUNKNOWN);
                   1574: 
                   1575: switch(op)
                   1576:        {
                   1577:        case OPPLUS:
                   1578:        case OPMINUS:
                   1579:        case OPSTAR:
                   1580:        case OPSLASH:
                   1581:        case OPPOWER:
                   1582:        case OPMOD:
                   1583:                if( ISNUMERIC(lt) && ISNUMERIC(rt) )
                   1584:                        return( maxtype(lt, rt) );
                   1585:                ERR("nonarithmetic operand of arithmetic operator")
                   1586: 
                   1587:        case OPNEG:
                   1588:                if( ISNUMERIC(lt) )
                   1589:                        return(lt);
                   1590:                ERR("nonarithmetic operand of negation")
                   1591: 
                   1592:        case OPNOT:
                   1593:                if(lt == TYLOGICAL)
                   1594:                        return(TYLOGICAL);
                   1595:                ERR("NOT of nonlogical")
                   1596: 
                   1597:        case OPAND:
                   1598:        case OPOR:
                   1599:        case OPEQV:
                   1600:        case OPNEQV:
                   1601:                if(lt==TYLOGICAL && rt==TYLOGICAL)
                   1602:                        return(TYLOGICAL);
                   1603:                ERR("nonlogical operand of logical operator")
                   1604: 
                   1605:        case OPLT:
                   1606:        case OPGT:
                   1607:        case OPLE:
                   1608:        case OPGE:
                   1609:        case OPEQ:
                   1610:        case OPNE:
                   1611:                if(lt==TYCHAR || rt==TYCHAR || lt==TYLOGICAL || rt==TYLOGICAL)
                   1612:                        {
                   1613:                        if(lt != rt)
                   1614:                                ERR("illegal comparison")
                   1615:                        }
                   1616: 
                   1617:                else if( ISCOMPLEX(lt) || ISCOMPLEX(rt) )
                   1618:                        {
                   1619:                        if(op!=OPEQ && op!=OPNE)
                   1620:                                ERR("order comparison of complex data")
                   1621:                        }
                   1622: 
                   1623:                else if( ! ISNUMERIC(lt) || ! ISNUMERIC(rt) )
                   1624:                        ERR("comparison of nonarithmetic data")
                   1625:                return(TYLOGICAL);
                   1626: 
                   1627:        case OPCONCAT:
                   1628:                if(lt==TYCHAR && rt==TYCHAR)
                   1629:                        return(TYCHAR);
                   1630:                ERR("concatenation of nonchar data")
                   1631: 
                   1632:        case OPCALL:
                   1633:        case OPCCALL:
                   1634:                return(lt);
                   1635: 
                   1636:        case OPADDR:
                   1637:                return(TYADDR);
                   1638: 
                   1639:        case OPCONV:
                   1640:                if(rt == 0)
                   1641:                        return(0);
                   1642:                if(lt==TYCHAR && ISINT(rt) )
                   1643:                        return(TYCHAR);
                   1644:        case OPASSIGN:
                   1645:        case OPPLUSEQ:
                   1646:        case OPSTAREQ:
                   1647:                if( ISINT(lt) && rt==TYCHAR)
                   1648:                        return(lt);
                   1649:                if(lt==TYCHAR || rt==TYCHAR || lt==TYLOGICAL || rt==TYLOGICAL)
                   1650:                        if(op!=OPASSIGN || lt!=rt)
                   1651:                                {
                   1652: /* debug fprintf(diagfile, " lt=%d, rt=%d, op=%d\n", lt, rt, op); */
                   1653: /* debug fatal("impossible conversion.  possible compiler bug"); */
                   1654:                                ERR("impossible conversion")
                   1655:                                }
                   1656:                return(lt);
                   1657: 
                   1658:        case OPMIN:
                   1659:        case OPMAX:
                   1660:        case OPBITOR:
                   1661:        case OPBITAND:
                   1662:        case OPBITXOR:
                   1663:        case OPBITNOT:
                   1664:        case OPLSHIFT:
                   1665:        case OPRSHIFT:
                   1666:                return(lt);
                   1667: 
                   1668:        case OPCOMMA:
                   1669:        case OPQUEST:
                   1670:        case OPCOLON:
                   1671:                return(rt);
                   1672: 
                   1673:        default:
                   1674:                fatali("cktype: impossible opcode %d", op);
                   1675:        }
                   1676: error: err(errs);
                   1677: error1:        return(TYERROR);
                   1678: }
                   1679: 
                   1680: LOCAL expptr fold(e)
                   1681: register struct Exprblock *e;
                   1682: {
                   1683: struct Constblock *p;
                   1684: #ifdef VERSION6
                   1685:        expptr lp, rp;
                   1686: #else
                   1687:        register expptr lp, rp;
                   1688: #endif
                   1689: int etype, mtype, ltype, rtype, opcode;
                   1690: int i, ll, lr;
                   1691: char *q, *s;
                   1692: union Constant lcon, rcon;
                   1693: 
                   1694: opcode = e->opcode;
                   1695: etype = e->vtype;
                   1696: 
                   1697: lp = e->leftp;
                   1698: ltype = lp->headblock.vtype;
                   1699: rp = e->rightp;
                   1700: 
                   1701: if(rp == 0)
                   1702:        switch(opcode)
                   1703:                {
                   1704:                case OPNOT:
                   1705:                        lp->constblock.const.ci = ! lp->constblock.const.ci;
                   1706:                        return(lp);
                   1707: 
                   1708:                case OPBITNOT:
                   1709:                        lp->constblock.const.ci = ~ lp->constblock.const.ci;
                   1710:                        return(lp);
                   1711: 
                   1712:                case OPNEG:
                   1713:                        consnegop(lp);
                   1714:                        return(lp);
                   1715: 
                   1716:                case OPCONV:
                   1717:                case OPADDR:
                   1718:                        return(e);
                   1719: 
                   1720:                default:
                   1721:                        fatali("fold: invalid unary operator %d", opcode);
                   1722:                }
                   1723: 
                   1724: rtype = rp->headblock.vtype;
                   1725: 
                   1726: p = ALLOC(Constblock);
                   1727: p->tag = TCONST;
                   1728: p->vtype = etype;
                   1729: p->vleng = e->vleng;
                   1730: 
                   1731: switch(opcode)
                   1732:        {
                   1733:        case OPCOMMA:
                   1734:        case OPQUEST:
                   1735:        case OPCOLON:
                   1736:                return(e);
                   1737: 
                   1738:        case OPAND:
                   1739:                p->const.ci = lp->constblock.const.ci &&
                   1740:                                rp->constblock.const.ci;
                   1741:                break;
                   1742: 
                   1743:        case OPOR:
                   1744:                p->const.ci = lp->constblock.const.ci ||
                   1745:                                rp->constblock.const.ci;
                   1746:                break;
                   1747: 
                   1748:        case OPEQV:
                   1749:                p->const.ci = lp->constblock.const.ci ==
                   1750:                                rp->constblock.const.ci;
                   1751:                break;
                   1752: 
                   1753:        case OPNEQV:
                   1754:                p->const.ci = lp->constblock.const.ci !=
                   1755:                                rp->constblock.const.ci;
                   1756:                break;
                   1757: 
                   1758:        case OPBITAND:
                   1759:                p->const.ci = lp->constblock.const.ci &
                   1760:                                rp->constblock.const.ci;
                   1761:                break;
                   1762: 
                   1763:        case OPBITOR:
                   1764:                p->const.ci = lp->constblock.const.ci |
                   1765:                                rp->constblock.const.ci;
                   1766:                break;
                   1767: 
                   1768:        case OPBITXOR:
                   1769:                p->const.ci = lp->constblock.const.ci ^
                   1770:                                rp->constblock.const.ci;
                   1771:                break;
                   1772: 
                   1773:        case OPLSHIFT:
                   1774:                p->const.ci = lp->constblock.const.ci <<
                   1775:                                rp->constblock.const.ci;
                   1776:                break;
                   1777: 
                   1778:        case OPRSHIFT:
                   1779:                p->const.ci = lp->constblock.const.ci >>
                   1780:                                rp->constblock.const.ci;
                   1781:                break;
                   1782: 
                   1783:        case OPCONCAT:
                   1784:                ll = lp->constblock.vleng->constblock.const.ci;
                   1785:                lr = rp->constblock.vleng->constblock.const.ci;
                   1786:                p->const.ccp = q = (char *) ckalloc(ll+lr);
                   1787:                p->vleng = ICON(ll+lr);
                   1788:                s = lp->constblock.const.ccp;
                   1789:                for(i = 0 ; i < ll ; ++i)
                   1790:                        *q++ = *s++;
                   1791:                s = rp->constblock.const.ccp;
                   1792:                for(i = 0; i < lr; ++i)
                   1793:                        *q++ = *s++;
                   1794:                break;
                   1795: 
                   1796: 
                   1797:        case OPPOWER:
                   1798:                if( ! ISINT(rtype) )
                   1799:                        return(e);
                   1800:                conspower(&(p->const), lp, rp->constblock.const.ci);
                   1801:                break;
                   1802: 
                   1803: 
                   1804:        default:
                   1805:                if(ltype == TYCHAR)
                   1806:                        {
                   1807:                        lcon.ci = cmpstr(lp->constblock.const.ccp,
                   1808:                                        rp->constblock.const.ccp,
                   1809:                                        lp->constblock.vleng->constblock.const.ci,
                   1810:                                        rp->constblock.vleng->constblock.const.ci);
                   1811:                        rcon.ci = 0;
                   1812:                        mtype = tyint;
                   1813:                        }
                   1814:                else    {
                   1815:                        mtype = maxtype(ltype, rtype);
                   1816:                        consconv(mtype, &lcon, ltype, &(lp->constblock.const) );
                   1817:                        consconv(mtype, &rcon, rtype, &(rp->constblock.const) );
                   1818:                        }
                   1819:                consbinop(opcode, mtype, &(p->const), &lcon, &rcon);
                   1820:                break;
                   1821:        }
                   1822: 
                   1823: frexpr(e);
                   1824: return(p);
                   1825: }
                   1826: 
                   1827: 
                   1828: 
                   1829: /* assign constant l = r , doing coercion */
                   1830: 
                   1831: consconv(lt, lv, rt, rv)
                   1832: int lt, rt;
                   1833: register union Constant *lv, *rv;
                   1834: {
                   1835: switch(lt)
                   1836:        {
                   1837:        case TYCHAR:
                   1838:                *(lv->ccp = ckalloc(1)) = rv->ci;
                   1839:                break;
                   1840: 
                   1841:        case TYSHORT:
                   1842:        case TYLONG:
                   1843:                if(rt == TYCHAR)
                   1844:                        lv->ci = rv->ccp[0];
                   1845:                else if( ISINT(rt) )
                   1846:                        lv->ci = rv->ci;
                   1847:                else    lv->ci = rv->cd[0];
                   1848:                break;
                   1849: 
                   1850:        case TYCOMPLEX:
                   1851:        case TYDCOMPLEX:
                   1852:                switch(rt)
                   1853:                        {
                   1854:                        case TYSHORT:
                   1855:                        case TYLONG:
                   1856:                                /* fall through and do real assignment of
                   1857:                                   first element
                   1858:                                */
                   1859:                        case TYREAL:
                   1860:                        case TYDREAL:
                   1861:                                lv->cd[1] = 0; break;
                   1862:                        case TYCOMPLEX:
                   1863:                        case TYDCOMPLEX:
                   1864:                                lv->cd[1] = rv->cd[1]; break;
                   1865:                        }
                   1866: 
                   1867:        case TYREAL:
                   1868:        case TYDREAL:
                   1869:                if( ISINT(rt) )
                   1870:                        lv->cd[0] = rv->ci;
                   1871:                else    lv->cd[0] = rv->cd[0];
                   1872:                break;
                   1873: 
                   1874:        case TYLOGICAL:
                   1875:                lv->ci = rv->ci;
                   1876:                break;
                   1877:        }
                   1878: }
                   1879: 
                   1880: 
                   1881: 
                   1882: consnegop(p)
                   1883: register struct Constblock *p;
                   1884: {
                   1885: switch(p->vtype)
                   1886:        {
                   1887:        case TYSHORT:
                   1888:        case TYLONG:
                   1889:                p->const.ci = - p->const.ci;
                   1890:                break;
                   1891: 
                   1892:        case TYCOMPLEX:
                   1893:        case TYDCOMPLEX:
                   1894:                p->const.cd[1] = - p->const.cd[1];
                   1895:                /* fall through and do the real parts */
                   1896:        case TYREAL:
                   1897:        case TYDREAL:
                   1898:                p->const.cd[0] = - p->const.cd[0];
                   1899:                break;
                   1900:        default:
                   1901:                fatali("consnegop: impossible type %d", p->vtype);
                   1902:        }
                   1903: }
                   1904: 
                   1905: 
                   1906: 
                   1907: LOCAL conspower(powp, ap, n)
                   1908: register union Constant *powp;
                   1909: struct Constblock *ap;
                   1910: ftnint n;
                   1911: {
                   1912: register int type;
                   1913: union Constant x;
                   1914: 
                   1915: switch(type = ap->vtype)       /* pow = 1 */ 
                   1916:        {
                   1917:        case TYSHORT:
                   1918:        case TYLONG:
                   1919:                powp->ci = 1;
                   1920:                break;
                   1921:        case TYCOMPLEX:
                   1922:        case TYDCOMPLEX:
                   1923:                powp->cd[1] = 0;
                   1924:        case TYREAL:
                   1925:        case TYDREAL:
                   1926:                powp->cd[0] = 1;
                   1927:                break;
                   1928:        default:
                   1929:                fatali("conspower: invalid type %d", type);
                   1930:        }
                   1931: 
                   1932: if(n == 0)
                   1933:        return;
                   1934: if(n < 0)
                   1935:        {
                   1936:        if( ISINT(type) )
                   1937:                {
                   1938:                err("integer ** negative power ");
                   1939:                return;
                   1940:                }
                   1941:        n = - n;
                   1942:        consbinop(OPSLASH, type, &x, powp, &(ap->const));
                   1943:        }
                   1944: else
                   1945:        consbinop(OPSTAR, type, &x, powp, &(ap->const));
                   1946: 
                   1947: for( ; ; )
                   1948:        {
                   1949:        if(n & 01)
                   1950:                consbinop(OPSTAR, type, powp, powp, &x);
                   1951:        if(n >>= 1)
                   1952:                consbinop(OPSTAR, type, &x, &x, &x);
                   1953:        else
                   1954:                break;
                   1955:        }
                   1956: }
                   1957: 
                   1958: 
                   1959: 
                   1960: /* do constant operation cp = a op b */
                   1961: 
                   1962: 
                   1963: LOCAL consbinop(opcode, type, cp, ap, bp)
                   1964: int opcode, type;
                   1965: register union Constant *ap, *bp, *cp;
                   1966: {
                   1967: int k;
                   1968: double temp;
                   1969: 
                   1970: switch(opcode)
                   1971:        {
                   1972:        case OPPLUS:
                   1973:                switch(type)
                   1974:                        {
                   1975:                        case TYSHORT:
                   1976:                        case TYLONG:
                   1977:                                cp->ci = ap->ci + bp->ci;
                   1978:                                break;
                   1979:                        case TYCOMPLEX:
                   1980:                        case TYDCOMPLEX:
                   1981:                                cp->cd[1] = ap->cd[1] + bp->cd[1];
                   1982:                        case TYREAL:
                   1983:                        case TYDREAL:
                   1984:                                cp->cd[0] = ap->cd[0] + bp->cd[0];
                   1985:                                break;
                   1986:                        }
                   1987:                break;
                   1988: 
                   1989:        case OPMINUS:
                   1990:                switch(type)
                   1991:                        {
                   1992:                        case TYSHORT:
                   1993:                        case TYLONG:
                   1994:                                cp->ci = ap->ci - bp->ci;
                   1995:                                break;
                   1996:                        case TYCOMPLEX:
                   1997:                        case TYDCOMPLEX:
                   1998:                                cp->cd[1] = ap->cd[1] - bp->cd[1];
                   1999:                        case TYREAL:
                   2000:                        case TYDREAL:
                   2001:                                cp->cd[0] = ap->cd[0] - bp->cd[0];
                   2002:                                break;
                   2003:                        }
                   2004:                break;
                   2005: 
                   2006:        case OPSTAR:
                   2007:                switch(type)
                   2008:                        {
                   2009:                        case TYSHORT:
                   2010:                        case TYLONG:
                   2011:                                cp->ci = ap->ci * bp->ci;
                   2012:                                break;
                   2013:                        case TYREAL:
                   2014:                        case TYDREAL:
                   2015:                                cp->cd[0] = ap->cd[0] * bp->cd[0];
                   2016:                                break;
                   2017:                        case TYCOMPLEX:
                   2018:                        case TYDCOMPLEX:
                   2019:                                temp = ap->cd[0] * bp->cd[0] -
                   2020:                                            ap->cd[1] * bp->cd[1] ;
                   2021:                                cp->cd[1] = ap->cd[0] * bp->cd[1] +
                   2022:                                            ap->cd[1] * bp->cd[0] ;
                   2023:                                cp->cd[0] = temp;
                   2024:                                break;
                   2025:                        }
                   2026:                break;
                   2027:        case OPSLASH:
                   2028:                switch(type)
                   2029:                        {
                   2030:                        case TYSHORT:
                   2031:                        case TYLONG:
                   2032:                                cp->ci = ap->ci / bp->ci;
                   2033:                                break;
                   2034:                        case TYREAL:
                   2035:                        case TYDREAL:
                   2036:                                cp->cd[0] = ap->cd[0] / bp->cd[0];
                   2037:                                break;
                   2038:                        case TYCOMPLEX:
                   2039:                        case TYDCOMPLEX:
                   2040:                                zdiv(cp,ap,bp);
                   2041:                                break;
                   2042:                        }
                   2043:                break;
                   2044: 
                   2045:        case OPMOD:
                   2046:                if( ISINT(type) )
                   2047:                        {
                   2048:                        cp->ci = ap->ci % bp->ci;
                   2049:                        break;
                   2050:                        }
                   2051:                else
                   2052:                        fatal("inline mod of noninteger");
                   2053: 
                   2054:        default:          /* relational ops */
                   2055:                switch(type)
                   2056:                        {
                   2057:                        case TYSHORT:
                   2058:                        case TYLONG:
                   2059:                                if(ap->ci < bp->ci)
                   2060:                                        k = -1;
                   2061:                                else if(ap->ci == bp->ci)
                   2062:                                        k = 0;
                   2063:                                else    k = 1;
                   2064:                                break;
                   2065:                        case TYREAL:
                   2066:                        case TYDREAL:
                   2067:                                if(ap->cd[0] < bp->cd[0])
                   2068:                                        k = -1;
                   2069:                                else if(ap->cd[0] == bp->cd[0])
                   2070:                                        k = 0;
                   2071:                                else    k = 1;
                   2072:                                break;
                   2073:                        case TYCOMPLEX:
                   2074:                        case TYDCOMPLEX:
                   2075:                                if(ap->cd[0] == bp->cd[0] &&
                   2076:                                   ap->cd[1] == bp->cd[1] )
                   2077:                                        k = 0;
                   2078:                                else    k = 1;
                   2079:                                break;
                   2080:                        }
                   2081: 
                   2082:                switch(opcode)
                   2083:                        {
                   2084:                        case OPEQ:
                   2085:                                cp->ci = (k == 0);
                   2086:                                break;
                   2087:                        case OPNE:
                   2088:                                cp->ci = (k != 0);
                   2089:                                break;
                   2090:                        case OPGT:
                   2091:                                cp->ci = (k == 1);
                   2092:                                break;
                   2093:                        case OPLT:
                   2094:                                cp->ci = (k == -1);
                   2095:                                break;
                   2096:                        case OPGE:
                   2097:                                cp->ci = (k >= 0);
                   2098:                                break;
                   2099:                        case OPLE:
                   2100:                                cp->ci = (k <= 0);
                   2101:                                break;
                   2102:                        }
                   2103:                break;
                   2104:        }
                   2105: }
                   2106: 
                   2107: 
                   2108: 
                   2109: 
                   2110: conssgn(p)
                   2111: register expptr p;
                   2112: {
                   2113: if( ! ISCONST(p) )
                   2114:        fatal( "sgn(nonconstant)" );
                   2115: 
                   2116: switch(p->headblock.vtype)
                   2117:        {
                   2118:        case TYSHORT:
                   2119:        case TYLONG:
                   2120:                if(p->constblock.const.ci > 0) return(1);
                   2121:                if(p->constblock.const.ci < 0) return(-1);
                   2122:                return(0);
                   2123: 
                   2124:        case TYREAL:
                   2125:        case TYDREAL:
                   2126:                if(p->constblock.const.cd[0] > 0) return(1);
                   2127:                if(p->constblock.const.cd[0] < 0) return(-1);
                   2128:                return(0);
                   2129: 
                   2130:        case TYCOMPLEX:
                   2131:        case TYDCOMPLEX:
                   2132:                return(p->constblock.const.cd[0]!=0 || p->constblock.const.cd[1]!=0);
                   2133: 
                   2134:        default:
                   2135:                fatali( "conssgn(type %d)", p->constblock.vtype);
                   2136:        }
                   2137: /* NOTREACHED */
                   2138: }
                   2139: 
                   2140: char *powint[ ] = { "pow_ii", "pow_ri", "pow_di", "pow_ci", "pow_zi" };
                   2141: 
                   2142: 
                   2143: LOCAL expptr mkpower(p)
                   2144: register struct Exprblock *p;
                   2145: {
                   2146: register expptr q, lp, rp;
                   2147: int ltype, rtype, mtype;
                   2148: 
                   2149: lp = p->leftp;
                   2150: rp = p->rightp;
                   2151: ltype = lp->headblock.vtype;
                   2152: rtype = rp->headblock.vtype;
                   2153: 
                   2154: if(ISICON(rp))
                   2155:        {
                   2156:        if(rp->constblock.const.ci == 0)
                   2157:                {
                   2158:                frexpr(p);
                   2159:                if( ISINT(ltype) )
                   2160:                        return( ICON(1) );
                   2161:                else
                   2162:                        return( putconst( mkconv(ltype, ICON(1))) );
                   2163:                }
                   2164:        if(rp->constblock.const.ci < 0)
                   2165:                {
                   2166:                if( ISINT(ltype) )
                   2167:                        {
                   2168:                        frexpr(p);
                   2169:                        err("integer**negative");
                   2170:                        return( errnode() );
                   2171:                        }
                   2172:                rp->constblock.const.ci = - rp->constblock.const.ci;
                   2173:                p->leftp = lp = fixexpr(mkexpr(OPSLASH, ICON(1), lp));
                   2174:                }
                   2175:        if(rp->constblock.const.ci == 1)
                   2176:                {
                   2177:                frexpr(rp);
                   2178:                free(p);
                   2179:                return(lp);
                   2180:                }
                   2181: 
                   2182:        if( ONEOF(ltype, MSKINT|MSKREAL) )
                   2183:                {
                   2184:                p->vtype = ltype;
                   2185:                return(p);
                   2186:                }
                   2187:        }
                   2188: if( ISINT(rtype) )
                   2189:        {
                   2190:        if(ltype==TYSHORT && rtype==TYSHORT && (!ISCONST(lp) || tyint==TYSHORT) )
                   2191:                q = call2(TYSHORT, "pow_hh", lp, rp);
                   2192:        else    {
                   2193:                if(ltype == TYSHORT)
                   2194:                        {
                   2195:                        ltype = TYLONG;
                   2196:                        lp = mkconv(TYLONG,lp);
                   2197:                        }
                   2198:                q = call2(ltype, powint[ltype-TYLONG], lp, mkconv(TYLONG, rp));
                   2199:                }
                   2200:        }
                   2201: else if( ISREAL( (mtype = maxtype(ltype,rtype)) ))
                   2202:        q = call2(mtype, "pow_dd",
                   2203:                mkconv(TYDREAL,lp), mkconv(TYDREAL,rp));
                   2204: else   {
                   2205:        q = call2(TYDCOMPLEX, "pow_zz",
                   2206:                mkconv(TYDCOMPLEX,lp), mkconv(TYDCOMPLEX,rp));
                   2207:        if(mtype == TYCOMPLEX)
                   2208:                q = mkconv(TYCOMPLEX, q);
                   2209:        }
                   2210: free(p);
                   2211: return(q);
                   2212: }
                   2213: 
                   2214: 
                   2215: 
                   2216: /* Complex Division.  Same code as in Runtime Library
                   2217: */
                   2218: 
                   2219: struct dcomplex { double dreal, dimag; };
                   2220: 
                   2221: 
                   2222: LOCAL zdiv(c, a, b)
                   2223: register struct dcomplex *a, *b, *c;
                   2224: {
                   2225: double ratio, den;
                   2226: double abr, abi;
                   2227: 
                   2228: if( (abr = b->dreal) < 0.)
                   2229:        abr = - abr;
                   2230: if( (abi = b->dimag) < 0.)
                   2231:        abi = - abi;
                   2232: if( abr <= abi )
                   2233:        {
                   2234:        if(abi == 0)
                   2235:                fatal("complex division by zero");
                   2236:        ratio = b->dreal / b->dimag ;
                   2237:        den = b->dimag * (1 + ratio*ratio);
                   2238:        c->dreal = (a->dreal*ratio + a->dimag) / den;
                   2239:        c->dimag = (a->dimag*ratio - a->dreal) / den;
                   2240:        }
                   2241: 
                   2242: else
                   2243:        {
                   2244:        ratio = b->dimag / b->dreal ;
                   2245:        den = b->dreal * (1 + ratio*ratio);
                   2246:        c->dreal = (a->dreal + a->dimag*ratio) / den;
                   2247:        c->dimag = (a->dimag - a->dreal*ratio) / den;
                   2248:        }
                   2249: 
                   2250: }

unix.superglobalmegacorp.com

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