1: #include <ctype.h>
   2: 
   3: #include "defs"
   4: 
   5: static int lastfmtchar;
   6: static int writeop;
   7: static int needcomma;
   8: 
   9: 
  10: ptr mkiost(kwd,unit,list)
  11: int kwd;
  12: ptr unit;
  13: ptr list;
  14: {
  15: register ptr p;
  16: 
  17: if(unit!=NULL && unit->vtype!=TYINT)
  18:     {
  19:     execerr("I/O unit must be an integer", "");
  20:     return(NULL);
  21:     }
  22: p = allexpblock();
  23: p->tag = TIOSTAT;
  24: p->vtype = TYINT;
  25: p->iokwd = kwd;
  26: p->iounit = unit;
  27: p->iolist = list;
  28: 
  29: return(p);
  30: }
  31: 
  32: 
  33: 
  34: 
  35: struct iogroup *mkiogroup(list, format, dop)
  36: ptr list;
  37: char *format;
  38: ptr dop;
  39: {
  40: register struct iogroup *p;
  41: 
  42: p = ALLOC(iogroup);
  43: p->tag = TIOGROUP;
  44: p->doptr = dop;
  45: p->iofmt = format;
  46: p->ioitems = list;
  47: return(p);
  48: }
  49: 
  50: ptr exio(iostp, errhandle)
  51: struct iostblock *iostp;
  52: int errhandle;
  53: {
  54: ptr unit, list;
  55: int fmtlabel, errlabel, endlabel, jumplabel;
  56: ptr errval;
  57: int fmtio;
  58: 
  59: if(iostp == NULL)
  60:     return( errnode() );
  61: unit = iostp->iounit;
  62: list = iostp->iolist;
  63: 
  64: /* kwd=	0  binary input 	2  formatted input
  65: 	1  binary output	3  formatted output
  66: */
  67: 
  68: writeop = iostp->iokwd & 01;
  69: if( fmtio = (iostp->iokwd & 02) )
  70:     fmtlabel = nextlab() ;
  71: frexpblock(iostp);
  72: 
  73: errval = 0;
  74: endlabel = 0;
  75: if(errhandle)
  76:     {
  77:     switch(tailor.errmode)
  78:         {
  79:         default:
  80:             execerr("no error handling ", "");
  81:             return( errnode() );
  82: 
  83:         case IOERRIBM:  /* ibm: err=, end= */
  84:             jumplabel = nextlab();
  85:             break;
  86: 
  87:         case IOERRFORT77:   /* New Fortran Standard: iostat= */
  88:             break;
  89: 
  90:         }
  91:     errval = gent(TYINT, PNULL);
  92:     }
  93: if(unit)
  94:     unit = simple(RVAL, unit);
  95: else    unit = mkint(writeop ? tailor.ftnout : tailor.ftnin);
  96: 
  97: if(unit->tag!=TCONST && (unit->tag!=TNAME || unit->vsubs!=0))
  98:     unit = simple(LVAL, mknode(TASGNOP,OPASGN,gent(TYINT,PNULL),unit));
  99: 
 100: simlist(list);
 101: 
 102: exlab(0);
 103: putic(ICKEYWORD, (writeop ? FWRITE : FREAD) );
 104: putic(ICOP, OPLPAR);
 105: prexpr(unit);
 106: frexpr(unit);
 107: 
 108: if( fmtio )
 109:     {
 110:     putic(ICOP, OPCOMMA);
 111:     putic(ICLABEL, fmtlabel);
 112:     }
 113: 
 114: if(errhandle) switch(tailor.errmode)
 115:     {
 116:     case IOERRIBM:
 117:         putic(ICOP,OPCOMMA);
 118:         putsii(ICCONST, "err =");
 119:         putic(ICLABEL, errlabel = nextlab() );
 120:         if(!writeop)
 121:             {
 122:             putic(ICOP,OPCOMMA);
 123:             putsii(ICCONST, "end =");
 124:             putic(ICLABEL, endlabel = nextlab() );
 125:             }
 126:         break;
 127: 
 128:     case IOERRFORT77:
 129:         putic(ICOP,OPCOMMA);
 130:         putsii(ICCONST, "iostat =");
 131:         putname(errval);
 132:         break;
 133:     }
 134: 
 135: putic(ICOP,OPRPAR);
 136: putic(ICBLANK, 1);
 137: 
 138: needcomma = NO;
 139: doiolist(list);
 140: if(fmtio)
 141:     {
 142:     exlab(fmtlabel);
 143:     putic(ICKEYWORD, FFORMAT);
 144:     putic(ICOP, OPLPAR);
 145:     lastfmtchar = '(';
 146:     doformat(1, list);
 147:     putic(ICOP, OPRPAR);
 148:     }
 149: friolist(list);
 150: 
 151: if(errhandle && tailor.errmode==IOERRIBM)
 152:     {
 153:     exasgn(cpexpr(errval), OPASGN, mkint(0) );
 154:     exgoto(jumplabel);
 155:     exlab(errlabel);
 156:     exasgn(cpexpr(errval), OPASGN, mkint(1) );
 157:     if(endlabel)
 158:         {
 159:         exgoto(jumplabel);
 160:         exlab(endlabel);
 161:         exasgn(cpexpr(errval), OPASGN,
 162:             mknode(TNEGOP,OPMINUS,mkint(1),PNULL) );
 163:         }
 164:     exlab(jumplabel);
 165:     }
 166: 
 167: return( errval );
 168: }
 169: 
 170: doiolist(list)
 171: ptr list;
 172: {
 173: register ptr p, q;
 174: register struct doblock *dop;
 175: for(p = list ; p ; p = p->nextp)
 176:     {
 177:     switch( (q = p->datap) ->tag)
 178:         {
 179:         case TIOGROUP:
 180:             if(dop = q->doptr)
 181:                 {
 182:                 if(needcomma)
 183:                     putic(ICOP, OPCOMMA);
 184:                 putic(ICOP, OPLPAR);
 185:                 needcomma = NO;
 186:                 }
 187:             doiolist(q->ioitems);
 188:             if(dop)
 189:                 {
 190:                 putic(ICOP,OPCOMMA);
 191:                 prexpr(dop->dovar);
 192:                 putic(ICOP, OPEQUALS);
 193:                 prexpr(dop->dopar[0]);
 194:                 putic(ICOP, OPCOMMA);
 195:                 prexpr(dop->dopar[1]);
 196:                 if(dop->dopar[2])
 197:                     {
 198:                     putic(ICOP, OPCOMMA);
 199:                     prexpr(dop->dopar[2]);
 200:                     }
 201:                 putic(ICOP, OPRPAR);
 202:                 needcomma = YES;
 203:                 }
 204:             break;
 205: 
 206:         case TIOITEM:
 207:             if(q->ioexpr)
 208:                 {
 209:                 if(needcomma)
 210:                     putic(ICOP, OPCOMMA);
 211:                 prexpr(q->ioexpr);
 212:                 needcomma = YES;
 213:                 }
 214:             break;
 215: 
 216:         default:
 217:             badtag("doiolist", q->tag);
 218:         }
 219:     }
 220: }
 221: 
 222: doformat(nrep, list)
 223: int nrep;
 224: ptr list;
 225: {
 226: register ptr p, q;
 227: int k;
 228: ptr arrsize();
 229: 
 230: if(nrep > 1)
 231:     {
 232:     fmtnum(nrep);
 233:     fmtop(OPLPAR);
 234:     }
 235: 
 236: for(p = list ; p ; p = p->nextp)
 237:     switch( (q = p->datap) ->tag)
 238:         {
 239:         case TIOGROUP:
 240:             if(q->iofmt)
 241:                 prfmt(q->nrep, q->iofmt);
 242:             else    {
 243:                 doformat(q->nrep>0 ? q->nrep :
 244:                     (q->doptr ? repfac(q->doptr) : 1),
 245:                     q->ioitems);
 246:                 }
 247:             break;
 248: 
 249:         case TIOITEM:
 250:             if(q->iofmt == NULL)
 251:                 break;
 252: 
 253:             if(q->nrep==0 && q->ioexpr && q->ioexpr->vdim)
 254:                 {
 255:                 if( ! isicon(arrsize(q->ioexpr), &k) )
 256:                     execerr("io of adjustable array", "");
 257:                 else
 258:                     prfmt(k, q->iofmt);
 259:                 }
 260:             else
 261:                 prfmt(q->nrep, q->iofmt);
 262:         }
 263: if(nrep > 1)
 264:     fmtop(OPRPAR);
 265: }
 266: 
 267: fmtop(op)
 268: register int op;
 269: {
 270: register c;
 271: 
 272: c = (op==OPLPAR ? '(' : (op==OPRPAR ? ')' : 'x') );
 273: fmtcom(c);
 274: putic(ICOP, op);
 275: lastfmtchar = c;
 276: }
 277: 
 278: 
 279: 
 280: 
 281: fmtnum(k)
 282: int k;
 283: {
 284: fmtcom('1');
 285: prexpr( mkint(k) );
 286: lastfmtchar = ',';  /* prevent further comma after factor*/
 287: }
 288: 
 289: 
 290: 
 291: 
 292: 
 293: 
 294: 
 295: 
 296: /* separate formats with comma unless already a slash*/
 297: fmtcom(c)
 298: int c;
 299: {
 300: if( c!='/' && c!=')' && lastfmtchar!='/' && lastfmtchar!='(' && lastfmtchar!=',' )
 301:     {
 302:     putic(ICOP, OPCOMMA);
 303:     lastfmtchar = ',';
 304:     }
 305: }
 306: 
 307: prfmt(nrep, str)
 308: int nrep;
 309: char *str;
 310: {
 311: char fmt[20];
 312: register int k, k0, k1, k2;
 313: register char *t;
 314: 
 315: fmtcom(nrep>1 ? '1' : str[0]);
 316: 
 317: if(nrep > 1)
 318:     {
 319:     fmtnum(nrep);
 320:     fmtop(OPLPAR);
 321:     }
 322: 
 323: switch(str[0])
 324:     {
 325:     case 'd':
 326:     case 'e':
 327:     case 'g':
 328:         if(writeop)
 329:             {
 330:             putsii(ICCONST, "1p");
 331:             break;
 332:             }
 333: 
 334:     case 'f':
 335:         putsii(ICCONST, "0p");
 336:         break;
 337: 
 338:     case 'c':
 339:         k = convci(str+1);
 340:         k0 = tailor.ftnchwd;
 341:         k1 = k / k0;
 342:         k2 = k % k0;
 343:         if(k1>0 && k2>0)
 344:             sprintf(fmt, "(%da%d,a%d)",k1,k0,k2);
 345:         else if(k1>1)
 346:             sprintf(fmt, "(%da%d)", k1, k0);
 347:         else    sprintf(fmt, "a%d", k);
 348:         putsii(ICCONST, fmt);
 349:         lastfmtchar = 'f';  /* last char isnt operator */
 350:         goto close;
 351: 
 352:     default:
 353:         break;
 354:     }
 355: putsii(ICCONST,str);
 356: /* if the format is an nH, act as if it ended with a non-operator character */
 357: if( isdigit(str[0]) )
 358:     {
 359:     for(t = str+1 ; isdigit(*t) ; ++t);
 360:         ;
 361:     if(*t=='h' || *t=='H')
 362:         {
 363:         lastfmtchar = 'f';
 364:         goto close;
 365:         }
 366:     }
 367: lastfmtchar = str[ strlen(str)-1 ];
 368: 
 369: close:
 370:     if(nrep > 1)
 371:         fmtop(OPRPAR);
 372: }
 373: 
 374: friolist(list)
 375: ptr list;
 376: {
 377: register ptr p, q;
 378: register struct doblock *dop;
 379: 
 380: for(p = list; p; p = p->nextp)
 381:     {
 382:     switch ( (q = p->datap) ->tag)
 383:         {
 384:         case TIOGROUP:
 385:             if(dop = q->doptr)
 386:                 {
 387:                 frexpr(dop->dovar);
 388:                 frexpr(dop->dopar[0]);
 389:                 frexpr(dop->dopar[1]);
 390:                 if(dop->dopar[2])
 391:                     frexpr(dop->dopar[2]);
 392:                 cfree(dop);
 393:                 }
 394:             friolist(q->ioitems);
 395:             break;
 396: 
 397:         case TIOITEM:
 398:             if(q->ioexpr)
 399:                 frexpr(q->ioexpr);
 400:             break;
 401: 
 402:         default:
 403:             badtag("friolist", q->tag);
 404:         }
 405:     if(q->iofmt)
 406:         cfree(q->iofmt);
 407:     cfree(q);
 408:     }
 409: frchain( &list );
 410: }
 411: 
 412: simlist(p)
 413: register ptr p;
 414: {
 415: register ptr q, ep;
 416: struct iogroup *enloop();
 417: 
 418: for( ; p ; p = p->nextp)
 419:     switch( (q = p->datap) ->tag )
 420:         {
 421:         case TIOGROUP:
 422:             simlist(q->ioitems);
 423:             break;
 424: 
 425:         case TIOITEM:
 426:             if(ep = q->ioexpr)
 427:                 {
 428:                 /* if element is a subaggregate, need
 429: 				   an implied do loop */
 430:                 if( (ep->voffset || ep->vsubs) &&
 431:                     (ep->vdim || ep->vtypep) )
 432:                     p->datap = enloop(q);
 433:                 else
 434:                     q->ioexpr = simple(LVAL,ep);
 435:                 }
 436:             break;
 437: 
 438:         default:
 439:             badtag("ioblock", q->tag);
 440:         }
 441: }
 442: 
 443: 
 444: 
 445: 
 446: /* replace an aggregate by an implied do loop of elements */
 447: 
 448: struct iogroup *enloop(p)
 449: struct ioitem *p;
 450: {
 451: register struct doblock *dop;
 452: struct iogroup *gp;
 453: ptr np, q, v, arrsize(), mkioitem();
 454: int nrep, k, nwd;
 455: 
 456: q = p->ioexpr;
 457: np = arrsize(q);
 458: if( ! isicon(np, &nrep) )
 459:     nrep = 0;
 460: 
 461: if(q->vtype == TYCHAR)
 462:     {
 463:     nwd = ceil(conval(q->vtypep), tailor.ftnchwd);
 464:     if(nwd != 1)
 465:         np = simple(LVAL, mknode(TAROP,OPSTAR,np,mkint(nwd)));
 466:     }
 467: else
 468:     nwd = 0;
 469: 
 470: if( isicon(np, &k) && k==1)
 471:     return(p);
 472: 
 473: dop = ALLOC(doblock);
 474: dop->tag = TDOBLOCK;
 475: 
 476: dop->dovar = v = gent(TYINT, PNULL);
 477: dop->dopar[0] = mkint(1);
 478: dop->dopar[1] = simple(SUBVAL, np);
 479: dop->dopar[2] = NULL;
 480: 
 481: q = simple(LVAL, q);
 482: if(q->vsubs == NULL)
 483:     q->vsubs = mknode(TLIST,0, mkchain(cpexpr(v),CHNULL), PNULL);
 484: else
 485:     q->vsubs->leftp->datap = simple(SUBVAL, mknode(TAROP,OPPLUS, cpexpr(v),
 486:              mknode(TAROP,OPMINUS,q->vsubs->leftp->datap,mkint(1))));
 487: q->vdim = NULL;
 488: gp = mkiogroup( mkchain(mkioitem(q,CNULL), CHNULL), p->iofmt, dop);
 489: gp->nrep = nrep;
 490: cfree(p);
 491: return(gp);
 492: }
 493: 
 494: ptr mkformat(letter, n1, n2)
 495: char letter;
 496: register ptr n1, n2;
 497: {
 498: char f[20], *fp, *s;
 499: int k;
 500: 
 501: if(letter == 's')
 502:     {
 503:     if(n1)
 504:         {
 505:         k = conval(n1);
 506:         frexpr(n1);
 507:         }
 508:     else    k = 1;
 509: 
 510:     for(fp = f; k-->0 ; )
 511:         *fp++ = '/';
 512:     *fp = '\0';
 513:     return( copys(f) );
 514:     }
 515: 
 516: f[0] = letter;
 517: fp = f+1;
 518: 
 519: if(n1)  {
 520:     n1 = simple(RVAL,n1);
 521:     if(n1->tag==TCONST && n1->vtype==TYINT)
 522:         {
 523:         for(s = n1->leftp ; *s; )
 524:             *fp++ = *s++;
 525:         }
 526:     else    execerr("bad format component %s", n1->leftp);
 527:     frexpr(n1);
 528:     }
 529: 
 530: if(n2)  {
 531:     if(n2->tag==TCONST && n2->vtype==TYINT)
 532:         {
 533:         *fp++ = '.';
 534:         for(s = n2->leftp ; *s; )
 535:             *fp++ = *s++;
 536:         }
 537:     else    execerr("bad format component %s", n2->leftp);
 538:     frexpr(n2);
 539:     }
 540: 
 541: if( letter == 'x' )
 542:     {
 543:     if(n1 == 0)
 544:         *fp++ = '1';
 545:     fp[0] = 'x';
 546:     fp[1] = '\0';
 547:     return( copys(f+1) );
 548:     }
 549: else    {
 550:     *fp = '\0';
 551:     return( copys(f) );
 552:     }
 553: }
 554: 
 555: ptr mkioitem(e,f)
 556: register ptr e;
 557: char *f;
 558: {
 559: register ptr p;
 560: char fmt[10];
 561: ptr gentemp();
 562: 
 563: p = ALLOC(ioitem);
 564: p->tag = TIOITEM;
 565: if(e!=NULL && e->tag==TCONST)
 566:     if(e->vtype==TYCHAR && (f==0 || (f[0]=='c' && f[1]=='\0') ))
 567:         {
 568:         p->ioexpr = 0;
 569:         sprintf(msg, "%dh%s", strlen(e->leftp), e->leftp);
 570:         p->iofmt = copys(msg);
 571:         frexpr(e);
 572:         return(p);
 573:         }
 574:     else    e = mknode(TASGNOP,OPASGN,gentemp(e),e);
 575: 
 576: if(e && e->vtype==TYCHAR && f && f[0]=='c' && f[1]=='\0')
 577:     f = NULL;
 578: if(f == NULL)
 579:     {
 580:     switch(e->vtype)
 581:         {
 582:         case TYINT:
 583:         case TYREAL:
 584:         case TYLREAL:
 585:         case TYCOMPLEX:
 586:         case TYLOG:
 587:             f = copys( tailor.dfltfmt[e->vtype] );
 588:             break;
 589: 
 590:         case TYCHAR:
 591:             if(e->vtypep->tag != TCONST)
 592:                 {
 593:                 execerr("no adjustable character formats", "");
 594:                 f = 0;
 595:                 }
 596:             else    {
 597:                 sprintf(fmt, "c%s", e->vtypep->leftp);
 598:                 f = copys(fmt);
 599:                 }
 600:             break;
 601: 
 602:         default:
 603:             execerr("cannot do I/O on structures", "");
 604:             f = 0;
 605:             break;
 606:         }
 607:     }
 608: 
 609: p->ioexpr = e;
 610: p->iofmt = f;
 611: return(p);
 612: }
 613: 
 614: 
 615: 
 616: ptr arrsize(p)
 617: ptr p;
 618: {
 619: register ptr b;
 620: ptr f, q;
 621: 
 622: q = mkint(1);
 623: 
 624: if(b = p->vdim)
 625:     for(b = b->datap ; b ; b = b->nextp)
 626:     {
 627:     if(b->upperb == 0) continue;
 628:     f = cpexpr(b->upperb);
 629:     if(b->lowerb)
 630:         f = mknode(TAROP,OPPLUS,f,
 631:             mknode(TAROP,OPMINUS,mkint(1),cpexpr(b->lowerb)));
 632:     q = simple(RVAL, mknode(TAROP,OPSTAR,q,f));
 633:     }
 634: return(q);
 635: }
 636: 
 637: 
 638: 
 639: 
 640: repfac(dop)
 641: register struct doblock *dop;
 642: {
 643: int m1, m2, m3;
 644: 
 645: m3 = 1;
 646: if( isicon(dop->dopar[0],&m1) &&  isicon(dop->dopar[1],&m2) &&
 647:   (dop->dopar[2]==NULL || isicon(dop->dopar[2],&m3)) )
 648:     {
 649:     if(m3 > 0)
 650:         return(1 + (m2-m1)/m3);
 651:     }
 652: else    execerr("nonconstant implied do", "");
 653: return(1);
 654: }
 655: 
 656: 
 657: 
 658: ioop(s)
 659: char *s;
 660: {
 661: if( equals(s, "backspace") )
 662:     return(FBACKSPACE);
 663: if( equals(s, "rewind") )
 664:     return(FREWIND);
 665: if( equals(s, "endfile") )
 666:     return(FENDFILE);
 667: return(0);
 668: }
 669: 
 670: 
 671: 
 672: 
 673: ptr exioop(p, errcheck)
 674: register struct exprblock *p;
 675: int errcheck;
 676: {
 677: register ptr q, t;
 678: 
 679: if( (q = p->rightp)==NULL || (q = q->leftp)==NULL  )
 680:     {
 681:     execerr("bad I/O operation", "");
 682:     return(NULL);
 683:     }
 684: q = simple(LVAL, cpexpr(q->datap) );
 685: 
 686: exlab(0);
 687: putic(ICKEYWORD, ioop(p->leftp->sthead->namep));
 688: 
 689: if(errcheck)
 690:     {
 691:     if(tailor.errmode != IOERRFORT77)
 692:         {
 693:         execerr("cannot test value of IOOP without ftn77", "");
 694:         return( errnode() );
 695:         }
 696:     putic(ICOP, OPLPAR);
 697:     prexpr(q);
 698:     putic(ICOP, OPCOMMA);
 699:     putsii(ICCONST, "iostat =");
 700:     prexpr(cpexpr( t = gent(TYINT,PNULL)));
 701:     putic(ICOP, OPRPAR);
 702:     return( t );
 703:     }
 704: else    {
 705:     putic(ICBLANK, 1);
 706:     prexpr(q);
 707:     }
 708: }

Defined functions

arrsize defined in line 616; used 6 times
doformat defined in line 222; used 2 times
doiolist defined in line 170; used 2 times
enloop defined in line 448; used 2 times
exio defined in line 50; used 2 times
exioop defined in line 673; used 4 times
fmtcom defined in line 297; used 3 times
fmtnum defined in line 281; used 2 times
fmtop defined in line 267; used 4 times
friolist defined in line 374; used 2 times
ioop defined in line 658; used 5 times
mkformat defined in line 494; never used
mkiogroup defined in line 35; used 1 times
mkioitem defined in line 555; used 2 times
mkiost defined in line 10; never used
prfmt defined in line 307; used 3 times
repfac defined in line 640; used 1 times
simlist defined in line 412; used 2 times

Defined variables

lastfmtchar defined in line 5; used 10 times
needcomma defined in line 7; used 6 times
writeop defined in line 6; used 5 times
Last modified: 1982-06-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1698
Valid CSS Valid XHTML 1.0 Strict