|
|
1.1 ! root 1: #include <ctype.h> ! 2: #include "defs" ! 3: ! 4: ! 5: /* basic simplifying procedure */ ! 6: ! 7: ptr simple(t,e) ! 8: int t; /* take on the values LVAL, RVAL, and SUBVAL */ ! 9: register ptr e; /* points to an expression */ ! 10: { ! 11: int tag, subtype; ! 12: ptr lp, rp; ! 13: int ltag; ! 14: int lsubt; ! 15: ptr p, e1; ! 16: ptr exio(), exioop(), dblop(), setfield(), gentemp(); ! 17: int a,b,c; ! 18: ! 19: top: ! 20: ! 21: if(e == 0) return(0); ! 22: ! 23: tag = e->tag; ! 24: subtype = e->subtype; ! 25: if(lp = e->leftp) ! 26: { ! 27: ltag = lp->tag; ! 28: lsubt = lp->subtype; ! 29: } ! 30: rp = e->rightp; ! 31: ! 32: TEST fprintf(diagfile, "simple(%d; tag %d,%d)\n", t,tag,subtype); ! 33: ! 34: switch(tag){ ! 35: ! 36: case TNOTOP: ! 37: switch(ltag) { ! 38: ! 39: case TNOTOP: /* not not = yes */ ! 40: frexpblock(e); ! 41: e = lp->leftp; ! 42: frexpblock(lp); ! 43: goto top; ! 44: ! 45: case TLOGOP: /* de Morgan's Law */ ! 46: lp->subtype = (OPOR+OPAND) - lp->subtype; ! 47: lp->leftp = mknode(TNOTOP,OPNOT,lp->leftp, PNULL); ! 48: lp->rightp=mknode(TNOTOP,OPNOT,lp->rightp, PNULL); ! 49: frexpblock(e); ! 50: e = lp; ! 51: goto top; ! 52: ! 53: case TRELOP: /* reverse the condition */ ! 54: lp->subtype = (OPEQ+OPNE) - lp->subtype; ! 55: frexpblock(e); ! 56: e = lp; ! 57: goto top; ! 58: ! 59: case TCALL: ! 60: case TASGNOP: ! 61: e->leftp = simple(RVAL,lp); ! 62: ! 63: case TNAME: ! 64: case TFTNBLOCK: ! 65: lp = simple(RVAL,lp); ! 66: ! 67: case TTEMP: ! 68: if(t == LVAL) ! 69: e = simple(LVAL, ! 70: mknode(TASGNOP,0, gentemp(e->leftp), e)); ! 71: break; ! 72: ! 73: case TCONST: ! 74: if(equals(lp->leftp, ".false.")) ! 75: e->leftp = (int *)copys(".true."); ! 76: else if(equals(lp->leftp, ".true.")) ! 77: e->leftp = (int *)copys(".false."); ! 78: else goto typerr; ! 79: ! 80: e->tag = TCONST; ! 81: e->subtype = 0; ! 82: cfree(lp->leftp); ! 83: frexpblock(lp); ! 84: break; ! 85: ! 86: default: goto typerr; ! 87: } ! 88: break; ! 89: ! 90: ! 91: ! 92: ! 93: case TLOGOP: switch(subtype) { ! 94: case OPOR: ! 95: case OPAND: ! 96: goto binop; ! 97: ! 98: case OP2OR: ! 99: case OP2AND: ! 100: lp = e->leftp = simple(RVAL, lp); ! 101: if(lp->tag != TTEMP) ! 102: lp = simple(RVAL, ! 103: mknode(TASGNOP,0, gent(TYLOG,0),lp)); ! 104: return( simple(LVAL, mknode(TASGNOP,subtype,lp,rp)) ); ! 105: default: ! 106: fatal("impossible logical operator"); ! 107: } ! 108: ! 109: case TNEGOP: ! 110: lp = e->leftp = simple(RVAL,lp); ! 111: ltag = lp->tag; ! 112: lsubt = lp->subtype; ! 113: ! 114: if(ltag==TNEGOP) ! 115: { ! 116: frexpblock(e); ! 117: e = lp->leftp; ! 118: frexpblock(lp); ! 119: goto top; ! 120: } ! 121: else goto lvcheck; ! 122: ! 123: case TAROP: ! 124: case TRELOP: ! 125: ! 126: binop: ! 127: ! 128: e->leftp = simple(RVAL,lp); ! 129: lp = e->leftp; ! 130: ltag = lp->tag; ! 131: lsubt = lp->subtype; ! 132: ! 133: e->rightp= simple(RVAL,rp); ! 134: rp = e->rightp; ! 135: ! 136: if(tag==TAROP && isicon(rp,&b) ) ! 137: { /* simplify a*1, a/1 , a+0, a-0 */ ! 138: if( ((subtype==OPSTAR||subtype==OPSLASH) && b==1) || ! 139: ((subtype==OPPLUS||subtype==OPMINUS) && b==0) ) ! 140: { ! 141: frexpr(rp); ! 142: mvexpr(lp,e); ! 143: goto top; ! 144: } ! 145: ! 146: if(isicon(lp, &a)) /* try folding const op const */ ! 147: { ! 148: e1 = fold(e); ! 149: if(e1!=e || e1->tag!=TAROP) ! 150: { ! 151: e = e1; ! 152: goto top; ! 153: } ! 154: } ! 155: if(ltag==TAROP && lp->needpar==0 && isicon(lp->rightp,&a) ) ! 156: { /* look for cases of (e op const ) op' const */ ! 157: ! 158: if( (subtype==OPPLUS||subtype==OPMINUS) && ! 159: (lsubt==OPPLUS||lsubt==OPMINUS) ) ! 160: { /* (e +- const) +- const */ ! 161: c = (subtype==OPPLUS ? 1 : -1) * b + ! 162: (lsubt==OPPLUS? 1 : -1) * a; ! 163: if(c > 0) ! 164: subtype = OPPLUS; ! 165: else { ! 166: subtype = OPMINUS; ! 167: c = -c; ! 168: } ! 169: fixexpr: ! 170: frexpr(rp); ! 171: frexpr(lp->rightp); ! 172: frexpblock(e); ! 173: e = lp; ! 174: e->subtype = subtype; ! 175: e->rightp = mkint(c); ! 176: goto top; ! 177: } ! 178: ! 179: else if(lsubt==OPSTAR && ! 180: ( (subtype==OPSTAR) || ! 181: (subtype==OPSLASH && a%b==0)) ) ! 182: { /* (e * const ) (* or /) const */ ! 183: c = (subtype==OPSTAR ? a*b : a/b ); ! 184: subtype = OPSTAR; ! 185: goto fixexpr; ! 186: } ! 187: } ! 188: if(ltag==TAROP && (lsubt==OPPLUS || lsubt==OPMINUS) && ! 189: subtype==OPSLASH && divides(lp,conval(rp)) ) ! 190: { ! 191: e->leftp = mknode(TAROP,OPSLASH,lp->leftp, cpexpr(rp)); ! 192: e->rightp = mknode(TAROP,OPSLASH,lp->rightp, rp); ! 193: e->subtype = lsubt; ! 194: goto top; ! 195: } ! 196: } ! 197: ! 198: else if( tag==TRELOP && isicon(lp,&a) && isicon(rp,&b) ) ! 199: { ! 200: e1 = fold(e); ! 201: if(e1!=e || e1->tag!=TRELOP) ! 202: { ! 203: e = e1; ! 204: goto top; ! 205: } ! 206: } ! 207: ! 208: lvcheck: ! 209: if(t == LVAL) ! 210: e = simple(LVAL, mknode(TASGNOP,0, gentemp(e),e)); ! 211: else if(t == SUBVAL) ! 212: { /* test for legal Fortran c*v +-c form */ ! 213: /* ! 214: if(tailor.ftn77 && e->vtype==TYINT) ! 215: break; ! 216: */ ! 217: if(tag==TAROP && (subtype==OPPLUS || subtype==OPMINUS)) ! 218: if(rp->tag==TCONST && rp->vtype==TYINT) ! 219: { ! 220: if(!cvform(lp)) ! 221: e->leftp = simple(SUBVAL, lp); ! 222: } ! 223: else goto makesub; ! 224: else if( !cvform(e) ) goto makesub; ! 225: } ! 226: break; ! 227: ! 228: case TCALL: ! 229: if( lp->tag!=TFTNBLOCK && ioop(((struct stentry *)lp->sthead)->namep) ) ! 230: { ! 231: e = exioop(e, YES); ! 232: exlab(0); ! 233: break; ! 234: } ! 235: e->rightp = simple(RVAL, rp); ! 236: if(t == SUBVAL) ! 237: goto makesub; ! 238: if(t == LVAL) ! 239: e = simple(RVAL, mknode(TASGNOP,0, gentemp(e),e)); ! 240: break; ! 241: ! 242: ! 243: case TNAME: ! 244: if(e->voffset) ! 245: fixsubs(e); ! 246: if(e->vsubs) ! 247: e->vsubs = simple(SUBVAL, e->vsubs); ! 248: if(t==SUBVAL && !vform(e)) ! 249: goto makesub; ! 250: ! 251: case TTEMP: ! 252: case TFTNBLOCK: ! 253: case TCONST: ! 254: if(t==SUBVAL && e->vtype!=TYINT) ! 255: goto makesub; ! 256: break; ! 257: ! 258: case TASGNOP: ! 259: lp = e->leftp = simple(LVAL,lp); ! 260: if(subtype==OP2OR || subtype==OP2AND) ! 261: e = dblop(e); ! 262: ! 263: else { ! 264: rp = e->rightp = simple(RVAL,rp); ! 265: if(e->vtype == TYCHAR) ! 266: excall(mkcall(mkftnblock(TYSUBR,"ef1asc"), arg4(cpexpr(lp),rp))); ! 267: else if(e->vtype == TYSTRUCT) ! 268: { ! 269: if(((struct typeblock *)lp->vtypep)->strsize != ((struct typeblock *)rp->vtypep)->strsize) ! 270: fatal("simple: attempt to assign incompatible structures"); ! 271: e1 = (int *)mkchain(cpexpr(lp),mkchain(rp, ! 272: mkchain(mkint(((struct typeblock *)lp->vtypep)->strsize),CHNULL))); ! 273: excall(mkcall(mkftnblock(TYSUBR,"ef1ass"), ! 274: mknode(TLIST, 0, e1, PNULL) )); ! 275: } ! 276: else if(lp->vtype == TYFIELD) ! 277: lp = setfield(e); ! 278: else { ! 279: if(subtype != OPASGN) /* but is one of += etc */ ! 280: { ! 281: rp = e->rightp = simple(RVAL, mknode( ! 282: (subtype<=OPPOWER?TAROP:TLOGOP),subtype, ! 283: cpexpr(e->leftp),e->rightp)); ! 284: e->subtype = OPASGN; ! 285: } ! 286: exlab(0); ! 287: prexpr(e); ! 288: frexpr(rp); ! 289: } ! 290: frexpblock(e); ! 291: e = lp; ! 292: if(t == SUBVAL) goto top; ! 293: } ! 294: ! 295: break; ! 296: ! 297: case TLIST: ! 298: for(p=lp ; p ; p = p->nextp) ! 299: p->datap = simple(t, p->datap); ! 300: break; ! 301: ! 302: case TIOSTAT: ! 303: e = exio(e, 1); ! 304: break; ! 305: ! 306: default: ! 307: break; ! 308: } ! 309: ! 310: return(e); ! 311: ! 312: ! 313: typerr: ! 314: exprerr("type match error", CNULL); ! 315: return(e); ! 316: ! 317: makesub: ! 318: if(t==SUBVAL && e->vtype!=TYINT) ! 319: warn1("Line %d. Non-integer subscript", yylineno); ! 320: return( simple(RVAL, mknode(TASGNOP,0,gent(TYINT,PNULL),e)) ); ! 321: } ! 322: ! 323: ptr fold(e) ! 324: register ptr e; ! 325: { ! 326: int a, b, c; ! 327: register ptr lp, rp; ! 328: ! 329: lp = e->leftp; ! 330: rp = e->rightp; ! 331: ! 332: if(lp->tag!=TCONST && lp->tag!=TNEGOP) ! 333: return(e); ! 334: ! 335: if(rp->tag!=TCONST && rp->tag!=TNEGOP) ! 336: return(e); ! 337: ! 338: ! 339: switch(e->tag) ! 340: { ! 341: case TAROP: ! 342: if( !isicon(lp,&a) || !isicon(rp,&b) ) ! 343: return(e); ! 344: ! 345: switch(e->subtype) ! 346: { ! 347: case OPPLUS: ! 348: c = a + b;break; ! 349: case OPMINUS: ! 350: c = a - b; break; ! 351: case OPSTAR: ! 352: c = a * b; break; ! 353: case OPSLASH: ! 354: if(a%b!=0 && (a<0 || b<0) ) ! 355: return(e); ! 356: c = a / b; break; ! 357: case OPPOWER: ! 358: return(e); ! 359: default: ! 360: fatal("fold: illegal binary operator"); ! 361: } ! 362: frexpr(e); ! 363: ! 364: if(c >= 0) ! 365: return( mkint(c) ); ! 366: else return(mknode(TNEGOP,OPMINUS, mkint(-c), PNULL) ); ! 367: ! 368: case TRELOP: ! 369: if( !isicon(lp,&a) || !isicon(rp,&b) ) ! 370: return(e); ! 371: frexpr(e); ! 372: ! 373: switch(e->subtype) ! 374: { ! 375: case OPEQ: ! 376: c = a == b; break; ! 377: case OPLT: ! 378: c = a < b ; break; ! 379: case OPGT: ! 380: c = a > b; break; ! 381: case OPLE: ! 382: c = a <= b; break; ! 383: case OPGE: ! 384: c = a >= b; break; ! 385: case OPNE: ! 386: c = a != b; break; ! 387: default: ! 388: fatal("fold: invalid relational operator"); ! 389: } ! 390: return( mkconst(TYLOG, (c ? ".true." : ".false.")) ); ! 391: ! 392: ! 393: case TLOGOP: ! 394: if(lp->vtype!=TYLOG || rp->vtype!=TYLOG) ! 395: return(e); ! 396: a = equals(lp->leftp, ".true."); ! 397: b = equals(rp->leftp, ".true."); ! 398: frexpr(e); ! 399: ! 400: switch(e->subtype) ! 401: { ! 402: case OPAND: ! 403: case OP2AND: ! 404: c = a & b; break; ! 405: case OPOR: ! 406: case OP2OR: ! 407: c = a | b; break; ! 408: default: ! 409: fatal("fold: invalid logical operator"); ! 410: } ! 411: return( mkconst(TYLOG, (c? ".true." : ".false")) ); ! 412: ! 413: default: ! 414: return(e); ! 415: } ! 416: } ! 417: ! 418: #define TO + 100* ! 419: ! 420: ! 421: ptr coerce(t,e) /* coerce expression e to type t */ ! 422: int t; ! 423: register ptr e; ! 424: { ! 425: register int et; ! 426: int econst; ! 427: char buff[100]; ! 428: char *s, *s1; ! 429: ptr conrep(), xfixf(); ! 430: ! 431: if(e->tag == TNEGOP) ! 432: { ! 433: e->leftp = coerce(t, e->leftp); ! 434: goto settype; ! 435: } ! 436: ! 437: et = e->vtype; ! 438: econst = (e->tag == TCONST); ! 439: TEST fprintf(diagfile, "coerce type %d to type %d\n", et, t); ! 440: if(t == et) ! 441: return(e); ! 442: ! 443: switch( et TO t ) ! 444: { ! 445: case TYCOMPLEX TO TYINT: ! 446: case TYLREAL TO TYINT: ! 447: e = coerce(TYREAL,e); ! 448: case TYREAL TO TYINT: ! 449: if(econst) ! 450: e = xfixf(e); ! 451: if(e->vtype != TYINT) ! 452: e = mkcall(builtin(TYINT,"ifix"), arg1(e)); ! 453: break; ! 454: ! 455: case TYINT TO TYREAL: ! 456: if(econst) ! 457: { ! 458: e->leftp = conrep(e->leftp, "."); ! 459: goto settype; ! 460: } ! 461: e = mkcall(builtin(TYREAL,"float"), arg1(e)); ! 462: break; ! 463: ! 464: case TYLREAL TO TYREAL: ! 465: if(econst) ! 466: { ! 467: for(s=(char *)e->leftp ; *s && *s!='d';++s) ! 468: ; ! 469: *s = 'e'; ! 470: goto settype; ! 471: } ! 472: e = mkcall(builtin(TYREAL,"sngl"), arg1(e)); ! 473: break; ! 474: ! 475: case TYCOMPLEX TO TYREAL: ! 476: if(econst) ! 477: { ! 478: s1 = (char *)(e->leftp) + 1; ! 479: s = buff; ! 480: while(*s1!=',' && *s1!='\0') ! 481: *s1++ = *s++; ! 482: *s = '\0'; ! 483: cfree(e->leftp); ! 484: e->leftp = (int *)copys(buff); ! 485: goto settype; ! 486: } ! 487: else ! 488: e = mkcall(mkftnblock(TYREAL,"real"), arg1(e)); ! 489: break; ! 490: ! 491: case TYINT TO TYLREAL: ! 492: if(econst) ! 493: { ! 494: e->leftp = conrep(e->leftp,"d0"); ! 495: goto settype; ! 496: } ! 497: case TYCOMPLEX TO TYLREAL: ! 498: e = coerce(TYREAL,e); ! 499: case TYREAL TO TYLREAL: ! 500: if(econst) ! 501: { ! 502: for(s=(char *)e->leftp ; *s && *s!='e'; ++s) ! 503: ; ! 504: if(*s == 'e') ! 505: *s = 'd'; ! 506: else e->leftp = conrep(e->leftp,"d0"); ! 507: goto settype; ! 508: } ! 509: e = mkcall(builtin(TYLREAL,"dble"), arg1(e)); ! 510: break; ! 511: ! 512: case TYINT TO TYCOMPLEX: ! 513: case TYLREAL TO TYCOMPLEX: ! 514: e = coerce(TYREAL, e); ! 515: case TYREAL TO TYCOMPLEX: ! 516: if(e->tag == TCONST) ! 517: { ! 518: sprintf(buff, "(%s,0.)", e->leftp); ! 519: cfree(e->leftp); ! 520: e->leftp = (int *)copys(buff); ! 521: goto settype; ! 522: } ! 523: else ! 524: e = mkcall(builtin(TYCOMPLEX,"cmplx"), ! 525: arg2(e, mkconst(TYREAL,"0."))); ! 526: break; ! 527: ! 528: ! 529: default: ! 530: goto mismatch; ! 531: } ! 532: ! 533: return(e); ! 534: ! 535: ! 536: mismatch: ! 537: exprerr("impossible conversion", ""); ! 538: frexpr(e); ! 539: return( errnode() ); ! 540: ! 541: ! 542: settype: ! 543: e->vtype = t; ! 544: return(e); ! 545: } ! 546: ! 547: ! 548: ! 549: /* check whether expression is in form c, v, or v*c */ ! 550: cvform(p) ! 551: register ptr p; ! 552: { ! 553: switch(p->tag) ! 554: { ! 555: case TCONST: ! 556: return(p->vtype == TYINT); ! 557: ! 558: case TNAME: ! 559: return(vform(p)); ! 560: ! 561: case TAROP: ! 562: if(p->subtype==OPSTAR && ((struct headbits *)p->rightp)->tag==TCONST ! 563: && ((struct exprblock *)p->rightp)->vtype==TYINT && vform(p->leftp)) ! 564: return(1); ! 565: ! 566: default: ! 567: return(0); ! 568: } ! 569: } ! 570: ! 571: ! 572: ! 573: ! 574: /* is p a simple integer variable */ ! 575: vform(p) ! 576: register ptr p; ! 577: { ! 578: return( p->tag==TNAME && p->vtype==TYINT && p->vdim==0 ! 579: && p->voffset==0 && p->vsubs==0) ; ! 580: } ! 581: ! 582: ! 583: ! 584: ptr dblop(p) ! 585: ptr p; ! 586: { ! 587: ptr q; ! 588: ! 589: bgnexec(); ! 590: if(p->subtype == OP2OR) ! 591: q = mknode(TNOTOP,OPNOT, cpexpr(p->leftp), PNULL); ! 592: else q = cpexpr(p->leftp); ! 593: ! 594: pushctl(STIF, q); ! 595: bgnexec(); ! 596: exasgn(cpexpr(p->leftp), OPASGN, p->rightp); ! 597: ifthen(); ! 598: popctl(); ! 599: addexec(); ! 600: return(p->leftp); ! 601: } ! 602: ! 603: ! 604: ! 605: ! 606: divides(a,b) ! 607: ptr a; ! 608: int b; ! 609: { ! 610: if(a->vtype!=TYINT) ! 611: return(0); ! 612: ! 613: switch(a->tag) ! 614: { ! 615: case TNEGOP: ! 616: return( divides(a->leftp,b) ); ! 617: ! 618: case TCONST: ! 619: return( conval(a) % b == 0); ! 620: ! 621: case TAROP: ! 622: switch(a->subtype) ! 623: { ! 624: case OPPLUS: ! 625: case OPMINUS: ! 626: return(divides(a->leftp,b)&& ! 627: divides(a->rightp,b) ); ! 628: ! 629: case OPSTAR: ! 630: return(divides(a->rightp,b)); ! 631: ! 632: default: ! 633: return(0); ! 634: } ! 635: default: ! 636: return(0); ! 637: } ! 638: /* NOTREACHED */ ! 639: } ! 640: ! 641: /* truncate floating point constant to integer */ ! 642: ! 643: #define MAXD 100 ! 644: ! 645: ptr xfixf(e) ! 646: struct exprblock *e; ! 647: { ! 648: char digit[MAXD+1]; /* buffer into which digits are placed */ ! 649: char *first; /* points to first nonzero digit */ ! 650: register char *end; /* points at position past last digit */ ! 651: register char *dot; /* decimal point is immediately to left of this digit */ ! 652: register char *s; ! 653: int expon; ! 654: ! 655: dot = NULL; ! 656: end = digit; ! 657: expon = 0; ! 658: ! 659: for(s = (char *)e->leftp ; *s; ++s) ! 660: if( isdigit(*s) ) ! 661: { ! 662: if(end-digit > MAXD) ! 663: return((int *)e); ! 664: *end++ = *s; ! 665: } ! 666: else if(*s == '.') ! 667: dot = end; ! 668: else if(*s=='d' || *s=='e') ! 669: { ! 670: expon = convci(s+1); ! 671: break; ! 672: } ! 673: else fatal1("impossible character %d in floating constant", *s); ! 674: ! 675: if(dot == NULL) ! 676: dot = end; ! 677: dot += expon; ! 678: if(dot-digit > MAXD) ! 679: return((int *)e); ! 680: for(first = digit; first<end && *first=='0' ; ++first) ! 681: ; ! 682: if(dot<=first) ! 683: { ! 684: dot = first+1; ! 685: *first = '0'; ! 686: } ! 687: else while(end < dot) ! 688: *end++ = '0'; ! 689: *dot = '\0'; ! 690: cfree(e->leftp); ! 691: e->leftp = (int *)copys(first); ! 692: e->vtype = TYINT; ! 693: return((int *)e); ! 694: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.