home *** CD-ROM | disk | FTP | other *** search
- #include "defs"
-
- union
- {
- int ijunk;
- struct intrpacked bits;
- } packed;
-
- struct intrbits
- {
- int intrgroup /* :3 */;
- int intrstuff /* result type or number of generics */;
- int intrno /* :7 */;
- };
-
- LOCAL struct intrblock
- {
- char intrfname[VL];
- struct intrbits intrval;
- } intrtab[ ] =
- {
- "int", { INTRCONV, TYLONG },
- "real", { INTRCONV, TYREAL },
- "dble", { INTRCONV, TYDREAL },
- "cmplx", { INTRCONV, TYCOMPLEX },
- "dcmplx", { INTRCONV, TYDCOMPLEX },
- "ifix", { INTRCONV, TYLONG },
- "idint", { INTRCONV, TYLONG },
- "float", { INTRCONV, TYREAL },
- "dfloat", { INTRCONV, TYDREAL },
- "sngl", { INTRCONV, TYREAL },
- "ichar", { INTRCONV, TYLONG },
- "char", { INTRCONV, TYCHAR },
-
- "max", { INTRMAX, TYUNKNOWN },
- "max0", { INTRMAX, TYLONG },
- "amax0", { INTRMAX, TYREAL },
- "max1", { INTRMAX, TYLONG },
- "amax1", { INTRMAX, TYREAL },
- "dmax1", { INTRMAX, TYDREAL },
-
- "and", { INTRBOOL, TYUNKNOWN, OPBITAND },
- "or", { INTRBOOL, TYUNKNOWN, OPBITOR },
- "xor", { INTRBOOL, TYUNKNOWN, OPBITXOR },
- "not", { INTRBOOL, TYUNKNOWN, OPBITNOT },
- "lshift", { INTRBOOL, TYUNKNOWN, OPLSHIFT },
- "rshift", { INTRBOOL, TYUNKNOWN, OPRSHIFT },
-
- "min", { INTRMIN, TYUNKNOWN },
- "min0", { INTRMIN, TYLONG },
- "amin0", { INTRMIN, TYREAL },
- "min1", { INTRMIN, TYLONG },
- "amin1", { INTRMIN, TYREAL },
- "dmin1", { INTRMIN, TYDREAL },
-
- "aint", { INTRGEN, 2, 0 },
- "dint", { INTRSPEC, TYDREAL, 1 },
-
- "anint", { INTRGEN, 2, 2 },
- "dnint", { INTRSPEC, TYDREAL, 3 },
-
- "nint", { INTRGEN, 4, 4 },
- "idnint", { INTRGEN, 2, 6 },
-
- "abs", { INTRGEN, 6, 8 },
- "iabs", { INTRGEN, 2, 9 },
- "dabs", { INTRSPEC, TYDREAL, 11 },
- "cabs", { INTRSPEC, TYREAL, 12 },
- "zabs", { INTRSPEC, TYDREAL, 13 },
-
- "mod", { INTRGEN, 4, 14 },
- "amod", { INTRSPEC, TYREAL, 16 },
- "dmod", { INTRSPEC, TYDREAL, 17 },
-
- "sign", { INTRGEN, 4, 18 },
- "isign", { INTRGEN, 2, 19 },
- "dsign", { INTRSPEC, TYDREAL, 21 },
-
- "dim", { INTRGEN, 4, 22 },
- "idim", { INTRGEN, 2, 23 },
- "ddim", { INTRSPEC, TYDREAL, 25 },
-
- "dprod", { INTRSPEC, TYDREAL, 26 },
-
- "len", { INTRSPEC, TYLONG, 27 },
- "index", { INTRSPEC, TYLONG, 29 },
-
- "imag", { INTRGEN, 2, 31 },
- "aimag", { INTRSPEC, TYREAL, 31 },
- "dimag", { INTRSPEC, TYDREAL, 32 },
-
- "conjg", { INTRGEN, 2, 33 },
- "dconjg", { INTRSPEC, TYDCOMPLEX, 34 },
-
- "sqrt", { INTRGEN, 4, 35 },
- "dsqrt", { INTRSPEC, TYDREAL, 36 },
- "csqrt", { INTRSPEC, TYCOMPLEX, 37 },
- "zsqrt", { INTRSPEC, TYDCOMPLEX, 38 },
-
- "exp", { INTRGEN, 4, 39 },
- "dexp", { INTRSPEC, TYDREAL, 40 },
- "cexp", { INTRSPEC, TYCOMPLEX, 41 },
- "zexp", { INTRSPEC, TYDCOMPLEX, 42 },
-
- "log", { INTRGEN, 4, 43 },
- "alog", { INTRSPEC, TYREAL, 43 },
- "dlog", { INTRSPEC, TYDREAL, 44 },
- "clog", { INTRSPEC, TYCOMPLEX, 45 },
- "zlog", { INTRSPEC, TYDCOMPLEX, 46 },
-
- "log10", { INTRGEN, 2, 47 },
- "alog10", { INTRSPEC, TYREAL, 47 },
- "dlog10", { INTRSPEC, TYDREAL, 48 },
-
- "sin", { INTRGEN, 4, 49 },
- "dsin", { INTRSPEC, TYDREAL, 50 },
- "csin", { INTRSPEC, TYCOMPLEX, 51 },
- "zsin", { INTRSPEC, TYDCOMPLEX, 52 },
-
- "cos", { INTRGEN, 4, 53 },
- "dcos", { INTRSPEC, TYDREAL, 54 },
- "ccos", { INTRSPEC, TYCOMPLEX, 55 },
- "zcos", { INTRSPEC, TYDCOMPLEX, 56 },
-
- "tan", { INTRGEN, 2, 57 },
- "dtan", { INTRSPEC, TYDREAL, 58 },
-
- "asin", { INTRGEN, 2, 59 },
- "dasin", { INTRSPEC, TYDREAL, 60 },
-
- "acos", { INTRGEN, 2, 61 },
- "dacos", { INTRSPEC, TYDREAL, 62 },
-
- "atan", { INTRGEN, 2, 63 },
- "datan", { INTRSPEC, TYDREAL, 64 },
-
- "atan2", { INTRGEN, 2, 65 },
- "datan2", { INTRSPEC, TYDREAL, 66 },
-
- "sinh", { INTRGEN, 2, 67 },
- "dsinh", { INTRSPEC, TYDREAL, 68 },
-
- "cosh", { INTRGEN, 2, 69 },
- "dcosh", { INTRSPEC, TYDREAL, 70 },
-
- "tanh", { INTRGEN, 2, 71 },
- "dtanh", { INTRSPEC, TYDREAL, 72 },
-
- "lge", { INTRSPEC, TYLOGICAL, 73},
- "lgt", { INTRSPEC, TYLOGICAL, 75},
- "lle", { INTRSPEC, TYLOGICAL, 77},
- "llt", { INTRSPEC, TYLOGICAL, 79},
-
- "" };
-
-
- LOCAL struct specblock
- {
- char atype;
- char rtype;
- char nargs;
- char spxname[XL];
- char othername; /* index into callbyvalue table */
- } spectab[ ] =
- {
- { TYREAL,TYREAL,1,"r_int" },
- { TYDREAL,TYDREAL,1,"d_int" },
-
- { TYREAL,TYREAL,1,"r_nint" },
- { TYDREAL,TYDREAL,1,"d_nint" },
-
- { TYREAL,TYSHORT,1,"h_nint" },
- { TYREAL,TYLONG,1,"i_nint" },
-
- { TYDREAL,TYSHORT,1,"h_dnnt" },
- { TYDREAL,TYLONG,1,"i_dnnt" },
-
- { TYREAL,TYREAL,1,"r_abs" },
- { TYSHORT,TYSHORT,1,"h_abs" },
- { TYLONG,TYLONG,1,"i_abs" },
- { TYDREAL,TYDREAL,1,"d_abs" },
- { TYCOMPLEX,TYREAL,1,"c_abs" },
- { TYDCOMPLEX,TYDREAL,1,"z_abs" },
-
- { TYSHORT,TYSHORT,2,"h_mod" },
- { TYLONG,TYLONG,2,"i_mod" },
- { TYREAL,TYREAL,2,"r_mod" },
- { TYDREAL,TYDREAL,2,"d_mod" },
-
- { TYREAL,TYREAL,2,"r_sign" },
- { TYSHORT,TYSHORT,2,"h_sign" },
- { TYLONG,TYLONG,2,"i_sign" },
- { TYDREAL,TYDREAL,2,"d_sign" },
-
- { TYREAL,TYREAL,2,"r_dim" },
- { TYSHORT,TYSHORT,2,"h_dim" },
- { TYLONG,TYLONG,2,"i_dim" },
- { TYDREAL,TYDREAL,2,"d_dim" },
-
- { TYREAL,TYDREAL,2,"d_prod" },
-
- { TYCHAR,TYSHORT,1,"h_len" },
- { TYCHAR,TYLONG,1,"i_len" },
-
- { TYCHAR,TYSHORT,2,"h_indx" },
- { TYCHAR,TYLONG,2,"i_indx" },
-
- { TYCOMPLEX,TYREAL,1,"r_imag" },
- { TYDCOMPLEX,TYDREAL,1,"d_imag" },
- { TYCOMPLEX,TYCOMPLEX,1,"r_cnjg" },
- { TYDCOMPLEX,TYDCOMPLEX,1,"d_cnjg" },
-
- { TYREAL,TYREAL,1,"r_sqrt", 1 },
- { TYDREAL,TYDREAL,1,"d_sqrt", 1 },
- { TYCOMPLEX,TYCOMPLEX,1,"c_sqrt" },
- { TYDCOMPLEX,TYDCOMPLEX,1,"z_sqrt" },
-
- { TYREAL,TYREAL,1,"r_exp", 2 },
- { TYDREAL,TYDREAL,1,"d_exp", 2 },
- { TYCOMPLEX,TYCOMPLEX,1,"c_exp" },
- { TYDCOMPLEX,TYDCOMPLEX,1,"z_exp" },
-
- { TYREAL,TYREAL,1,"r_log", 3 },
- { TYDREAL,TYDREAL,1,"d_log", 3 },
- { TYCOMPLEX,TYCOMPLEX,1,"c_log" },
- { TYDCOMPLEX,TYDCOMPLEX,1,"z_log" },
-
- { TYREAL,TYREAL,1,"r_lg10" },
- { TYDREAL,TYDREAL,1,"d_lg10" },
-
- { TYREAL,TYREAL,1,"r_sin", 4 },
- { TYDREAL,TYDREAL,1,"d_sin", 4 },
- { TYCOMPLEX,TYCOMPLEX,1,"c_sin" },
- { TYDCOMPLEX,TYDCOMPLEX,1,"z_sin" },
-
- { TYREAL,TYREAL,1,"r_cos", 5 },
- { TYDREAL,TYDREAL,1,"d_cos", 5 },
- { TYCOMPLEX,TYCOMPLEX,1,"c_cos" },
- { TYDCOMPLEX,TYDCOMPLEX,1,"z_cos" },
-
- { TYREAL,TYREAL,1,"r_tan", 6 },
- { TYDREAL,TYDREAL,1,"d_tan", 6 },
-
- { TYREAL,TYREAL,1,"r_asin", 7 },
- { TYDREAL,TYDREAL,1,"d_asin", 7 },
-
- { TYREAL,TYREAL,1,"r_acos", 8 },
- { TYDREAL,TYDREAL,1,"d_acos", 8 },
-
- { TYREAL,TYREAL,1,"r_atan", 9 },
- { TYDREAL,TYDREAL,1,"d_atan", 9 },
-
- { TYREAL,TYREAL,2,"r_atn2", 10 },
- { TYDREAL,TYDREAL,2,"d_atn2", 10 },
-
- { TYREAL,TYREAL,1,"r_sinh", 11 },
- { TYDREAL,TYDREAL,1,"d_sinh", 11 },
-
- { TYREAL,TYREAL,1,"r_cosh", 12 },
- { TYDREAL,TYDREAL,1,"d_cosh", 12 },
-
- { TYREAL,TYREAL,1,"r_tanh", 13 },
- { TYDREAL,TYDREAL,1,"d_tanh", 13 },
-
- { TYCHAR,TYLOGICAL,2,"hl_ge" },
- { TYCHAR,TYLOGICAL,2,"l_ge" },
-
- { TYCHAR,TYLOGICAL,2,"hl_gt" },
- { TYCHAR,TYLOGICAL,2,"l_gt" },
-
- { TYCHAR,TYLOGICAL,2,"hl_le" },
- { TYCHAR,TYLOGICAL,2,"l_le" },
-
- { TYCHAR,TYLOGICAL,2,"hl_lt" },
- { TYCHAR,TYLOGICAL,2,"l_lt" }
- } ;
-
-
-
-
-
-
- char callbyvalue[ ][XL] =
- {
- "sqrt",
- "exp",
- "log",
- "sin",
- "cos",
- "tan",
- "asin",
- "acos",
- "atan",
- "atan2",
- "sinh",
- "cosh",
- "tanh"
- };
-
- struct exprblock *intrcall(np, argsp, nargs)
- struct nameblock *np;
- struct listblock *argsp;
- int nargs;
- {
- int i, rettype;
- struct addrblock *ap;
- register struct specblock *sp;
- struct exprblock *q, *inline();
- register chainp cp;
- struct constblock *mkcxcon();
- expptr ep;
- int mtype;
- int op;
-
- packed.ijunk = np->vardesc.varno;
- if(nargs == 0)
- goto badnargs;
-
- mtype = 0;
- for(cp = argsp->listp ; cp ; cp = cp->nextp)
- {
- /* TEMPORARY */ ep = cp->datap;
- /* TEMPORARY */ if( ISCONST(ep) && ep->vtype==TYSHORT )
- /* TEMPORARY */ cp->datap = mkconv(tyint, ep);
- mtype = maxtype(mtype, ep->vtype);
- }
-
- switch(packed.bits.f1)
- {
- case INTRBOOL:
- op = packed.bits.f3;
- if( ! ONEOF(mtype, MSKINT|MSKLOGICAL) )
- goto badtype;
- if(op == OPBITNOT)
- {
- if(nargs != 1)
- goto badnargs;
- q = mkexpr(OPBITNOT, argsp->listp->datap, NULL);
- }
- else
- {
- if(nargs != 2)
- goto badnargs;
- q = mkexpr(op, argsp->listp->datap,
- argsp->listp->nextp->datap);
- }
- frchain( &(argsp->listp) );
- free(argsp);
- return(q);
-
- case INTRCONV:
- rettype = packed.bits.f2;
- if(rettype == TYLONG)
- rettype = tyint;
- if( ISCOMPLEX(rettype) && nargs==2)
- {
- expptr qr, qi;
- qr = argsp->listp->datap;
- qi = argsp->listp->nextp->datap;
- if(ISCONST(qr) && ISCONST(qi))
- q = mkcxcon(qr,qi);
- else q = mkexpr(OPCONV,mkconv(rettype-2,qr),
- mkconv(rettype-2,qi));
- }
- else if(nargs == 1)
- q = mkconv(rettype, argsp->listp->datap);
- else goto badnargs;
-
- q->vtype = rettype;
- frchain(&(argsp->listp));
- free(argsp);
- return(q);
-
-
- case INTRGEN:
- sp = spectab + packed.bits.f3;
- for(i=0; i<packed.bits.f2 ; ++i)
- if(sp->atype == mtype)
- goto specfunct;
- else
- ++sp;
- goto badtype;
-
- case INTRSPEC:
- sp = spectab + packed.bits.f3;
- if(tyint==TYLONG && sp->rtype==TYSHORT)
- ++sp;
-
- specfunct:
- if(nargs != sp->nargs)
- goto badnargs;
- if(mtype != sp->atype)
- goto badtype;
- fixargs(YES, argsp);
- if(q = inline(sp-spectab, mtype, argsp->listp))
- {
- frchain( &(argsp->listp) );
- free(argsp);
- }
- else if(sp->othername)
- {
- ap = builtin(sp->rtype,
- varstr(XL, callbyvalue[sp->othername-1]) );
- q = fixexpr( mkexpr(OPCCALL, ap, argsp) );
- }
- else
- {
- ap = builtin(sp->rtype, varstr(XL, sp->spxname) );
- q = fixexpr( mkexpr(OPCALL, ap, argsp) );
- }
- return(q);
-
- case INTRMIN:
- case INTRMAX:
- if(nargs < 2)
- goto badnargs;
- if( ! ONEOF(mtype, MSKINT|MSKREAL) )
- goto badtype;
- argsp->vtype = mtype;
- q = mkexpr( (packed.bits.f1==INTRMIN ? OPMIN : OPMAX), argsp, NULL);
-
- q->vtype = mtype;
- rettype = packed.bits.f2;
- if(rettype == TYLONG)
- rettype = tyint;
- else if(rettype == TYUNKNOWN)
- rettype = mtype;
- return( mkconv(rettype, q) );
-
- default:
- fatal1("intrcall: bad intrgroup %d", packed.bits.f1);
- }
- badnargs:
- err1("bad number of arguments to intrinsic %s",
- varstr(VL,np->varname) );
- goto bad;
-
- badtype:
- err1("bad argument type to intrinsic %s", varstr(VL, np->varname) );
-
- bad:
- return( errnode() );
- }
-
-
-
-
- intrfunct(s)
- char s[VL];
- {
- register struct intrblock *p;
- char nm[VL];
- register int i;
-
- for(i = 0 ; i<VL ; ++s)
- nm[i++] = (*s==' ' ? '\0' : *s);
-
- for(p = intrtab; p->intrval.intrgroup!=INTREND ; ++p)
- {
- if( eqn(VL, nm, p->intrfname) )
- {
- packed.bits.f1 = p->intrval.intrgroup;
- packed.bits.f2 = p->intrval.intrstuff;
- packed.bits.f3 = p->intrval.intrno;
- return(packed.ijunk);
- }
- }
-
- return(0);
- }
-
-
-
-
-
- struct addrblock *intraddr(np)
- struct nameblock *np;
- {
- struct addrblock *q;
- struct specblock *sp;
-
- if(np->vclass!=CLPROC || np->vprocclass!=PINTRINSIC)
- fatal1("intraddr: %s is not intrinsic", varstr(VL,np->varname));
- packed.ijunk = np->vardesc.varno;
-
- switch(packed.bits.f1)
- {
- case INTRGEN:
- /* imag, log, and log10 arent specific functions */
- if(packed.bits.f3==31 || packed.bits.f3==43 || packed.bits.f3==47)
- goto bad;
-
- case INTRSPEC:
- sp = spectab + packed.bits.f3;
- if(tyint==TYLONG && sp->rtype==TYSHORT)
- ++sp;
- q = builtin(sp->rtype, varstr(XL,sp->spxname) );
- return(q);
-
- case INTRCONV:
- case INTRMIN:
- case INTRMAX:
- case INTRBOOL:
- bad:
- err1("cannot pass %s as actual",
- varstr(VL,np->varname));
- return( errnode() );
- }
- fatal1("intraddr: impossible f1=%d\n", packed.bits.f1);
- /* NOTREACHED */
- }
-
-
-
-
-
- struct exprblock *inline(fno, type, args)
- int fno;
- int type;
- chainp args;
- {
- register struct exprblock *q, *t, *t1;
-
- switch(fno)
- {
- case 8: /* real abs */
- case 9: /* short int abs */
- case 10: /* long int abs */
- case 11: /* double precision abs */
- if( addressable(q = args->datap) )
- {
- t = q;
- q = NULL;
- }
- else
- t = mktemp(type);
- t1 = mkexpr(OPQUEST, mkexpr(OPLE, mkconv(type,ICON(0)), cpexpr(t)),
- mkexpr(OPCOLON, cpexpr(t),
- mkexpr(OPNEG, cpexpr(t), NULL) ));
- if(q)
- t1 = mkexpr(OPCOMMA, mkexpr(OPASSIGN, cpexpr(t),q), t1);
- frexpr(t);
- return(t1);
-
- case 26: /* dprod */
- q = mkexpr(OPSTAR, args->datap, args->nextp->datap);
- q->vtype = TYDREAL;
- return(q);
-
- case 27: /* len of character string */
- q = cpexpr(args->datap->vleng);
- frexpr(args->datap);
- return(q);
-
- case 14: /* half-integer mod */
- case 15: /* mod */
- return( mkexpr(OPMOD, args->datap, args->nextp->datap) );
- }
- return(NULL);
- }
-