|
|
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 = copys(".true."); ! 76: else if(equals(lp->leftp, ".true.")) ! 77: e->leftp = 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: if(tag==TAROP && (subtype==OPPLUS || subtype==OPMINUS)) ! 214: if(rp->tag==TCONST && rp->vtype==TYINT) ! 215: { ! 216: if(!cvform(lp)) ! 217: e->leftp = simple(SUBVAL, lp); ! 218: } ! 219: else goto makesub; ! 220: else if( !cvform(e) ) goto makesub; ! 221: } ! 222: break; ! 223: ! 224: case TCALL: ! 225: if( lp->tag!=TFTNBLOCK && ioop(lp->sthead->namep) ) ! 226: { ! 227: e = exioop(e, YES); ! 228: exlab(0); ! 229: break; ! 230: } ! 231: e->rightp = simple(RVAL, rp); ! 232: if(t == SUBVAL) ! 233: goto makesub; ! 234: if(t == LVAL) ! 235: e = simple(RVAL, mknode(TASGNOP,0, gentemp(e),e)); ! 236: break; ! 237: ! 238: ! 239: case TNAME: ! 240: if(e->voffset) ! 241: fixsubs(e); ! 242: if(e->vsubs) ! 243: e->vsubs = simple(SUBVAL, e->vsubs); ! 244: if(t==SUBVAL && !vform(e)) ! 245: goto makesub; ! 246: ! 247: case TTEMP: ! 248: case TFTNBLOCK: ! 249: case TCONST: ! 250: if(t==SUBVAL && e->vtype!=TYINT) ! 251: goto makesub; ! 252: break; ! 253: ! 254: case TASGNOP: ! 255: lp = e->leftp = simple(LVAL,lp); ! 256: if(subtype==OP2OR || subtype==OP2AND) ! 257: e = dblop(e); ! 258: ! 259: else { ! 260: rp = e->rightp = simple(RVAL,rp); ! 261: if(e->vtype == TYCHAR) ! 262: excall(mkcall(mkftnblock(TYSUBR,"ef1asc"), arg4(cpexpr(lp),rp))); ! 263: else if(e->vtype == TYSTRUCT) ! 264: { ! 265: if(lp->vtypep->strsize != rp->vtypep->strsize) ! 266: fatal("simple: attempt to assign incompatible structures"); ! 267: e1 = mkchain(cpexpr(lp),mkchain(rp, ! 268: mkchain(mkint(lp->vtypep->strsize),CHNULL))); ! 269: excall(mkcall(mkftnblock(TYSUBR,"ef1ass"), ! 270: mknode(TLIST, 0, e1, PNULL) )); ! 271: } ! 272: else if(lp->vtype == TYFIELD) ! 273: lp = setfield(e); ! 274: else { ! 275: if(subtype != OPASGN) /* but is one of += etc */ ! 276: { ! 277: rp = e->rightp = simple(RVAL, mknode( ! 278: (subtype<=OPPOWER?TAROP:TLOGOP),subtype, ! 279: cpexpr(e->leftp),e->rightp)); ! 280: e->subtype = OPASGN; ! 281: } ! 282: exlab(0); ! 283: prexpr(e); ! 284: frexpr(rp); ! 285: } ! 286: frexpblock(e); ! 287: e = lp; ! 288: if(t == SUBVAL) goto top; ! 289: } ! 290: ! 291: break; ! 292: ! 293: case TLIST: ! 294: for(p=lp ; p ; p = p->nextp) ! 295: p->datap = simple(t, p->datap); ! 296: break; ! 297: ! 298: case TIOSTAT: ! 299: e = exio(e, 1); ! 300: break; ! 301: ! 302: default: ! 303: break; ! 304: } ! 305: ! 306: return(e); ! 307: ! 308: ! 309: typerr: ! 310: exprerr("type match error", CNULL); ! 311: return(e); ! 312: ! 313: makesub: ! 314: if(t==SUBVAL && e->vtype!=TYINT) ! 315: warn1("Line %d. Non-integer subscript", yylineno); ! 316: return( simple(RVAL, mknode(TASGNOP,0,gent(TYINT,PNULL),e)) ); ! 317: } ! 318: ! 319: ptr fold(e) ! 320: register ptr e; ! 321: { ! 322: int a, b, c; ! 323: register ptr lp, rp; ! 324: ! 325: lp = e->leftp; ! 326: rp = e->rightp; ! 327: ! 328: if(lp->tag!=TCONST && lp->tag!=TNEGOP) ! 329: return(e); ! 330: ! 331: if(rp->tag!=TCONST && rp->tag!=TNEGOP) ! 332: return(e); ! 333: ! 334: ! 335: switch(e->tag) ! 336: { ! 337: case TAROP: ! 338: if( !isicon(lp,&a) || !isicon(rp,&b) ) ! 339: return(e); ! 340: ! 341: switch(e->subtype) ! 342: { ! 343: case OPPLUS: ! 344: c = a + b;break; ! 345: case OPMINUS: ! 346: c = a - b; break; ! 347: case OPSTAR: ! 348: c = a * b; break; ! 349: case OPSLASH: ! 350: if(a%b!=0 && (a<0 || b<0) ) ! 351: return(e); ! 352: c = a / b; break; ! 353: case OPPOWER: ! 354: return(e); ! 355: default: ! 356: fatal("fold: illegal binary operator"); ! 357: } ! 358: frexpr(e); ! 359: ! 360: if(c >= 0) ! 361: return( mkint(c) ); ! 362: else return(mknode(TNEGOP,OPMINUS, mkint(-c), PNULL) ); ! 363: ! 364: case TRELOP: ! 365: if( !isicon(lp,&a) || !isicon(rp,&b) ) ! 366: return(e); ! 367: frexpr(e); ! 368: ! 369: switch(e->subtype) ! 370: { ! 371: case OPEQ: ! 372: c = a == b; break; ! 373: case OPLT: ! 374: c = a < b ; break; ! 375: case OPGT: ! 376: c = a > b; break; ! 377: case OPLE: ! 378: c = a <= b; break; ! 379: case OPGE: ! 380: c = a >= b; break; ! 381: case OPNE: ! 382: c = a != b; break; ! 383: default: ! 384: fatal("fold: invalid relational operator"); ! 385: } ! 386: return( mkconst(TYLOG, (c ? ".true." : ".false.")) ); ! 387: ! 388: ! 389: case TLOGOP: ! 390: if(lp->vtype!=TYLOG || rp->vtype!=TYLOG) ! 391: return(e); ! 392: a = equals(lp->leftp, ".true."); ! 393: b = equals(rp->leftp, ".true."); ! 394: frexpr(e); ! 395: ! 396: switch(e->subtype) ! 397: { ! 398: case OPAND: ! 399: case OP2AND: ! 400: c = a & b; break; ! 401: case OPOR: ! 402: case OP2OR: ! 403: c = a | b; break; ! 404: default: ! 405: fatal("fold: invalid logical operator"); ! 406: } ! 407: return( mkconst(TYLOG, (c? ".true." : ".false")) ); ! 408: ! 409: default: ! 410: return(e); ! 411: } ! 412: } ! 413: ! 414: #define TO + 100* ! 415: ! 416: ! 417: ptr coerce(t,e) /* coerce expression e to type t */ ! 418: int t; ! 419: register ptr e; ! 420: { ! 421: register int et; ! 422: int econst; ! 423: char buff[100]; ! 424: char *s, *s1; ! 425: ptr conrep(), xfixf(); ! 426: ! 427: if(e->tag == TNEGOP) ! 428: { ! 429: e->leftp = coerce(t, e->leftp); ! 430: goto settype; ! 431: } ! 432: ! 433: et = e->vtype; ! 434: econst = (e->tag == TCONST); ! 435: TEST fprintf(diagfile, "coerce type %d to type %d\n", et, t); ! 436: if(t == et) ! 437: return(e); ! 438: ! 439: switch( et TO t ) ! 440: { ! 441: case TYCOMPLEX TO TYINT: ! 442: case TYLREAL TO TYINT: ! 443: e = coerce(TYREAL,e); ! 444: case TYREAL TO TYINT: ! 445: if(econst) ! 446: e = xfixf(e); ! 447: if(e->vtype != TYINT) ! 448: e = mkcall(builtin(TYINT,"ifix"), arg1(e)); ! 449: break; ! 450: ! 451: case TYINT TO TYREAL: ! 452: if(econst) ! 453: { ! 454: e->leftp = conrep(e->leftp, "."); ! 455: goto settype; ! 456: } ! 457: e = mkcall(builtin(TYREAL,"float"), arg1(e)); ! 458: break; ! 459: ! 460: case TYLREAL TO TYREAL: ! 461: if(econst) ! 462: { ! 463: for(s=e->leftp ; *s && *s!='d';++s) ! 464: ; ! 465: *s = 'e'; ! 466: goto settype; ! 467: } ! 468: e = mkcall(builtin(TYREAL,"sngl"), arg1(e)); ! 469: break; ! 470: ! 471: case TYCOMPLEX TO TYREAL: ! 472: if(econst) ! 473: { ! 474: s1 = (char *)(e->leftp) + 1; ! 475: s = buff; ! 476: while(*s1!=',' && *s1!='\0') ! 477: *s1++ = *s++; ! 478: *s = '\0'; ! 479: cfree(e->leftp); ! 480: e->leftp = copys(buff); ! 481: goto settype; ! 482: } ! 483: else ! 484: e = mkcall(mkftnblock(TYREAL,"real"), arg1(e)); ! 485: break; ! 486: ! 487: case TYINT TO TYLREAL: ! 488: if(econst) ! 489: { ! 490: e->leftp = conrep(e->leftp,"d0"); ! 491: goto settype; ! 492: } ! 493: case TYCOMPLEX TO TYLREAL: ! 494: e = coerce(TYREAL,e); ! 495: case TYREAL TO TYLREAL: ! 496: if(econst) ! 497: { ! 498: for(s=e->leftp ; *s && *s!='e'; ++s) ! 499: ; ! 500: if(*s == 'e') ! 501: *s = 'd'; ! 502: else e->leftp = conrep(e->leftp,"d0"); ! 503: goto settype; ! 504: } ! 505: e = mkcall(builtin(TYLREAL,"dble"), arg1(e)); ! 506: break; ! 507: ! 508: case TYINT TO TYCOMPLEX: ! 509: case TYLREAL TO TYCOMPLEX: ! 510: e = coerce(TYREAL, e); ! 511: case TYREAL TO TYCOMPLEX: ! 512: if(e->tag == TCONST) ! 513: { ! 514: sprintf(buff, "(%s,0.)", e->leftp); ! 515: cfree(e->leftp); ! 516: e->leftp = copys(buff); ! 517: goto settype; ! 518: } ! 519: else ! 520: e = mkcall(builtin(TYCOMPLEX,"cmplx"), ! 521: arg2(e, mkconst(TYREAL,"0."))); ! 522: break; ! 523: ! 524: ! 525: default: ! 526: goto mismatch; ! 527: } ! 528: ! 529: return(e); ! 530: ! 531: ! 532: mismatch: ! 533: exprerr("impossible conversion", ""); ! 534: frexpr(e); ! 535: return( errnode() ); ! 536: ! 537: ! 538: settype: ! 539: e->vtype = t; ! 540: return(e); ! 541: } ! 542: ! 543: ! 544: ! 545: /* check whether expression is in form c, v, or v*c */ ! 546: cvform(p) ! 547: register ptr p; ! 548: { ! 549: switch(p->tag) ! 550: { ! 551: case TCONST: ! 552: return(p->vtype == TYINT); ! 553: ! 554: case TNAME: ! 555: return(vform(p)); ! 556: ! 557: case TAROP: ! 558: if(p->subtype==OPSTAR && p->rightp->tag==TCONST ! 559: && p->rightp->vtype==TYINT && vform(p->leftp)) ! 560: return(1); ! 561: ! 562: default: ! 563: return(0); ! 564: } ! 565: } ! 566: ! 567: ! 568: ! 569: ! 570: /* is p a simple integer variable */ ! 571: vform(p) ! 572: register ptr p; ! 573: { ! 574: return( p->tag==TNAME && p->vtype==TYINT && p->vdim==0 ! 575: && p->voffset==0 && p->vsubs==0) ; ! 576: } ! 577: ! 578: ! 579: ! 580: ptr dblop(p) ! 581: ptr p; ! 582: { ! 583: ptr q; ! 584: ! 585: bgnexec(); ! 586: if(p->subtype == OP2OR) ! 587: q = mknode(TNOTOP,OPNOT, cpexpr(p->leftp), PNULL); ! 588: else q = cpexpr(p->leftp); ! 589: ! 590: pushctl(STIF, q); ! 591: bgnexec(); ! 592: exasgn(cpexpr(p->leftp), OPASGN, p->rightp); ! 593: ifthen(); ! 594: popctl(); ! 595: addexec(); ! 596: return(p->leftp); ! 597: } ! 598: ! 599: ! 600: ! 601: ! 602: divides(a,b) ! 603: ptr a; ! 604: int b; ! 605: { ! 606: if(a->vtype!=TYINT) ! 607: return(0); ! 608: ! 609: switch(a->tag) ! 610: { ! 611: case TNEGOP: ! 612: return( divides(a->leftp,b) ); ! 613: ! 614: case TCONST: ! 615: return( conval(a) % b == 0); ! 616: ! 617: case TAROP: ! 618: switch(a->subtype) ! 619: { ! 620: case OPPLUS: ! 621: case OPMINUS: ! 622: return(divides(a->leftp,b)&& ! 623: divides(a->rightp,b) ); ! 624: ! 625: case OPSTAR: ! 626: return(divides(a->rightp,b)); ! 627: ! 628: default: ! 629: return(0); ! 630: } ! 631: default: ! 632: return(0); ! 633: } ! 634: /* NOTREACHED */ ! 635: } ! 636: ! 637: /* truncate floating point constant to integer */ ! 638: ! 639: #define MAXD 100 ! 640: ! 641: ptr xfixf(e) ! 642: struct exprblock *e; ! 643: { ! 644: char digit[MAXD+1]; /* buffer into which digits are placed */ ! 645: char *first; /* points to first nonzero digit */ ! 646: register char *end; /* points at position past last digit */ ! 647: register char *dot; /* decimal point is immediately to left of this digit */ ! 648: register char *s; ! 649: int expon; ! 650: ! 651: dot = NULL; ! 652: end = digit; ! 653: expon = 0; ! 654: ! 655: for(s = e->leftp ; *s; ++s) ! 656: if( isdigit(*s) ) ! 657: { ! 658: if(end-digit > MAXD) ! 659: return(e); ! 660: *end++ = *s; ! 661: } ! 662: else if(*s == '.') ! 663: dot = end; ! 664: else if(*s=='d' || *s=='e') ! 665: { ! 666: expon = convci(s+1); ! 667: break; ! 668: } ! 669: else fatal1("impossible character %d in floating constant", *s); ! 670: ! 671: if(dot == NULL) ! 672: dot = end; ! 673: dot += expon; ! 674: if(dot-digit > MAXD) ! 675: return(e); ! 676: for(first = digit; first<end && *first=='0' ; ++first) ! 677: ; ! 678: if(dot<=first) ! 679: { ! 680: dot = first+1; ! 681: *first = '0'; ! 682: } ! 683: else while(end < dot) ! 684: *end++ = '0'; ! 685: *dot = '\0'; ! 686: cfree(e->leftp); ! 687: e->leftp = copys(first); ! 688: e->vtype = TYINT; ! 689: return(e); ! 690: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.