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

Defined functions

cktype defined in line 1536; used 5 times
consbinop defined in line 1927; used 5 times
consconv defined in line 1795; used 4 times
consnegop defined in line 1846; used 2 times
conspower defined in line 1871; used 1 times
conssgn defined in line 2074; used 2 times
cpexpr defined in line 207; used 177 times
deregister defined in line 933; used 1 times
enregister defined in line 977; used 1 times
errnode defined in line 135; used 12 times
fixargs defined in line 607; used 2 times
fold defined in line 1655; used 2 times
impldcl defined in line 1270; used 5 times
inregister defined in line 963; used 3 times
letter defined in line 1298; used 2 times
memversion defined in line 948; used 4 times
mkaddcon defined in line 45; used 6 times
mkaddr defined in line 1118; used 7 times
mkarg defined in line 1170; used 2 times
mkbitcon defined in line 69; never used
mkconst defined in line 5; used 8 times
mkcxcon defined in line 104; used 2 times
mkexpr defined in line 1310; used 143 times
mkfunct defined in line 675; used 3 times
mkintcon defined in line 29; used 4 times
mklhs defined in line 852; used 11 times
mklogcon defined in line 17; never used
mkpower defined in line 2107; used 2 times
mkprim defined in line 1187; used 9 times
mkrealcon defined in line 57; used 4 times
mkscalar defined in line 646; used 5 times
mkstrcon defined in line 88; used 8 times
opconv defined in line 186; used 4 times
shorten defined in line 544; used 7 times
stfcall defined in line 770; used 2 times
subcheck defined in line 1064; used 2 times
suboffset defined in line 1002; used 4 times
vardcl defined in line 1220; used 9 times
zdiv defined in line 2186; used 1 times

Defined variables

args defined in line 1189; used 4 times
lstr defined in line 1190; used 4 times
powint defined in line 2104; used 1 times
rstr defined in line 1190; used 4 times
v defined in line 1188; used 33 times

Defined struct's

dcomplex defined in line 2183; used 2 times

Defined macros

COMMUTE defined in line 1307; used 3 times
ERR defined in line 1534; used 9 times
ICONEQ defined in line 1306; used 2 times
Last modified: 1979-05-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4517
Valid CSS Valid XHTML 1.0 Strict