Mercurial > hg > jgplsrc
view ca.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. */ /* */ /* Conjunctions: Atop and Ampersand */ #include "j.h" static DF1(jtonf1){PROLOG;DECLFG;A z;I flag=sv->flag,m=jt->xmode; PREF1(jtonf1); if(primitive(gs))if(flag&VFLR)jt->xmode=XMFLR; else if(flag&VCEIL)jt->xmode=XMCEIL; if(RAT&AT(w))RZ(w=pcvt(XNUM,w)); z=CALL1(f1,CALL1(g1,w,gs),fs); jt->xmode=m; EPILOG(z); } static DF2(jtuponf2){PROLOG;DECLFG;A z;I flag=sv->flag,m=jt->xmode; RZ(a&&w); if(primitive(gs))if(flag&VFLR)jt->xmode=XMFLR; else if(flag&VCEIL)jt->xmode=XMCEIL; if(RAT&AT(a))RZ(a=pcvt(XNUM,a)); if(RAT&AT(w))RZ(w=pcvt(XNUM,w)); z=INT&AT(a)&&INT&AT(w)&&CDIV==ID(gs)?intdiv(a,w):CALL1(f1,CALL2(g2,a,w,gs),fs); jt->xmode=m; EPILOG(z); } static X jtxmodpow(J jt,A a,A w,A h){A ox,z; if(!(XNUM&AT(a)))RZ(a=cvt(XNUM,a)); if(!(XNUM&AT(w)))RZ(w=cvt(XNUM,w)); if(!(XNUM&AT(h)))RZ(h=cvt(XNUM,h)); ox=jt->xmod; jt->xmod=h; GA(z,XNUM,1,0,0); *XAV(z)=xpow(*XAV(a),*XAV(w)); jt->xmod=ox; RNE(z); } #define DMOD 46340 /* <. %: _1+2^31 */ #if SY_64 #define XMOD 3037000499 /* <. %: _1+2^63 */ #else #define XMOD 94906265 /* <. %: _1+2^53 */ static I dmodpow(D x,I n,D m){D z=1; while(n){if(1&n)z=fmod(z*x,m); x=fmod(x*x,m); n>>=1;} R(I)z;} #endif static I imodpow(I x,I n,I m){I z=1; while(n){if(1&n)z=(z*x)%m; x=(x*x)%m; n>>=1;} R z;} static DF2(jtmodpow2){A h;B b,c;I at,m,n,wt,x,z; PREF2(jtmodpow2); h=VAV(self)->h; if(RAT&AT(a))RZ(a=pcvt(XNUM,a)) else if(!(AT(a)&INT+XNUM))RZ(a=pcvt(INT,a)); if(RAT&AT(w))RZ(w=pcvt(XNUM,w)) else if(!(AT(w)&INT+XNUM))RZ(w=pcvt(INT,w)); at=AT(a); wt=AT(w); if((AT(h)&XNUM||at&XNUM||wt&XNUM)&&at&XNUM+INT&&wt&INT+XNUM){A z; z=xmodpow(a,w,h); if(!jt->jerr)R z; RESETERR; R residue(h,expn2(a,w)); } n=*AV(w); if(!(INT&at&&INT&wt&&0<=n))R residue(h,expn2(a,w)); m=*AV(h); x=*AV(a); if(!m)R expn2(a,w); if(XMOD<m||XMOD<-m||m==IMIN||x==IMIN)R cvt(INT,xmodpow(a,w,h)); if(b=0>m)m=-m; if(c=0>x)x=-x; x=x%m; if(c)x=m-x; #if SY_64 z=imodpow(x,n,m); #else z=m>DMOD?dmodpow((D)x,n,(D)m):imodpow(x,n,m); #endif R sc(b?z-m:z); } /* a m&|@^ w ; m guaranteed to be INT or XNUM */ static DF1(jtmodpow1){A g=VAV(self)->g; R rank2ex(VAV(g)->f,w,self,0L,0L,jtmodpow2);} /* m&|@(n&^) w ; m guaranteed to be INT or XNUM */ static CS1(on1, CALL1(f1,CALL1(g1,w,gs),fs)) static CS2(jtupon2,CALL1(f1,CALL2(g2,a,w,gs),fs)) static DF2(on2){PROLOG;DECLFG;A ga,gw,z; PREF2(on2); gw=CALL1(g1,w,gs); ga=CALL1(g1,a,gs); z=CALL2(f2,ga,gw,fs); EPILOG(z); } static DF2(atcomp){AF f; RZ(a&&w); f=atcompf(a,w,self); R f?f(jt,a,w,self):upon2(a,w,self); } static DF2(atcomp0){A z;AF f;D oldct=jt->ct; RZ(a&&w); f=atcompf(a,w,self); jt->ct=0; z=f?f(jt,a,w,self):upon2(a,w,self); jt->ct=oldct; R z; } F2(jtatop){A f,g,h=0,x;AF f1=on1,f2=jtupon2;B b=0,j;C c,d,e;I flag=0,m=-1;V*av,*wv; ASSERTVV(a,w); av=VAV(a); c=av->id; wv=VAV(w); d=wv->id; switch(c){ case CNOT: if(d==CMATCH){f2=jtnotmatch; flag+=VIRS2;} break; case CGRADE: if(d==CGRADE){f1=jtranking; flag+=VIRS1;} break; case CSLASH: if(d==CCOMMA)f1=jtredravel; break; case CCEIL: f1=jtonf1; f2=jtuponf2; flag=VCEIL; break; case CFLOOR: f1=jtonf1; f2=jtuponf2; flag=VFLR; break; case CICAP: if(d==CNE)f1=jtnubind; else if(FIT0(CNE,wv))f1=jtnubind0; break; case CQUERY: if(d==CDOLLAR||d==CPOUND)f2=jtrollk; break; case CQRYDOT: if(d==CDOLLAR||d==CPOUND)f2=jtrollkx; break; case CRAZE: if(d==CCUT&&boxatop(w)){f1=jtrazecut1; f2=jtrazecut2;} break; case CSLDOT: if(d==CSLASH&&CSLASH==ID(av->f))f2=jtpolymult; break; case CQQ: if(d==CTHORN&&CEXEC==ID(av->f)&&equ(zero,av->g))f1=jtdigits10; break; case CEXP: if(d==CCIRCLE)f1=jtexppi; break; case CAMP: x=av->f; if(RAT&AT(x))RZ(x=pcvt(XNUM,x)); if((d==CEXP||d==CAMP&&CEXP==ID(wv->g))&&AT(x)&INT+XNUM&&!AR(x)&&CSTILE==ID(av->g)){ h=x; flag=VMOD; if(d==CEXP)f2=jtmodpow2; else f1=jtmodpow1; }} if(d==CEBAR||d==CEPS||(b=FIT0(CEPS,wv))){ f=av->f; g=av->g; e=ID(f); if(b)d=ID(wv->f); if(c==CICAP)m=7; else if(c==CSLASH)m=e==CPLUS?4:e==CPLUSDOT?5:e==CSTARDOT?6:-1; else if(c==CAMP&&(g==zero||g==one)){j=*BAV(g); m=e==CIOTA?j:e==CICO?2+j:-1;} switch(0<=m?d:-1){ case CEBAR: f2=b?atcomp0:atcomp; flag=6+8*m; break; case CEPS: f2=b?atcomp0:atcomp; flag=7+8*m; break; }} R fdef(CAT,VERB, f1,f2, a,w,h, flag, (I)wv->mr,(I)wv->lr,(I)wv->rr); } F2(jtatco){A f,g;AF f1=on1,f2=jtupon2;B b=0;C c,d,e;I flag=0,j,m=-1;V*av,*wv; ASSERTVV(a,w); av=VAV(a); c=av->id; f=av->f; g=av->g; e=ID(f); wv=VAV(w); d=wv->id; switch(c){ case CNOT: if(d==CMATCH){f2=jtnotmatch; flag+=VIRS2;} break; case CGRADE: if(d==CGRADE){f1=jtranking; flag+=VIRS1;} break; case CCEIL: f1=jtonf1; f2=jtuponf2; flag=VCEIL; break; case CFLOOR: f1=jtonf1; f2=jtuponf2; flag=VFLR; break; case CQUERY: if(d==CDOLLAR||d==CPOUND)f2=jtrollk; break; case CQRYDOT: if(d==CDOLLAR||d==CPOUND)f2=jtrollkx; break; case CICAP: m=7; if(d==CNE)f1=jtnubind; else if(FIT0(CNE,wv))f1=jtnubind0; break; case CAMP: if(g==zero||g==one){j=*BAV(g); m=e==CIOTA?j:e==CICO?2+j:-1;} break; case CSLASH: if(vaid(f)&&vaid(w))f2=jtfslashatg; if(d==CCOMMA)f1=jtredravel; else m=e==CPLUS?4:e==CPLUSDOT?5:e==CSTARDOT?6:-1; break; case CSEMICO: if(d==CLBRACE)f2=jtrazefrom; else if(d==CCUT){ j=i0(wv->g); if(CBOX==ID(wv->f)&&!j)f2=jtrazecut0; else if(boxatop(w)&&j&&-2<=j&&j<=2){f1=jtrazecut1; f2=jtrazecut2;} }} if(0<=m){ b=d==CFIT&&equ(zero,wv->g); switch(b?ID(wv->f):d){ case CEQ: f2=b?atcomp0:atcomp; flag=0+8*m; break; case CNE: f2=b?atcomp0:atcomp; flag=1+8*m; break; case CLT: f2=b?atcomp0:atcomp; flag=2+8*m; break; case CLE: f2=b?atcomp0:atcomp; flag=3+8*m; break; case CGE: f2=b?atcomp0:atcomp; flag=4+8*m; break; case CGT: f2=b?atcomp0:atcomp; flag=5+8*m; break; case CEBAR: f2=b?atcomp0:atcomp; flag=6+8*m; break; case CEPS: f2=b?atcomp0:atcomp; flag=7+8*m; break; }} R fdef(CATCO,VERB, f1,f2, a,w,0L, flag, RMAX,RMAX,RMAX); } F2(jtampco){AF f1=on1;C c,d;I flag=0;V*wv; ASSERTVV(a,w); c=ID(a); wv=VAV(w); d=wv->id; if (c==CSLASH&&d==CCOMMA) f1=jtredravel; else if(c==CRAZE&&d==CCUT&&boxatop(w))f1=jtrazecut1; else if(c==CGRADE&&d==CGRADE) {f1=jtranking; flag+=VIRS1;} R fdef(CAMPCO,VERB, f1,on2, a,w,0L, flag, RMAX,RMAX,RMAX); } static DF1(withl){DECLFG; R jt->rank?irs2(fs,w,gs,AR(fs),jt->rank[1],g2):CALL2(g2,fs,w,gs);} static DF1(withr){DECLFG; R jt->rank?irs2(w,gs,fs,jt->rank[1],AR(gs),f2):CALL2(f2,w,gs,fs);} static DF1(ixfixedleft ){V*v=VAV(self); R indexofprehashed(v->f,w,v->h);} static DF1(ixfixedright ){V*v=VAV(self); R indexofprehashed(v->g,w,v->h);} static DF1(ixfixedleft0 ){A z;D old=jt->ct;V*v=VAV(self); jt->ct=0.0; z=indexofprehashed(v->f,w,v->h); jt->ct=old; R z; } static DF1(ixfixedright0){A z;D old=jt->ct;V*v=VAV(self); jt->ct=0.0; z=indexofprehashed(v->g,w,v->h); jt->ct=old; R z; } static DF2(with2){R df1(w,powop(self,a));} F2(jtamp){A h=0;AF f1=on1,f2=on2;B b;C c,d=0;D old=jt->ct;I flag=0,mode=-1,p,r;V*u,*v; RZ(a&&w); switch(CONJCASE(a,w)){ default: ASSERTSYS(0,"amp"); case NN: ASSERT(0,EVDOMAIN); case NV: f1=withl; v=VAV(w); c=v->id; if(AN(a)&&AR(a)){ if(b=c==CFIT&&equ(zero,v->g))c=ID(v->f); mode=c==CIOTA?IIDOT:c==CICO?IICO:-1; } if(0<=mode){ if(b){jt->ct=0.0; h=indexofsub(mode,a,mark); jt->ct=old; f1=ixfixedleft0;} else { h=indexofsub(mode,a,mark); f1=ixfixedleft ;} }else switch(c){ case CWORDS: RZ(a=fsmvfya(a)); f1=jtfsmfx; break; case CIBEAM: if(v->f&&v->g&&128==i0(v->f)&&3==i0(v->g)){RZ(h=crccompile(a)); f1=jtcrcfixedleft;} } R fdef(CAMP,VERB, f1,with2, a,w,h, flag, RMAX,RMAX,RMAX); case VN: f1=withr; if(AN(w)&&AR(w)){ v=VAV(a); c=v->id; p=v->flag%256; if(b=c==CFIT&&equ(zero,v->g))c=ID(v->f); if(7==p%8)mode=II0EPS+p/8; /* (e.i.0:) etc. */ else mode=c==CEPS?IEPS:c==CLESS?ILESS:-1; } if(0<=mode){ if(b){jt->ct=0.0; h=indexofsub(mode,w,mark); jt->ct=old; f1=ixfixedright0;} else { h=indexofsub(mode,w,mark); f1=ixfixedright ;} } R fdef(CAMP,VERB, f1,with2, a,w,h, flag, RMAX,RMAX,RMAX); case VV: v=VAV(w); c=v->id; r=v->mr; if(c==CFORK||c==CAMP){ if(c==CFORK)d=ID(v->h); if(CIOTA==ID(v->g)&&(!d||d==CLEFT||d==CRIGHT)&&equ(alp,v->f)){ u=VAV(a); d=u->id; if(d==CLT||d==CLE||d==CEQ||d==CNE||d==CGE||d==CGT)f2=jtcharfn2; }}else switch(ID(a)){ case CGRADE: if(c==CGRADE){f1=jtranking; flag+=VIRS1;} break; case CSLASH: if(c==CCOMMA)f1=jtredravel; break; case CCEIL: f1=jtonf1; flag=VCEIL; break; case CFLOOR: f1=jtonf1; flag=VFLR; break; case CRAZE: if(c==CCUT&&boxatop(w))f1=jtrazecut1; } R fdef(CAMP,VERB, f1,f2, a,w,0L, flag, r,r,r); }}