1: #include "defs" 2: 3: union 4: { 5: int ijunk; 6: struct intrpacked bits; 7: } packed; 8: 9: struct intrbits 10: { 11: int intrgroup /* :3 */; 12: int intrstuff /* result type or number of generics */; 13: int intrno /* :7 */; 14: }; 15: 16: LOCAL struct intrblock 17: { 18: char intrfname[VL]; 19: struct intrbits intrval; 20: } intrtab[ ] = 21: { 22: "int", { INTRCONV, TYLONG }, 23: "real", { INTRCONV, TYREAL }, 24: "dble", { INTRCONV, TYDREAL }, 25: "cmplx", { INTRCONV, TYCOMPLEX }, 26: "dcmplx", { INTRCONV, TYDCOMPLEX }, 27: "ifix", { INTRCONV, TYLONG }, 28: "idint", { INTRCONV, TYLONG }, 29: "float", { INTRCONV, TYREAL }, 30: "dfloat", { INTRCONV, TYDREAL }, 31: "sngl", { INTRCONV, TYREAL }, 32: "ichar", { INTRCONV, TYLONG }, 33: "char", { INTRCONV, TYCHAR }, 34: 35: "max", { INTRMAX, TYUNKNOWN }, 36: "max0", { INTRMAX, TYLONG }, 37: "amax0", { INTRMAX, TYREAL }, 38: "max1", { INTRMAX, TYLONG }, 39: "amax1", { INTRMAX, TYREAL }, 40: "dmax1", { INTRMAX, TYDREAL }, 41: 42: "and", { INTRBOOL, TYUNKNOWN, OPBITAND }, 43: "or", { INTRBOOL, TYUNKNOWN, OPBITOR }, 44: "xor", { INTRBOOL, TYUNKNOWN, OPBITXOR }, 45: "not", { INTRBOOL, TYUNKNOWN, OPBITNOT }, 46: "lshift", { INTRBOOL, TYUNKNOWN, OPLSHIFT }, 47: "rshift", { INTRBOOL, TYUNKNOWN, OPRSHIFT }, 48: 49: "min", { INTRMIN, TYUNKNOWN }, 50: "min0", { INTRMIN, TYLONG }, 51: "amin0", { INTRMIN, TYREAL }, 52: "min1", { INTRMIN, TYLONG }, 53: "amin1", { INTRMIN, TYREAL }, 54: "dmin1", { INTRMIN, TYDREAL }, 55: 56: "aint", { INTRGEN, 2, 0 }, 57: "dint", { INTRSPEC, TYDREAL, 1 }, 58: 59: "anint", { INTRGEN, 2, 2 }, 60: "dnint", { INTRSPEC, TYDREAL, 3 }, 61: 62: "nint", { INTRGEN, 4, 4 }, 63: "idnint", { INTRGEN, 2, 6 }, 64: 65: "abs", { INTRGEN, 6, 8 }, 66: "iabs", { INTRGEN, 2, 9 }, 67: "dabs", { INTRSPEC, TYDREAL, 11 }, 68: "cabs", { INTRSPEC, TYREAL, 12 }, 69: "zabs", { INTRSPEC, TYDREAL, 13 }, 70: 71: "mod", { INTRGEN, 4, 14 }, 72: "amod", { INTRSPEC, TYREAL, 16 }, 73: "dmod", { INTRSPEC, TYDREAL, 17 }, 74: 75: "sign", { INTRGEN, 4, 18 }, 76: "isign", { INTRGEN, 2, 19 }, 77: "dsign", { INTRSPEC, TYDREAL, 21 }, 78: 79: "dim", { INTRGEN, 4, 22 }, 80: "idim", { INTRGEN, 2, 23 }, 81: "ddim", { INTRSPEC, TYDREAL, 25 }, 82: 83: "dprod", { INTRSPEC, TYDREAL, 26 }, 84: 85: "len", { INTRSPEC, TYLONG, 27 }, 86: "index", { INTRSPEC, TYLONG, 29 }, 87: 88: "imag", { INTRGEN, 2, 31 }, 89: "aimag", { INTRSPEC, TYREAL, 31 }, 90: "dimag", { INTRSPEC, TYDREAL, 32 }, 91: 92: "conjg", { INTRGEN, 2, 33 }, 93: "dconjg", { INTRSPEC, TYDCOMPLEX, 34 }, 94: 95: "sqrt", { INTRGEN, 4, 35 }, 96: "dsqrt", { INTRSPEC, TYDREAL, 36 }, 97: "csqrt", { INTRSPEC, TYCOMPLEX, 37 }, 98: "zsqrt", { INTRSPEC, TYDCOMPLEX, 38 }, 99: 100: "exp", { INTRGEN, 4, 39 }, 101: "dexp", { INTRSPEC, TYDREAL, 40 }, 102: "cexp", { INTRSPEC, TYCOMPLEX, 41 }, 103: "zexp", { INTRSPEC, TYDCOMPLEX, 42 }, 104: 105: "log", { INTRGEN, 4, 43 }, 106: "alog", { INTRSPEC, TYREAL, 43 }, 107: "dlog", { INTRSPEC, TYDREAL, 44 }, 108: "clog", { INTRSPEC, TYCOMPLEX, 45 }, 109: "zlog", { INTRSPEC, TYDCOMPLEX, 46 }, 110: 111: "log10", { INTRGEN, 2, 47 }, 112: "alog10", { INTRSPEC, TYREAL, 47 }, 113: "dlog10", { INTRSPEC, TYDREAL, 48 }, 114: 115: "sin", { INTRGEN, 4, 49 }, 116: "dsin", { INTRSPEC, TYDREAL, 50 }, 117: "csin", { INTRSPEC, TYCOMPLEX, 51 }, 118: "zsin", { INTRSPEC, TYDCOMPLEX, 52 }, 119: 120: "cos", { INTRGEN, 4, 53 }, 121: "dcos", { INTRSPEC, TYDREAL, 54 }, 122: "ccos", { INTRSPEC, TYCOMPLEX, 55 }, 123: "zcos", { INTRSPEC, TYDCOMPLEX, 56 }, 124: 125: "tan", { INTRGEN, 2, 57 }, 126: "dtan", { INTRSPEC, TYDREAL, 58 }, 127: 128: "asin", { INTRGEN, 2, 59 }, 129: "dasin", { INTRSPEC, TYDREAL, 60 }, 130: 131: "acos", { INTRGEN, 2, 61 }, 132: "dacos", { INTRSPEC, TYDREAL, 62 }, 133: 134: "atan", { INTRGEN, 2, 63 }, 135: "datan", { INTRSPEC, TYDREAL, 64 }, 136: 137: "atan2", { INTRGEN, 2, 65 }, 138: "datan2", { INTRSPEC, TYDREAL, 66 }, 139: 140: "sinh", { INTRGEN, 2, 67 }, 141: "dsinh", { INTRSPEC, TYDREAL, 68 }, 142: 143: "cosh", { INTRGEN, 2, 69 }, 144: "dcosh", { INTRSPEC, TYDREAL, 70 }, 145: 146: "tanh", { INTRGEN, 2, 71 }, 147: "dtanh", { INTRSPEC, TYDREAL, 72 }, 148: 149: "lge", { INTRSPEC, TYLOGICAL, 73}, 150: "lgt", { INTRSPEC, TYLOGICAL, 75}, 151: "lle", { INTRSPEC, TYLOGICAL, 77}, 152: "llt", { INTRSPEC, TYLOGICAL, 79}, 153: 154: "" }; 155: 156: 157: LOCAL struct specblock 158: { 159: char atype; 160: char rtype; 161: char nargs; 162: char spxname[XL]; 163: char othername; /* index into callbyvalue table */ 164: } spectab[ ] = 165: { 166: { TYREAL,TYREAL,1,"r_int" }, 167: { TYDREAL,TYDREAL,1,"d_int" }, 168: 169: { TYREAL,TYREAL,1,"r_nint" }, 170: { TYDREAL,TYDREAL,1,"d_nint" }, 171: 172: { TYREAL,TYSHORT,1,"h_nint" }, 173: { TYREAL,TYLONG,1,"i_nint" }, 174: 175: { TYDREAL,TYSHORT,1,"h_dnnt" }, 176: { TYDREAL,TYLONG,1,"i_dnnt" }, 177: 178: { TYREAL,TYREAL,1,"r_abs" }, 179: { TYSHORT,TYSHORT,1,"h_abs" }, 180: { TYLONG,TYLONG,1,"i_abs" }, 181: { TYDREAL,TYDREAL,1,"d_abs" }, 182: { TYCOMPLEX,TYREAL,1,"c_abs" }, 183: { TYDCOMPLEX,TYDREAL,1,"z_abs" }, 184: 185: { TYSHORT,TYSHORT,2,"h_mod" }, 186: { TYLONG,TYLONG,2,"i_mod" }, 187: { TYREAL,TYREAL,2,"r_mod" }, 188: { TYDREAL,TYDREAL,2,"d_mod" }, 189: 190: { TYREAL,TYREAL,2,"r_sign" }, 191: { TYSHORT,TYSHORT,2,"h_sign" }, 192: { TYLONG,TYLONG,2,"i_sign" }, 193: { TYDREAL,TYDREAL,2,"d_sign" }, 194: 195: { TYREAL,TYREAL,2,"r_dim" }, 196: { TYSHORT,TYSHORT,2,"h_dim" }, 197: { TYLONG,TYLONG,2,"i_dim" }, 198: { TYDREAL,TYDREAL,2,"d_dim" }, 199: 200: { TYREAL,TYDREAL,2,"d_prod" }, 201: 202: { TYCHAR,TYSHORT,1,"h_len" }, 203: { TYCHAR,TYLONG,1,"i_len" }, 204: 205: { TYCHAR,TYSHORT,2,"h_indx" }, 206: { TYCHAR,TYLONG,2,"i_indx" }, 207: 208: { TYCOMPLEX,TYREAL,1,"r_imag" }, 209: { TYDCOMPLEX,TYDREAL,1,"d_imag" }, 210: { TYCOMPLEX,TYCOMPLEX,1,"r_cnjg" }, 211: { TYDCOMPLEX,TYDCOMPLEX,1,"d_cnjg" }, 212: 213: { TYREAL,TYREAL,1,"r_sqrt", 1 }, 214: { TYDREAL,TYDREAL,1,"d_sqrt", 1 }, 215: { TYCOMPLEX,TYCOMPLEX,1,"c_sqrt" }, 216: { TYDCOMPLEX,TYDCOMPLEX,1,"z_sqrt" }, 217: 218: { TYREAL,TYREAL,1,"r_exp", 2 }, 219: { TYDREAL,TYDREAL,1,"d_exp", 2 }, 220: { TYCOMPLEX,TYCOMPLEX,1,"c_exp" }, 221: { TYDCOMPLEX,TYDCOMPLEX,1,"z_exp" }, 222: 223: { TYREAL,TYREAL,1,"r_log", 3 }, 224: { TYDREAL,TYDREAL,1,"d_log", 3 }, 225: { TYCOMPLEX,TYCOMPLEX,1,"c_log" }, 226: { TYDCOMPLEX,TYDCOMPLEX,1,"z_log" }, 227: 228: { TYREAL,TYREAL,1,"r_lg10" }, 229: { TYDREAL,TYDREAL,1,"d_lg10" }, 230: 231: { TYREAL,TYREAL,1,"r_sin", 4 }, 232: { TYDREAL,TYDREAL,1,"d_sin", 4 }, 233: { TYCOMPLEX,TYCOMPLEX,1,"c_sin" }, 234: { TYDCOMPLEX,TYDCOMPLEX,1,"z_sin" }, 235: 236: { TYREAL,TYREAL,1,"r_cos", 5 }, 237: { TYDREAL,TYDREAL,1,"d_cos", 5 }, 238: { TYCOMPLEX,TYCOMPLEX,1,"c_cos" }, 239: { TYDCOMPLEX,TYDCOMPLEX,1,"z_cos" }, 240: 241: { TYREAL,TYREAL,1,"r_tan", 6 }, 242: { TYDREAL,TYDREAL,1,"d_tan", 6 }, 243: 244: { TYREAL,TYREAL,1,"r_asin", 7 }, 245: { TYDREAL,TYDREAL,1,"d_asin", 7 }, 246: 247: { TYREAL,TYREAL,1,"r_acos", 8 }, 248: { TYDREAL,TYDREAL,1,"d_acos", 8 }, 249: 250: { TYREAL,TYREAL,1,"r_atan", 9 }, 251: { TYDREAL,TYDREAL,1,"d_atan", 9 }, 252: 253: { TYREAL,TYREAL,2,"r_atn2", 10 }, 254: { TYDREAL,TYDREAL,2,"d_atn2", 10 }, 255: 256: { TYREAL,TYREAL,1,"r_sinh", 11 }, 257: { TYDREAL,TYDREAL,1,"d_sinh", 11 }, 258: 259: { TYREAL,TYREAL,1,"r_cosh", 12 }, 260: { TYDREAL,TYDREAL,1,"d_cosh", 12 }, 261: 262: { TYREAL,TYREAL,1,"r_tanh", 13 }, 263: { TYDREAL,TYDREAL,1,"d_tanh", 13 }, 264: 265: { TYCHAR,TYLOGICAL,2,"hl_ge" }, 266: { TYCHAR,TYLOGICAL,2,"l_ge" }, 267: 268: { TYCHAR,TYLOGICAL,2,"hl_gt" }, 269: { TYCHAR,TYLOGICAL,2,"l_gt" }, 270: 271: { TYCHAR,TYLOGICAL,2,"hl_le" }, 272: { TYCHAR,TYLOGICAL,2,"l_le" }, 273: 274: { TYCHAR,TYLOGICAL,2,"hl_lt" }, 275: { TYCHAR,TYLOGICAL,2,"l_lt" } 276: } ; 277: 278: 279: 280: 281: 282: 283: char callbyvalue[ ][XL] = 284: { 285: "sqrt", 286: "exp", 287: "log", 288: "sin", 289: "cos", 290: "tan", 291: "asin", 292: "acos", 293: "atan", 294: "atan2", 295: "sinh", 296: "cosh", 297: "tanh" 298: }; 299: 300: struct exprblock *intrcall(np, argsp, nargs) 301: struct nameblock *np; 302: struct listblock *argsp; 303: int nargs; 304: { 305: int i, rettype; 306: struct addrblock *ap; 307: register struct specblock *sp; 308: struct exprblock *q, *inline(); 309: register chainp cp; 310: struct constblock *mkcxcon(); 311: expptr ep; 312: int mtype; 313: int op; 314: 315: packed.ijunk = np->vardesc.varno; 316: if(nargs == 0) 317: goto badnargs; 318: 319: mtype = 0; 320: for(cp = argsp->listp ; cp ; cp = cp->nextp) 321: { 322: /* TEMPORARY */ ep = cp->datap; 323: /* TEMPORARY */ if( ISCONST(ep) && ep->vtype==TYSHORT ) 324: /* TEMPORARY */ cp->datap = mkconv(tyint, ep); 325: mtype = maxtype(mtype, ep->vtype); 326: } 327: 328: switch(packed.bits.f1) 329: { 330: case INTRBOOL: 331: op = packed.bits.f3; 332: if( ! ONEOF(mtype, MSKINT|MSKLOGICAL) ) 333: goto badtype; 334: if(op == OPBITNOT) 335: { 336: if(nargs != 1) 337: goto badnargs; 338: q = mkexpr(OPBITNOT, argsp->listp->datap, NULL); 339: } 340: else 341: { 342: if(nargs != 2) 343: goto badnargs; 344: q = mkexpr(op, argsp->listp->datap, 345: argsp->listp->nextp->datap); 346: } 347: frchain( &(argsp->listp) ); 348: free(argsp); 349: return(q); 350: 351: case INTRCONV: 352: rettype = packed.bits.f2; 353: if(rettype == TYLONG) 354: rettype = tyint; 355: if( ISCOMPLEX(rettype) && nargs==2) 356: { 357: expptr qr, qi; 358: qr = argsp->listp->datap; 359: qi = argsp->listp->nextp->datap; 360: if(ISCONST(qr) && ISCONST(qi)) 361: q = mkcxcon(qr,qi); 362: else q = mkexpr(OPCONV,mkconv(rettype-2,qr), 363: mkconv(rettype-2,qi)); 364: } 365: else if(nargs == 1) 366: q = mkconv(rettype, argsp->listp->datap); 367: else goto badnargs; 368: 369: q->vtype = rettype; 370: frchain(&(argsp->listp)); 371: free(argsp); 372: return(q); 373: 374: 375: case INTRGEN: 376: sp = spectab + packed.bits.f3; 377: for(i=0; i<packed.bits.f2 ; ++i) 378: if(sp->atype == mtype) 379: goto specfunct; 380: else 381: ++sp; 382: goto badtype; 383: 384: case INTRSPEC: 385: sp = spectab + packed.bits.f3; 386: if(tyint==TYLONG && sp->rtype==TYSHORT) 387: ++sp; 388: 389: specfunct: 390: if(nargs != sp->nargs) 391: goto badnargs; 392: if(mtype != sp->atype) 393: goto badtype; 394: fixargs(YES, argsp); 395: if(q = inline(sp-spectab, mtype, argsp->listp)) 396: { 397: frchain( &(argsp->listp) ); 398: free(argsp); 399: } 400: else if(sp->othername) 401: { 402: ap = builtin(sp->rtype, 403: varstr(XL, callbyvalue[sp->othername-1]) ); 404: q = fixexpr( mkexpr(OPCCALL, ap, argsp) ); 405: } 406: else 407: { 408: ap = builtin(sp->rtype, varstr(XL, sp->spxname) ); 409: q = fixexpr( mkexpr(OPCALL, ap, argsp) ); 410: } 411: return(q); 412: 413: case INTRMIN: 414: case INTRMAX: 415: if(nargs < 2) 416: goto badnargs; 417: if( ! ONEOF(mtype, MSKINT|MSKREAL) ) 418: goto badtype; 419: argsp->vtype = mtype; 420: q = mkexpr( (packed.bits.f1==INTRMIN ? OPMIN : OPMAX), argsp, NULL); 421: 422: q->vtype = mtype; 423: rettype = packed.bits.f2; 424: if(rettype == TYLONG) 425: rettype = tyint; 426: else if(rettype == TYUNKNOWN) 427: rettype = mtype; 428: return( mkconv(rettype, q) ); 429: 430: default: 431: fatal1("intrcall: bad intrgroup %d", packed.bits.f1); 432: } 433: badnargs: 434: err1("bad number of arguments to intrinsic %s", 435: varstr(VL,np->varname) ); 436: goto bad; 437: 438: badtype: 439: err1("bad argument type to intrinsic %s", varstr(VL, np->varname) ); 440: 441: bad: 442: return( errnode() ); 443: } 444: 445: 446: 447: 448: intrfunct(s) 449: char s[VL]; 450: { 451: register struct intrblock *p; 452: char nm[VL]; 453: register int i; 454: 455: for(i = 0 ; i<VL ; ++s) 456: nm[i++] = (*s==' ' ? '\0' : *s); 457: 458: for(p = intrtab; p->intrval.intrgroup!=INTREND ; ++p) 459: { 460: if( eqn(VL, nm, p->intrfname) ) 461: { 462: packed.bits.f1 = p->intrval.intrgroup; 463: packed.bits.f2 = p->intrval.intrstuff; 464: packed.bits.f3 = p->intrval.intrno; 465: return(packed.ijunk); 466: } 467: } 468: 469: return(0); 470: } 471: 472: 473: 474: 475: 476: struct addrblock *intraddr(np) 477: struct nameblock *np; 478: { 479: struct addrblock *q; 480: struct specblock *sp; 481: 482: if(np->vclass!=CLPROC || np->vprocclass!=PINTRINSIC) 483: fatal1("intraddr: %s is not intrinsic", varstr(VL,np->varname)); 484: packed.ijunk = np->vardesc.varno; 485: 486: switch(packed.bits.f1) 487: { 488: case INTRGEN: 489: /* imag, log, and log10 arent specific functions */ 490: if(packed.bits.f3==31 || packed.bits.f3==43 || packed.bits.f3==47) 491: goto bad; 492: 493: case INTRSPEC: 494: sp = spectab + packed.bits.f3; 495: if(tyint==TYLONG && sp->rtype==TYSHORT) 496: ++sp; 497: q = builtin(sp->rtype, varstr(XL,sp->spxname) ); 498: return(q); 499: 500: case INTRCONV: 501: case INTRMIN: 502: case INTRMAX: 503: case INTRBOOL: 504: bad: 505: err1("cannot pass %s as actual", 506: varstr(VL,np->varname)); 507: return( errnode() ); 508: } 509: fatal1("intraddr: impossible f1=%d\n", packed.bits.f1); 510: /* NOTREACHED */ 511: } 512: 513: 514: 515: 516: 517: struct exprblock *inline(fno, type, args) 518: int fno; 519: int type; 520: chainp args; 521: { 522: register struct exprblock *q, *t, *t1; 523: 524: switch(fno) 525: { 526: case 8: /* real abs */ 527: case 9: /* short int abs */ 528: case 10: /* long int abs */ 529: case 11: /* double precision abs */ 530: if( addressable(q = args->datap) ) 531: { 532: t = q; 533: q = NULL; 534: } 535: else 536: t = mktemp(type); 537: t1 = mkexpr(OPQUEST, mkexpr(OPLE, mkconv(type,ICON(0)), cpexpr(t)), 538: mkexpr(OPCOLON, cpexpr(t), 539: mkexpr(OPNEG, cpexpr(t), NULL) )); 540: if(q) 541: t1 = mkexpr(OPCOMMA, mkexpr(OPASSIGN, cpexpr(t),q), t1); 542: frexpr(t); 543: return(t1); 544: 545: case 26: /* dprod */ 546: q = mkexpr(OPSTAR, args->datap, args->nextp->datap); 547: q->vtype = TYDREAL; 548: return(q); 549: 550: case 27: /* len of character string */ 551: q = cpexpr(args->datap->vleng); 552: frexpr(args->datap); 553: return(q); 554: 555: case 14: /* half-integer mod */ 556: case 15: /* mod */ 557: return( mkexpr(OPMOD, args->datap, args->nextp->datap) ); 558: } 559: return(NULL); 560: }