Mercurial > hg > jgplsrc
view u.c @ 0:e0bbaa717f41 draft default tip
lol J
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Mon, 25 Nov 2013 11:56:30 -0500 |
parents | |
children |
line wrap: on
line source
/* Copyright 1990-2011, Jsoftware Inc. All rights reserved. */ /* License in license.txt. */ /* */ /* Interpreter Utilities */ #include "j.h" #if SY_64 I jtmult(J jt,I x,I y){B neg;I a,b,c,p,q,qs,r,s,z;static I m=0x00000000ffffffff; if(!x||!y)R 0; neg=0>x!=0>y; if(0>x){x=-x; ASSERT(0<x,EVLIMIT);} p=m&(x>>32); q=m&x; if(0>y){y=-y; ASSERT(0<y,EVLIMIT);} r=m&(y>>32); s=m&y; ASSERT(!(p&&r),EVLIMIT); a=p*s+q*r; qs=q*s; b=m&(qs>>32); c=m&qs; ASSERT(2147483648>a+b,EVLIMIT); z=c+((a+b)<<32); R neg?-z:z; } I jtprod(J jt,I n,I*v){I*u,z; if(1>n)R 1; u=v; DO(n, if(!*u++)R 0;); z=*v++; DO(n-1, z=mult(z,*v++);); R z; } #else I jtmult(J jt,I x,I y){D z=x*(D)y; ASSERT(z<=IMAX,EVLIMIT); R(I)z;} I jtprod(J jt,I n,I*v){D z=1; DO(n, z*=(D)v[i];); ASSERT(z<=IMAX,EVLIMIT); R(I)z;} #endif #if SY_64 && SY_WIN32 #pragma message("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Win64 bug workaround") D jfloor1(D x){D y; if(-2.0e9<=x&&x<=2.0e9)R floor(x); if(x<-4.51e15||4.51e15<x)R x; y=x; *((I*)&y)&=0xffffffffff000000; R y+floor(x-y); } /* workaround for Windows 64 bit bug */ #endif B all0(A w){RZ(w); R !memchr(AV(w),C1,AN(w));} B all1(A w){RZ(w); R !memchr(AV(w),C0,AN(w));} I jtaii(J jt,A w){I m=IC(w); R m&&!(SPARSE&AT(w))?AN(w)/m:prod(AR(w)-1,1+AS(w));} A jtapv(J jt,I n,I b,I m){A z;I j=b-m,p=b+m*(n-1),*x; GA(z,INT,n,1,0); x=AV(z); switch(m){ case 0: DO(n, *x++=b;); break; case -1: while(j!=p)*x++=--j; break; case 1: while(j!=p)*x++=++j; break; default: while(j!=p)*x++=j+=m; } R z; } /* b+m*i.n */ B jtb0(J jt,A w){RZ(w); ASSERT(!AR(w),EVRANK); if(!(B01&AT(w)))RZ(w=cvt(B01,w)); R*BAV(w);} B*jtbfi(J jt,I n,A w,B p){A t;B*b;I*v; GA(t,B01,n,1,0); b=BAV(t); memset(b,!p,n); v=AV(w); DO(AN(w), b[v[i]]=p;); R b; } /* boolean mask from integers: p=(i.n)e.w */ I bp(I t){ switch(t){ case B01: R sizeof(B); case LIT: case ASGN: case NAME: R sizeof(C); case C2T: R sizeof(C2); case INT: case LPAR: case RPAR: case MARK: case SYMB: R sizeof(I); case FL: R sizeof(D); case CMPX: R sizeof(Z); case BOX: R sizeof(A); case XNUM: R sizeof(X); case RAT: R sizeof(Q); case SB01: case SINT: case SFL: case SCMPX: case SLIT: case SBOX: R sizeof(P); case VERB: case ADV: case CONJ: R sizeof(V); case CONW: R sizeof(CW); case SBT: R sizeof(SB); #ifdef UNDER_CE default: R t&XD?sizeof(DX):t&XZ?sizeof(ZX):-1; #else case XD: R sizeof(DX); case XZ: R sizeof(ZX); default: R -1; #endif }} I bsum(I n,B*b){I q,z=0;UC*u;UI t,*v; v=(UI*)b; u=(UC*)&t; q=n/(255*SZI); #if SY_64 DO(q, t=0; DO(255, t+=*v++;); z+=u[0]+u[1]+u[2]+u[3]+u[4]+u[5]+u[6]+u[7];); #else DO(q, t=0; DO(255, t+=*v++;); z+=u[0]+u[1]+u[2]+u[3];); #endif u=(UC*)v; DO(n-q*255*SZI, z+=*u++;); R z; } /* sum of boolean vector b */ C cf(A w){RZ(w); R*CAV(w);} C cl(A w){RZ(w); R*(CAV(w)+AN(w)-1);} I jtcoerce2(J jt,A*a,A*w,I mt){I at,at1,t,wt,wt1; RZ(*a&&*w); at=AT(*a); at1=AN(*a)?at:0; wt=AT(*w); wt1=AN(*w)?wt:0; RE(t=maxtype(at1,wt1)); RE(t=maxtype(t,mt)); if(!t)RE(t=maxtype(at,wt)); if(t!=at)RZ(*a=cvt(t,*a)); if(t!=wt)RZ(*w=cvt(t,*w)); R t; } A jtcstr(J jt,C*s){R str((I)strlen(s),s);} B evoke(A w){V*v=VAV(w); R CTILDE==v->id&&v->f&&NAME&AT(v->f);} I jti0(J jt,A w){RZ(w=vi(w)); ASSERT(!AR(w),EVRANK); R*AV(w);} A jtifb(J jt,I n,B*b){A z;I m,*zv; m=bsum(n,b); if(m==n)R IX(n); GA(z,INT,m,1,0); zv=AV(z); #if !SY_64 && SY_WIN32 {I i,q=SZI*(n/SZI),*u=(I*)b; for(i=0;i<q;i+=SZI)switch(*u++){ case B0001: *zv++=i+3; break; case B0010: *zv++=i+2; break; case B0011: *zv++=i+2; *zv++=i+3; break; case B0100: *zv++=i+1; break; case B0101: *zv++=i+1; *zv++=i+3; break; case B0110: *zv++=i+1; *zv++=i+2; break; case B0111: *zv++=i+1; *zv++=i+2; *zv++=i+3; break; case B1000: *zv++=i; break; case B1001: *zv++=i; *zv++=i+3; break; case B1010: *zv++=i; *zv++=i+2; break; case B1011: *zv++=i; *zv++=i+2; *zv++=i+3; break; case B1100: *zv++=i; *zv++=i+1; break; case B1101: *zv++=i; *zv++=i+1; *zv++=i+3; break; case B1110: *zv++=i; *zv++=i+1; *zv++=i+2; break; case B1111: *zv++=i; *zv++=i+1; *zv++=i+2; *zv++=i+3; } b=(B*)u; DO(n%SZI, if(*b++)*zv++=q+i;); } #else DO(n, if(b[i])*zv++=i;); #endif R z; } /* integer vector from boolean mask */ F1(jtii){RZ(w); R IX(IC(w));} I jtmaxtype(J jt,I s,I t){I u; u=s|t; if(!(u&SPARSE))R u&CMPX?CMPX:u&FL?FL:s<t?t:s; if(s){s=s&SPARSE?s:STYPE(s); ASSERT(s,EVDOMAIN);} if(t){t=t&SPARSE?t:STYPE(t); ASSERT(t,EVDOMAIN);} R s<t?t:s; } void mvc(I m,void*z,I n,void*w){I p=n,r;static I k=sizeof(D); MC(z,w,MIN(p,m)); while(m>p){r=m-p; MC(p+(C*)z,z,MIN(p,r)); p+=p;} } /* // faster but on some compilers runs afoul of things that look like NaNs // exponent bytes are silently changed by one bit void mvc(I m,void*z,I n,void*w){I p=n,r;static I k=sizeof(D); if(m<k||k<n||(I)z%k){MC(z,w,MIN(p,m)); while(m>p){r=m-p; MC(p+(C*)z,z,MIN(p,r)); p+=p;}} else{C*e,*s;D d[7],d0,*v; p=0==k%n?8:6==n?24:n*k; // p=lcm(k,n) e=(C*)d; s=w; DO(p, *e++=s[i%n];); v=(D*)z; d0=*d; switch(p){ case 8: DO(m/p, *v++=d0;); break; case 24: DO(m/p, *v++=d0; *v++=d[1]; *v++=d[2];); break; case 40: DO(m/p, *v++=d0; *v++=d[1]; *v++=d[2]; *v++=d[3]; *v++=d[4];); break; case 56: DO(m/p, *v++=d0; *v++=d[1]; *v++=d[2]; *v++=d[3]; *v++=d[4]; *v++=d[5]; *v++=d[6];); } if(r=m%p){s=(C*)v; e=(C*)d; DO(r, *s++=e[i];);} }} */ A jtodom(J jt,I r,I n,I*s){A q,z;I j,k,m,*u,*zv; RE(m=prod(n,s)); k=n*SZI; GA(z,INT,m*n,2==r?2:n,s); zv=AV(z)-n; if(2==r){u=AS(z); u[0]=m; u[1]=n;} if(!(m&&n))R z; if(1==n)DO(m, *++zv=i;) else{ GA(q,INT,n,1,0); u=AV(q); memset(u,C0,k); u[n-1]=-1; DO(m, ++u[j=n-1]; DO(n, if(u[j]<s[j])break; u[j]=0; ++u[--j];); MC(zv+=n,u,k);); } R z; } F1(jtrankle){R!w||AR(w)?w:ravel(w);} A jtsc(J jt,I k) {A z; GA(z,INT, 1,0,0); *IAV(z)=k; R z;} A jtsc4(J jt,I t,I v){A z; GA(z,t, 1,0,0); *IAV(z)=v; R z;} A jtscb(J jt,B b) {A z; GA(z,B01, 1,0,0); *BAV(z)=b; R z;} A jtscc(J jt,C c) {A z; GA(z,LIT, 1,0,0); *CAV(z)=c; R z;} A jtscf(J jt,D x) {A z; GA(z,FL, 1,0,0); *DAV(z)=x; R z;} A jtscx(J jt,X x) {A z; GA(z,XNUM,1,0,0); *XAV(z)=ca(x); R z;} A jtstr(J jt,I n,C*s){A z; GA(z,LIT,n,1,0); MC(AV(z),s,n); R z;} F1(jtstr0){A z;C*x;I n; RZ(w); n=AN(w); GA(z,LIT,1+n,1,0); x=CAV(z); MC(x,AV(w),n); x[n]=0; R z;} A jtv2(J jt,I a,I b){A z;I*x; GA(z,INT,2,1,0); x=AV(z); *x++=a; *x=b; R z;} A jtvci(J jt,I k){A z; GA(z,INT,1,1,0); *IAV(z)=k; R z;} A jtvec(J jt,I t,I n,void*v){A z; GA(z,t,n,1,0); MC(AV(z),v,n*bp(t)); R z;} F1(jtvi){RZ(w); R INT&AT(w)?w:cvt(INT,w);} F1(jtvib){A z;D d,e,*wv;I i,n,*old,p=-IMAX,q=IMAX,*zv; RZ(w); old=jt->rank; jt->rank=0; if(AT(w)&SPARSE)RZ(w=denseit(w)); switch(AT(w)){ case INT: z=w; break; case B01: z=cvt(INT,w); break; case XNUM: case RAT: z=cvt(INT,maximum(sc(p),minimum(sc(q),w))); break; default: if(!(AT(w)&FL))RZ(w=cvt(FL,w)); n=AN(w); wv=DAV(w); GA(z,INT,n,AR(w),AS(w)); zv=AV(z); for(i=0;i<n;++i){ d=wv[i]; e=jfloor(d); if (d==inf ) zv[i]=q; else if(d==infm) zv[i]=p; else if( FEQ(d,e))zv[i]=d<p?p:q<d?q:(I)e; else if(++e,FEQ(d,e))zv[i]=d<p?p:q<d?q:(I)e; else ASSERT(0,EVDOMAIN); }} jt->rank=old; R z; } F1(jtvip){I*v; RZ(w); if(!(INT&AT(w)))RZ(w=cvt(INT,w)); v=AV(w); DO(AN(w), ASSERT(0<=*v++,EVDOMAIN);); R w;} F1(jtvs){RZ(w); ASSERT(1>=AR(w),EVRANK); R LIT&AT(w)?w:cvt(LIT,w);} /* verify string */