1: #include "defs"
   2: 
   3: /* start a new procedure */
   4: 
   5: newproc()
   6: {
   7: if(parstate != OUTSIDE)
   8:     {
   9:     execerr("missing end statement", 0);
  10:     endproc();
  11:     }
  12: 
  13: parstate = INSIDE;
  14: procclass = CLMAIN; /* default */
  15: }
  16: 
  17: 
  18: 
  19: /* end of procedure. generate variables, epilogs, and prologs */
  20: 
  21: endproc()
  22: {
  23: struct labelblock *lp;
  24: 
  25: if(parstate < INDATA)
  26:     enddcl();
  27: if(ctlstack >= ctls)
  28:     err("DO loop or BLOCK IF not closed");
  29: for(lp = labeltab ; lp < labtabend ; ++lp)
  30:     if(lp->stateno!=0 && lp->labdefined==NO)
  31:         err1("missing statement number %s", convic(lp->stateno) );
  32: 
  33: epicode();
  34: procode();
  35: dobss();
  36: prdbginfo();
  37: 
  38: #if FAMILY == SCJ
  39:     putbracket();
  40: #endif
  41: 
  42: procinit(); /* clean up for next procedure */
  43: }
  44: 
  45: 
  46: 
  47: /* End of declaration section of procedure.  Allocate storage. */
  48: 
  49: enddcl()
  50: {
  51: register struct entrypoint *p;
  52: 
  53: parstate = INEXEC;
  54: docommon();
  55: doequiv();
  56: docomleng();
  57: for(p = entries ; p ; p = p->nextp)
  58:     doentry(p);
  59: }
  60: 
  61: /* ROUTINES CALLED WHEN ENCOUNTERING ENTRY POINTS */
  62: 
  63: /* Main program or Block data */
  64: 
  65: startproc(progname, class)
  66: struct extsym * progname;
  67: int class;
  68: {
  69: register struct entrypoint *p;
  70: 
  71: p = ALLOC(entrypoint);
  72: if(class == CLMAIN)
  73:     puthead("MAIN__", CLMAIN);
  74: else
  75:     puthead(NULL, CLBLOCK);
  76: if(class == CLMAIN)
  77:     newentry( mkname(5, "MAIN_") );
  78: p->entryname = progname;
  79: p->entrylabel = newlabel();
  80: entries = p;
  81: 
  82: procclass = class;
  83: retlabel = newlabel();
  84: fprintf(diagfile, "   %s", (class==CLMAIN ? "MAIN" : "BLOCK DATA") );
  85: if(progname)
  86:     fprintf(diagfile, " %s", nounder(XL, procname = progname->extname) );
  87: fprintf(diagfile, ":\n");
  88: }
  89: 
  90: /* subroutine or function statement */
  91: 
  92: struct extsym *newentry(v)
  93: register struct nameblock *v;
  94: {
  95: register struct extsym *p;
  96: struct extsym *mkext();
  97: 
  98: p = mkext( varunder(VL, v->varname) );
  99: 
 100: if(p==NULL || p->extinit || ! ONEOF(p->extstg, M(STGUNKNOWN)|M(STGEXT)) )
 101:     {
 102:     if(p == 0)
 103:         dclerr("invalid entry name", v);
 104:     else    dclerr("external name already used", v);
 105:     return(0);
 106:     }
 107: v->vstg = STGAUTO;
 108: v->vprocclass = PTHISPROC;
 109: v->vclass = CLPROC;
 110: p->extstg = STGEXT;
 111: p->extinit = YES;
 112: return(p);
 113: }
 114: 
 115: 
 116: entrypt(class, type, length, entry, args)
 117: int class, type;
 118: ftnint length;
 119: struct extsym *entry;
 120: chainp args;
 121: {
 122: register struct nameblock *q;
 123: register struct entrypoint *p;
 124: 
 125: if(class != CLENTRY)
 126:     puthead( varstr(XL, procname = entry->extname), class);
 127: if(class == CLENTRY)
 128:     fprintf(diagfile, "       entry ");
 129: fprintf(diagfile, "   %s:\n", nounder(XL, entry->extname));
 130: q = mkname(VL, nounder(XL,entry->extname) );
 131: 
 132: if( (type = lengtype(type, (int) length)) != TYCHAR)
 133:     length = 0;
 134: if(class == CLPROC)
 135:     {
 136:     procclass = CLPROC;
 137:     proctype = type;
 138:     procleng = length;
 139: 
 140:     retlabel = newlabel();
 141:     if(type == TYSUBR)
 142:         ret0label = newlabel();
 143:     }
 144: 
 145: p = ALLOC(entrypoint);
 146: entries = hookup(entries, p);
 147: p->entryname = entry;
 148: p->arglist = args;
 149: p->entrylabel = newlabel();
 150: p->enamep = q;
 151: 
 152: if(class == CLENTRY)
 153:     {
 154:     class = CLPROC;
 155:     if(proctype == TYSUBR)
 156:         type = TYSUBR;
 157:     }
 158: 
 159: q->vclass = class;
 160: q->vprocclass = PTHISPROC;
 161: settype(q, type, (int) length);
 162: /* hold all initial entry points till end of declarations */
 163: if(parstate >= INDATA)
 164:     doentry(p);
 165: }
 166: 
 167: /* generate epilogs */
 168: 
 169: LOCAL epicode()
 170: {
 171: register int i;
 172: 
 173: if(procclass==CLPROC)
 174:     {
 175:     if(proctype==TYSUBR)
 176:         {
 177:         putlabel(ret0label);
 178:         if(substars)
 179:             putforce(TYINT, ICON(0) );
 180:         putlabel(retlabel);
 181:         goret(TYSUBR);
 182:         }
 183:     else    {
 184:         putlabel(retlabel);
 185:         if(multitypes)
 186:             {
 187:             typeaddr = autovar(1, TYADDR, NULL);
 188:             putbranch( cpexpr(typeaddr) );
 189:             for(i = 0; i < NTYPES ; ++i)
 190:                 if(rtvlabel[i] != 0)
 191:                     {
 192:                     putlabel(rtvlabel[i]);
 193:                     retval(i);
 194:                     }
 195:             }
 196:         else
 197:             retval(proctype);
 198:         }
 199:     }
 200: 
 201: else if(procclass != CLBLOCK)
 202:     {
 203:     putlabel(retlabel);
 204:     goret(TYSUBR);
 205:     }
 206: }
 207: 
 208: 
 209: /* generate code to return value of type  t */
 210: 
 211: LOCAL retval(t)
 212: register int t;
 213: {
 214: register struct addrblock *p;
 215: 
 216: switch(t)
 217:     {
 218:     case TYCHAR:
 219:     case TYCOMPLEX:
 220:     case TYDCOMPLEX:
 221:         break;
 222: 
 223:     case TYLOGICAL:
 224:         t = tylogical;
 225:     case TYADDR:
 226:     case TYSHORT:
 227:     case TYLONG:
 228:         p = cpexpr(retslot);
 229:         p->vtype = t;
 230:         putforce(t, p);
 231:         break;
 232: 
 233:     case TYREAL:
 234:     case TYDREAL:
 235:         p = cpexpr(retslot);
 236:         p->vtype = t;
 237:         putforce(t, p);
 238:         break;
 239: 
 240:     default:
 241:         fatal1("retval: impossible type %d", t);
 242:     }
 243: goret(t);
 244: }
 245: 
 246: 
 247: /* Allocate extra argument array if needed. Generate prologs. */
 248: 
 249: LOCAL procode()
 250: {
 251: register struct entrypoint *p;
 252: struct addrblock *argvec;
 253: 
 254: #if TARGET==GCOS
 255:     argvec = autovar(lastargslot/SZADDR, TYADDR, NULL);
 256: #else
 257:     if(lastargslot>0 && nentry>1)
 258:         argvec = autovar(lastargslot/SZADDR, TYADDR, NULL);
 259:     else
 260:         argvec = NULL;
 261: #endif
 262: 
 263: 
 264: #if TARGET == PDP11
 265:     /* for the optimizer */
 266:     if(fudgelabel)
 267:         putlabel(fudgelabel);
 268: #endif
 269: 
 270: for(p = entries ; p ; p = p->nextp)
 271:     prolog(p, argvec);
 272: 
 273: #if FAMILY == SCJ
 274:     putrbrack(procno);
 275: #endif
 276: 
 277: prendproc();
 278: }
 279: 
 280: /*
 281:    manipulate argument lists (allocate argument slot positions)
 282:  * keep track of return types and labels
 283:  */
 284: 
 285: LOCAL doentry(ep)
 286: struct entrypoint *ep;
 287: {
 288: register int type;
 289: register struct nameblock *np;
 290: chainp p;
 291: register struct nameblock *q;
 292: 
 293: ++nentry;
 294: if(procclass == CLMAIN)
 295:     {
 296:     putlabel(ep->entrylabel);
 297:     return;
 298:     }
 299: else if(procclass == CLBLOCK)
 300:     return;
 301: 
 302: impldcl( np = mkname(VL, nounder(XL, ep->entryname->extname) ) );
 303: type = np->vtype;
 304: if(proctype == TYUNKNOWN)
 305:     if( (proctype = type) == TYCHAR)
 306:         procleng = (np->vleng ? np->vleng->const.ci : (ftnint) 0);
 307: 
 308: if(proctype == TYCHAR)
 309:     {
 310:     if(type != TYCHAR)
 311:         err("noncharacter entry of character function");
 312:     else if( (np->vleng ? np->vleng->const.ci : (ftnint) 0) != procleng)
 313:         err("mismatched character entry lengths");
 314:     }
 315: else if(type == TYCHAR)
 316:     err("character entry of noncharacter function");
 317: else if(type != proctype)
 318:     multitype = YES;
 319: if(rtvlabel[type] == 0)
 320:     rtvlabel[type] = newlabel();
 321: ep->typelabel = rtvlabel[type];
 322: 
 323: if(type == TYCHAR)
 324:     {
 325:     if(chslot < 0)
 326:         {
 327:         chslot = nextarg(TYADDR);
 328:         chlgslot = nextarg(TYLENG);
 329:         }
 330:     np->vstg = STGARG;
 331:     np->vardesc.varno = chslot;
 332:     if(procleng == 0)
 333:         np->vleng = mkarg(TYLENG, chlgslot);
 334:     }
 335: else if( ISCOMPLEX(type) )
 336:     {
 337:     np->vstg = STGARG;
 338:     if(cxslot < 0)
 339:         cxslot = nextarg(TYADDR);
 340:     np->vardesc.varno = cxslot;
 341:     }
 342: else if(type != TYSUBR)
 343:     {
 344:     if(nentry == 1)
 345:         retslot = autovar(1, TYDREAL, NULL);
 346:     np->vstg = STGAUTO;
 347:     np->voffset = retslot->memoffset->const.ci;
 348:     }
 349: 
 350: for(p = ep->arglist ; p ; p = p->nextp)
 351:     if(! ((q = p->datap)->vdcldone) )
 352:         q->vardesc.varno = nextarg(TYADDR);
 353: 
 354: for(p = ep->arglist ; p ; p = p->nextp)
 355:     if(! ((q = p->datap)->vdcldone) )
 356:         {
 357:         impldcl(q);
 358:         q->vdcldone = YES;
 359:         if(q->vtype == TYCHAR)
 360:             {
 361:             if(q->vleng == NULL)    /* character*(*) */
 362:                 q->vleng = mkarg(TYLENG, nextarg(TYLENG) );
 363:             else if(nentry == 1)
 364:                 nextarg(TYLENG);
 365:             }
 366:         else if(q->vclass==CLPROC && nentry==1)
 367:             nextarg(TYLENG) ;
 368:         }
 369: 
 370: putlabel(ep->entrylabel);
 371: }
 372: 
 373: 
 374: 
 375: LOCAL nextarg(type)
 376: int type;
 377: {
 378: int k;
 379: k = lastargslot;
 380: lastargslot += typesize[type];
 381: return(k);
 382: }
 383: 
 384: /* generate variable references */
 385: 
 386: LOCAL dobss()
 387: {
 388: register struct hashentry *p;
 389: register struct nameblock *q;
 390: register int i;
 391: int align;
 392: ftnint leng, iarrl, iarrlen();
 393: struct extsym *mkext();
 394: char *memname();
 395: 
 396: pruse(asmfile, USEBSS);
 397: 
 398: for(p = hashtab ; p<lasthash ; ++p)
 399:     if(q = p->varp)
 400:     {
 401:     if( (q->vclass==CLUNKNOWN && q->vstg!=STGARG) ||
 402:         (q->vclass==CLVAR && q->vstg==STGUNKNOWN) )
 403:         warn1("local variable %s never used", varstr(VL,q->varname) );
 404:     else if(q->vclass==CLVAR && q->vstg==STGBSS)
 405:         {
 406:         align = (q->vtype==TYCHAR ? ALILONG : typealign[q->vtype]);
 407:         if(bssleng % align != 0)
 408:             {
 409:             bssleng = roundup(bssleng, align);
 410:             preven(align);
 411:             }
 412:         prlocvar( memname(STGBSS, q->vardesc.varno), iarrl = iarrlen(q) );
 413:         bssleng += iarrl;
 414:         }
 415:     else if(q->vclass==CLPROC && q->vprocclass==PEXTERNAL && q->vstg!=STGARG)
 416:         mkext(varunder(VL, q->varname)) ->extstg = STGEXT;
 417: 
 418:     if(q->vclass==CLVAR && q->vstg!=STGARG)
 419:         {
 420:         if(q->vdim && !ISICON(q->vdim->nelt) )
 421:             dclerr("adjustable dimension on non-argument", q);
 422:         if(q->vtype==TYCHAR && (q->vleng==NULL || !ISICON(q->vleng)))
 423:             dclerr("adjustable leng on nonargument", q);
 424:         }
 425:     }
 426: 
 427: for(i = 0 ; i < nequiv ; ++i)
 428:     if(eqvclass[i].eqvinit==NO && (leng = eqvclass[i].eqvleng)!=0 )
 429:         {
 430:         bssleng = roundup(bssleng, ALIDOUBLE);
 431:         preven(ALIDOUBLE);
 432:         prlocvar( memname(STGEQUIV, i), leng);
 433:         bssleng += leng;
 434:         }
 435: }
 436: 
 437: 
 438: 
 439: 
 440: doext()
 441: {
 442: struct extsym *p;
 443: 
 444: for(p = extsymtab ; p<nextext ; ++p)
 445:     prext( varstr(XL, p->extname), p->maxleng, p->extinit);
 446: }
 447: 
 448: 
 449: 
 450: 
 451: ftnint iarrlen(q)
 452: register struct nameblock *q;
 453: {
 454: ftnint leng;
 455: 
 456: leng = typesize[q->vtype];
 457: if(leng <= 0)
 458:     return(-1);
 459: if(q->vdim)
 460:     if( ISICON(q->vdim->nelt) )
 461:         leng *= q->vdim->nelt->const.ci;
 462:     else    return(-1);
 463: if(q->vleng)
 464:     if( ISICON(q->vleng) )
 465:         leng *= q->vleng->const.ci;
 466:     else    return(-1);
 467: return(leng);
 468: }
 469: 
 470: LOCAL docommon()
 471: {
 472: register struct extsym *p;
 473: register chainp q;
 474: struct dimblock *t;
 475: expptr neltp;
 476: register struct nameblock *v;
 477: ftnint size;
 478: int type;
 479: 
 480: for(p = extsymtab ; p<nextext ; ++p)
 481:     if(p->extstg==STGCOMMON)
 482:         {
 483:         for(q = p->extp ; q ; q = q->nextp)
 484:             {
 485:             v = q->datap;
 486:             if(v->vdcldone == NO)
 487:                 vardcl(v);
 488:             type = v->vtype;
 489:             if(p->extleng % typealign[type] != 0)
 490:                 {
 491:                 dclerr("common alignment", v);
 492:                 p->extleng = roundup(p->extleng, typealign[type]);
 493:                 }
 494:             v->voffset = p->extleng;
 495:             v->vardesc.varno = p - extsymtab;
 496:             if(type == TYCHAR)
 497:                 size = v->vleng->const.ci;
 498:             else    size = typesize[type];
 499:             if(t = v->vdim)
 500:                 if( (neltp = t->nelt) && ISCONST(neltp) )
 501:                     size *= neltp->const.ci;
 502:                 else
 503:                     dclerr("adjustable array in common", v);
 504:             p->extleng += size;
 505:             }
 506: 
 507:         frchain( &(p->extp) );
 508:         }
 509: }
 510: 
 511: 
 512: 
 513: 
 514: 
 515: LOCAL docomleng()
 516: {
 517: register struct extsym *p;
 518: 
 519: for(p = extsymtab ; p < nextext ; ++p)
 520:     if(p->extstg == STGCOMMON)
 521:         {
 522:         if(p->maxleng!=0 && p->extleng!=0 && p->maxleng!=p->extleng &&
 523:             !eqn(XL,"_BLNK__ ",p->extname) )
 524:             warn1("incompatible lengths for common block %s",
 525:                 nounder(XL, p->extname) );
 526:         if(p->maxleng < p->extleng)
 527:             p->maxleng = p->extleng;
 528:         p->extleng = 0;
 529:     }
 530: }
 531: 
 532: 
 533: 
 534: 
 535: /* ROUTINES DEALING WITH AUTOMATIC AND TEMPORARY STORAGE */
 536: 
 537: frtemp(p)
 538: struct addrblock *p;
 539: {
 540: holdtemps = mkchain(p, holdtemps);
 541: }
 542: 
 543: 
 544: 
 545: 
 546: /* allocate an automatic variable slot */
 547: 
 548: struct addrblock *autovar(nelt, t, lengp)
 549: register int nelt, t;
 550: expptr lengp;
 551: {
 552: ftnint leng;
 553: register struct addrblock *q;
 554: 
 555: if(t == TYCHAR)
 556:     if( ISICON(lengp) )
 557:         leng = lengp->const.ci;
 558:     else    {
 559:         fatal("automatic variable of nonconstant length");
 560:         }
 561: else
 562:     leng = typesize[t];
 563: autoleng = roundup( autoleng, typealign[t]);
 564: 
 565: q = ALLOC(addrblock);
 566: q->tag = TADDR;
 567: q->vtype = t;
 568: if(t == TYCHAR)
 569:     q->vleng = ICON(leng);
 570: q->vstg = STGAUTO;
 571: q->ntempelt = nelt;
 572: #if TARGET==PDP11 || TARGET==VAX
 573:     /* stack grows downward */
 574:     autoleng += nelt*leng;
 575:     q->memoffset = ICON( - autoleng );
 576: #else
 577:     q->memoffset = ICON( autoleng );
 578:     autoleng += nelt*leng;
 579: #endif
 580: 
 581: return(q);
 582: }
 583: 
 584: 
 585: struct addrblock *mktmpn(nelt, type, lengp)
 586: int nelt;
 587: register int type;
 588: expptr lengp;
 589: {
 590: ftnint leng;
 591: chainp p, oldp;
 592: register struct addrblock *q;
 593: 
 594: if(type==TYUNKNOWN || type==TYERROR)
 595:     fatal1("mktmpn: invalid type %d", type);
 596: 
 597: if(type==TYCHAR)
 598:     if( ISICON(lengp) )
 599:         leng = lengp->const.ci;
 600:     else    {
 601:         err("adjustable length");
 602:         return( errnode() );
 603:         }
 604: for(oldp = &templist ; p = oldp->nextp ; oldp = p)
 605:     {
 606:     q = p->datap;
 607:     if(q->vtype==type && q->ntempelt==nelt &&
 608:         (type!=TYCHAR || q->vleng->const.ci==leng) )
 609:         {
 610:         oldp->nextp = p->nextp;
 611:         free(p);
 612:         return(q);
 613:         }
 614:     }
 615: q = autovar(nelt, type, lengp);
 616: q->istemp = YES;
 617: return(q);
 618: }
 619: 
 620: 
 621: 
 622: 
 623: struct addrblock *mktemp(type, lengp)
 624: int type;
 625: expptr lengp;
 626: {
 627: return( mktmpn(1,type,lengp) );
 628: }
 629: 
 630: /* VARIOUS ROUTINES FOR PROCESSING DECLARATIONS */
 631: 
 632: struct extsym *comblock(len, s)
 633: register int len;
 634: register char *s;
 635: {
 636: struct extsym *mkext(), *p;
 637: 
 638: if(len == 0)
 639:     {
 640:     s = BLANKCOMMON;
 641:     len = strlen(s);
 642:     }
 643: p = mkext( varunder(len, s) );
 644: if(p->extstg == STGUNKNOWN)
 645:     p->extstg = STGCOMMON;
 646: else if(p->extstg != STGCOMMON)
 647:     {
 648:     err1("%s cannot be a common block name", s);
 649:     return(0);
 650:     }
 651: 
 652: return( p );
 653: }
 654: 
 655: 
 656: incomm(c, v)
 657: struct extsym *c;
 658: struct nameblock *v;
 659: {
 660: if(v->vstg != STGUNKNOWN)
 661:     dclerr("incompatible common declaration", v);
 662: else
 663:     {
 664:     v->vstg = STGCOMMON;
 665:     c->extp = hookup(c->extp, mkchain(v,NULL) );
 666:     }
 667: }
 668: 
 669: 
 670: 
 671: 
 672: settype(v, type, length)
 673: register struct nameblock * v;
 674: register int type;
 675: register int length;
 676: {
 677: if(type == TYUNKNOWN)
 678:     return;
 679: 
 680: if(type==TYSUBR && v->vtype!=TYUNKNOWN && v->vstg==STGARG)
 681:     {
 682:     v->vtype = TYSUBR;
 683:     frexpr(v->vleng);
 684:     }
 685: else if(type < 0)   /* storage class set */
 686:     {
 687:     if(v->vstg == STGUNKNOWN)
 688:         v->vstg = - type;
 689:     else if(v->vstg != -type)
 690:         dclerr("incompatible storage declarations", v);
 691:     }
 692: else if(v->vtype == TYUNKNOWN)
 693:     {
 694:     if( (v->vtype = lengtype(type, length))==TYCHAR && length!=0)
 695:         v->vleng = ICON(length);
 696:     }
 697: else if(v->vtype!=type || (type==TYCHAR && v->vleng->const.ci!=length) )
 698:     dclerr("incompatible type declarations", v);
 699: }
 700: 
 701: 
 702: 
 703: 
 704: 
 705: lengtype(type, length)
 706: register int type;
 707: register int length;
 708: {
 709: switch(type)
 710:     {
 711:     case TYREAL:
 712:         if(length == 8)
 713:             return(TYDREAL);
 714:         if(length == 4)
 715:             goto ret;
 716:         break;
 717: 
 718:     case TYCOMPLEX:
 719:         if(length == 16)
 720:             return(TYDCOMPLEX);
 721:         if(length == 8)
 722:             goto ret;
 723:         break;
 724: 
 725:     case TYSHORT:
 726:     case TYDREAL:
 727:     case TYDCOMPLEX:
 728:     case TYCHAR:
 729:     case TYUNKNOWN:
 730:     case TYSUBR:
 731:     case TYERROR:
 732:         goto ret;
 733: 
 734:     case TYLOGICAL:
 735:         if(length == 4)
 736:             goto ret;
 737:         break;
 738: 
 739:     case TYLONG:
 740:         if(length == 0)
 741:             return(tyint);
 742:         if(length == 2)
 743:             return(TYSHORT);
 744:         if(length == 4)
 745:             goto ret;
 746:         break;
 747:     default:
 748:         fatal1("lengtype: invalid type %d", type);
 749:     }
 750: 
 751: if(length != 0)
 752:     err("incompatible type-length combination");
 753: 
 754: ret:
 755:     return(type);
 756: }
 757: 
 758: 
 759: 
 760: 
 761: 
 762: setintr(v)
 763: register struct nameblock * v;
 764: {
 765: register int k;
 766: 
 767: if(v->vstg == STGUNKNOWN)
 768:     v->vstg = STGINTR;
 769: else if(v->vstg!=STGINTR)
 770:     dclerr("incompatible use of intrinsic function", v);
 771: if(v->vclass==CLUNKNOWN)
 772:     v->vclass = CLPROC;
 773: if(v->vprocclass == PUNKNOWN)
 774:     v->vprocclass = PINTRINSIC;
 775: else if(v->vprocclass != PINTRINSIC)
 776:     dclerr("invalid intrinsic declaration", v);
 777: if(k = intrfunct(v->varname))
 778:     v->vardesc.varno = k;
 779: else
 780:     dclerr("unknown intrinsic function", v);
 781: }
 782: 
 783: 
 784: 
 785: setext(v)
 786: register struct nameblock * v;
 787: {
 788: if(v->vclass == CLUNKNOWN)
 789:     v->vclass = CLPROC;
 790: else if(v->vclass != CLPROC)
 791:     dclerr("invalid external declaration", v);
 792: 
 793: if(v->vprocclass == PUNKNOWN)
 794:     v->vprocclass = PEXTERNAL;
 795: else if(v->vprocclass != PEXTERNAL)
 796:     dclerr("invalid external declaration", v);
 797: }
 798: 
 799: 
 800: 
 801: 
 802: /* create dimensions block for array variable */
 803: 
 804: setbound(v, nd, dims)
 805: register struct nameblock * v;
 806: int nd;
 807: struct { expptr lb, ub; } dims[ ];
 808: {
 809: register expptr q, t;
 810: register struct dimblock *p;
 811: int i;
 812: 
 813: if(v->vclass == CLUNKNOWN)
 814:     v->vclass = CLVAR;
 815: else if(v->vclass != CLVAR)
 816:     {
 817:     dclerr("only variables may be arrays", v);
 818:     return;
 819:     }
 820: 
 821: v->vdim = p = (struct dimblock *) ckalloc( sizeof(int) + (3+2*nd)*sizeof(expptr) );
 822: p->ndim = nd;
 823: p->nelt = ICON(1);
 824: 
 825: for(i=0 ; i<nd ; ++i)
 826:     {
 827:     if( (q = dims[i].ub) == NULL)
 828:         {
 829:         if(i == nd-1)
 830:             {
 831:             frexpr(p->nelt);
 832:             p->nelt = NULL;
 833:             }
 834:         else
 835:             err("only last bound may be asterisk");
 836:         p->dims[i].dimsize = ICON(1);;
 837:         p->dims[i].dimexpr = NULL;
 838:         }
 839:     else
 840:         {
 841:         if(dims[i].lb)
 842:             {
 843:             q = mkexpr(OPMINUS, q, cpexpr(dims[i].lb));
 844:             q = mkexpr(OPPLUS, q, ICON(1) );
 845:             }
 846:         if( ISCONST(q) )
 847:             {
 848:             p->dims[i].dimsize = q;
 849:             p->dims[i].dimexpr = NULL;
 850:             }
 851:         else    {
 852:             p->dims[i].dimsize = autovar(1, tyint, NULL);
 853:             p->dims[i].dimexpr = q;
 854:             }
 855:         if(p->nelt)
 856:             p->nelt = mkexpr(OPSTAR, p->nelt, cpexpr(p->dims[i].dimsize));
 857:         }
 858:     }
 859: 
 860: q = dims[nd-1].lb;
 861: if(q == NULL)
 862:     q = ICON(1);
 863: 
 864: for(i = nd-2 ; i>=0 ; --i)
 865:     {
 866:     t = dims[i].lb;
 867:     if(t == NULL)
 868:         t = ICON(1);
 869:     if(p->dims[i].dimsize)
 870:         q = mkexpr(OPPLUS, t, mkexpr(OPSTAR, cpexpr(p->dims[i].dimsize), q) );
 871:     }
 872: 
 873: if( ISCONST(q) )
 874:     {
 875:     p->baseoffset = q;
 876:     p->basexpr = NULL;
 877:     }
 878: else
 879:     {
 880:     p->baseoffset = autovar(1, tyint, NULL);
 881:     p->basexpr = q;
 882:     }
 883: }

Defined functions

autovar defined in line 548; used 10 times
comblock defined in line 632; never used
dobss defined in line 386; used 1 times
  • in line 35
docomleng defined in line 515; used 1 times
  • in line 56
docommon defined in line 470; used 1 times
  • in line 54
doentry defined in line 285; used 2 times
doext defined in line 440; used 1 times
enddcl defined in line 49; used 2 times
endproc defined in line 21; used 2 times
entrypt defined in line 116; never used
epicode defined in line 169; used 1 times
  • in line 33
frtemp defined in line 537; used 5 times
iarrlen defined in line 451; used 4 times
incomm defined in line 656; never used
lengtype defined in line 705; used 3 times
mktmpn defined in line 585; used 6 times
newentry defined in line 92; used 2 times
newproc defined in line 5; never used
nextarg defined in line 375; used 7 times
procode defined in line 249; used 1 times
  • in line 34
retval defined in line 211; used 2 times
setbound defined in line 804; never used
setext defined in line 785; never used
setintr defined in line 762; never used
settype defined in line 672; used 3 times
startproc defined in line 65; never used
Last modified: 1979-05-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1978
Valid CSS Valid XHTML 1.0 Strict