Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign up
Fetching contributors…
| /* Copyright 1990-2010, Jsoftware Inc. All rights reserved. */ | |
| /* Licensed use only. Any other use is in violation of copyright. */ | |
| /* */ | |
| /* Representations: Linear and Paren */ | |
| #include "j.h" | |
| #if !SY_WINCE | |
| // extern int isdigit(int); | |
| #include <ctype.h> | |
| #endif | |
| static F1(jtlnoun); | |
| static F1(jtlnum); | |
| static DF1(jtlrr); | |
| #define NUMV(c) (c==C9||c==CD||c==CA||c==CS) | |
| static B jtlp(J jt,A w){B b=1,p=0;C c,d,q=CQUOTE,*v;I j=0,n; | |
| RZ(w); | |
| n=AN(w); v=CAV(w); c=*v; d=*(v+n-1); | |
| if(1==n||(2==n||3>=n&&' '==c)&&(d==CESC1||d==CESC2)||vnm(n,v))R 0; | |
| if(C9==ctype[(UC)c])DO(n-1, d=c; c=ctype[(UC)*++v]; if(b=!NUMV(c)||d==CS&&c!=C9)break;) | |
| else if(c==q) DO(n-1, c=*v++; if(c==q)p=!p; if(b=p?0:c!=q)break;) | |
| else if(c=='(') DO(n-1, c=*v++; j+=c=='('?1:c==')'?-1:0; if(b=!j)break;) | |
| R b; | |
| } /* 1 iff put parens around w */ | |
| static A jtlcpa(J jt,B b,A w){A z=w;C*zv;I n; | |
| RZ(w); | |
| if(b){n=AN(w); GATV(z,LIT,2+n,1,0); zv=CAV(z); *zv='('; MC(1+zv,AV(w),n); zv[1+n]=')';} | |
| R z; | |
| } /* if b then (w) otherwise just w */ | |
| static A jtlcpb(J jt,B b,A w){A z=w;B p;C c,*v,*wv,*zv;I n; | |
| RZ(w); | |
| n=AN(w); wv=CAV(w); | |
| if(!b){ | |
| c=ctype[(UC)*wv]; v=wv; p=0; | |
| if (c==CQ)DO(n-1, c=ctype[(UC)*++v]; if(c==CQ)p=!p; else if(p){b=1; break;}) | |
| else if(c==C9)DO(n-1, c=ctype[(UC)*++v]; if(!(c==C9 ||c==CS )){b=1; break;}) | |
| else DO(n-1, c= *++v ; if(!(c==CESC1||c==CESC2)){b=1; break;}); | |
| if(b&&vnm(n,wv))b=0; | |
| } | |
| if(b){GATV(z,LIT,2+n,1,0); zv=CAV(z); *zv='('; MC(1+zv,wv,n); zv[1+n]=')';} | |
| R z; | |
| } | |
| static A jtlcpx(J jt,A w){RZ(w); R CALL2(jt->lcp,lp(w),w,0);} | |
| static F1(jtltiea){A t,*v,*wv,x,y;B b;C c;I n; | |
| RZ(w); | |
| n=AN(w); wv=AAV(w); RZ(t=spellout(CGRAVE)); | |
| GATV(y,BOX,n+n,1,0); v=AAV(y); | |
| DO(n, *v++=i?t:mtv; x=wv[i]; c=ID(x); RZ(x=lrr(x)); | |
| b=c==CHOOK||c==CFORK||i&&lp(x); RZ(*v++=CALL2(jt->lcp,b,x,0));); | |
| R raze(y); | |
| } | |
| static F1(jtltieb){A pt,t,*v,*wv,x,y;B b;C c,*s;I n; | |
| RZ(w); | |
| n=AN(w); wv=AAV(w); RZ(t=spellout(CGRAVE)); RZ(pt=over(scc(')'),t)); | |
| GATV(y,BOX,n+n,1,0); v=AAV(y); | |
| if(1>=n)x=mtv; else{GATV(x,LIT,n-2,1,0); s=CAV(x); DO(n-2, *s++='(';);} | |
| DO(n, *v++=0==i?x:1==i?t:pt; x=wv[i]; c=ID(x); RZ(x=lrr(x)); | |
| b=c==CHOOK||c==CFORK||i&&lp(x); RZ(*v++=CALL2(jt->lcp,b,x,0));); | |
| R raze(y); | |
| } | |
| static F1(jtlsh){R over(thorn1(shape(w)),spellout(CDOLLAR));} | |
| static F1(jtlshape){I r,*s; | |
| RZ(w); | |
| r=AR(w); s=AS(w); | |
| R 2==r&&(1==s[0]||1==s[1]) ? spellout((C)(1==s[1]?CCOMDOT:CLAMIN)) : !r ? mtv : | |
| 1<r ? lsh(w) : 1<AN(w) ? mtv : spellout(CCOMMA); | |
| } | |
| static F1(jtlchar){A y;B b,p=1,r1;C c,d,*u,*v;I j,k,m,n; | |
| RZ(w); | |
| m=AN(alp); n=AN(w); j=n-m; r1=1==AR(w); u=v=CAV(w); d=*v; | |
| if(0<=j&&r1&&!memcmp(v+j,AV(alp),m)){ | |
| if(!j)R cstr("a."); | |
| RZ(y=lchar(1==j?scc(*v):str(j,v))); | |
| R lp(y)?over(cstr("a.,~"),y):over(y,cstr(",a.")); | |
| } | |
| if(r1&&m==n&&(y=icap(ne(w,alp)))&&m>AN(y)){ | |
| if(1==AN(y))RZ(y=head(y)); | |
| R over(over(cstr("a. "),lcpx(lnum(y))),over(cstr("}~"),lchar(from(y,w)))); | |
| } | |
| j=2; b=7<n||1<n&&1<AR(w); | |
| DO(n, c=*v++; if(c==CQUOTE)++j; b&=c==d; p&=31<c&&c<127;); | |
| if(b){n=1; j=MIN(3,j);} | |
| if(!p){ | |
| k=(UC)d; RZ(y=indexof(alp,w)); | |
| if(r1&&n<m&&(!k||k==m-n)&&equ(y,apv(n,k,1L)))R over(thorn1(sc(d?-n:n)),cstr("{.a.")); | |
| RZ(y=lnum(y)); | |
| R lp(y)?over(cstr("a.{~"),y):over(y,cstr("{a.")); | |
| } | |
| GATV(y,LIT,n+j,1,0); v=CAV(y); | |
| *v=*(v+n+j-1)=CQUOTE; ++v; | |
| if(2==j)MC(v,u,n); else DO(n, *v++=c=*u++; if(c==CQUOTE)*v++=c;); | |
| R over(b?lsh(w):lshape(w),y); | |
| } /* non-empty character array */ | |
| static F1(jtlbox){A p,*v,*vv,*wv,x,y;B b=0;I n; | |
| RZ(w); | |
| if(equ(ace,w)&&B01&AT(AAV0(w)))R cstr("a:"); | |
| n=AN(w); wv=AAV(w); | |
| DO(n, x=wv[i]; if(BOX&AT(x)){b=1; break;}); b=b||1==n; | |
| GATV(y,BOX,n+n-!b,1,0); v=vv=AAV(y); | |
| if(b){ | |
| RZ(p=cstr("),(<")); | |
| DO(n, x=wv[i]; *v++=p; RZ(*v++=lnoun(x));); | |
| RZ(*vv=cstr(1==n?"<":"(<")); if(1<n)RZ(vv[n+n-2]=cstr("),<")); | |
| R over(lshape(w),raze(y)); | |
| } | |
| DO(n, x=wv[i]; if(b=1!=AR(x)||!(LIT&AT(x)))break;); | |
| if(!b){C c[256],d,*t;UC*s; | |
| DO(256,c[i]=1;); | |
| RZ(x=raze(w)); s=UAV(x); | |
| DO(AN(x), c[*s++]=0;); | |
| if(c[CQUOTE]&&equ(w,words(x)))R over(cstr(";:"),lchar(x)); | |
| if(c[d=' ']||c[d='|']||c[d='/']||c[d=',']||c[d=';']){ | |
| GATV(y,LIT,n+AN(x),1,0); t=CAV(y); | |
| DO(n, x=wv[i]; *t++=d; MC(t,AV(x),AN(x)); t+=AN(x);); | |
| RZ(y=lchar(y)); | |
| R over(lshape(w),over(cstr(isdigit(*CAV(y))?"<;.(_1) ":"<;._1 "),y)); | |
| }} | |
| RZ(p=cstr(";")); | |
| DO(n-1, RZ(*v++=lcpx(lnoun(wv[i]))); *v++=p;); | |
| RZ(*v=lnoun(wv[n-1])); | |
| R over(lshape(w),raze(y)); | |
| } /* non-empty boxed array */ | |
| static F1(jtlnum1){A z;I t; | |
| RZ(w); | |
| t=AT(w); | |
| RZ(z=t&FL+CMPX?df1(w,fit(ds(CTHORN),sc((I)18))):thorn1(w)); | |
| R t&XNUM+RAT&&!memchr(CAV(z),t&XNUM?'x':'r',AN(z))?over(z,scc('x')):z; | |
| } /* dense non-empty numeric vector */ | |
| static F1(jtlnum){A b,d,t,*v,y;B p;I n; | |
| RZ(t=ravel(w)); | |
| n=AN(w); | |
| if(7<n||1<n&&1<AR(w)){ | |
| // see if we can use a clever encoding | |
| d=minus(from(num[1],t),b=from(num[0],t)); | |
| p=equ(t,plus(b,tymes(d,IX(n)))); | |
| if(p){ | |
| if(equ(d,num[0]))R over(lsh(w),lnum1(b)); | |
| GAT(y,BOX,6,1,0); v=AAV(y); v[0]=v[1]=v[2]=v[3]=mtv; | |
| if(p=!(equ(b,sc(n-1))&&equ(d,num[-1]))){ | |
| if (!equ(b,num[0] )){v[0]=lnum1(b); v[1]=spellout(CPLUS);} | |
| if ( equ(d,num[-1])) v[1]=spellout(CMINUS); | |
| else if(!equ(d,num[1] )){v[2]=lnum1(d); v[3]=spellout(CSTAR);} | |
| } | |
| v[4]=spellout(CIOTA); v[5]=thorn1(p?shape(w):negate(shape(w))); | |
| RE(y); R raze(y); | |
| } | |
| RESETERR; // if there was an error getting to p, clear it | |
| } | |
| // not clever; just out the atoms | |
| R over(lshape(w),lnum1(t)); | |
| } /* dense numeric non-empty array */ | |
| static F1(jtlsparse){A a,e,q,t,x,y,z;B ba,be,bn;I j,r,*v;P*p; | |
| RZ(w); | |
| r=AR(w); p=PAV(w); a=SPA(p,a); e=SPA(p,e); y=SPA(p,i); x=SPA(p,x); | |
| bn=0; v=AS(w); DO(r, if(!*v++){bn=1; break;}); | |
| ba=0; if(r==AR(a)){v=AV(a); DO(r, if(i!=*v++){ba=1; break;});} | |
| be=!(AT(w)&SFL&&0==*DAV(e)); | |
| if(be)RZ(z=over(lnoun(e),cstr(SB01&AT(w)?"":SINT&AT(w)?"+-~2":SFL&AT(w)?"+-~2.1":"+-~2j1"))); | |
| if(be||ba){ | |
| RZ(z=be?over(lcpx(lnoun(a)), over(scc(';'),z)):lnoun(a)); | |
| RZ(z= over(lcpx(lnoun(shape(w))),over(scc(';'),z)) ); | |
| }else RZ(z=lnoun(shape(w))); | |
| RZ(z=over(cstr("1$."),z)); | |
| if(bn||!*AS(y))R z; | |
| if(AN(a)){ | |
| RZ(x=lcpx(lnoun(x))); | |
| RZ(y=1==r?lnoun(ravel(y)):over(cstr("(<\"1)"),lnoun(y))); | |
| RZ(t=over(x,over(cstr(" ("),over(y,cstr(")}"))))); | |
| }else RZ(t=over(lcpx(lnoun(head(x))),cstr(" a:}"))); | |
| ba=0; v=AV(a); DO(AN(a), if(i!=*v++){ba=1; break;}); | |
| if(!ba)R over(t,z); | |
| RZ(q=less(IX(r),a)); | |
| RZ(z=over(over(lcpx(lnoun(q)),cstr("|:")),z)); | |
| RZ(z=over(t,z)); | |
| RZ(q=grade1(over(less(IX(r),q),q))); | |
| j=r; v=AV(q); DO(r, if(i!=*v++){j=i; break;}); | |
| R over(lcpx(lnoun(drop(sc(j),q))),over(cstr("|:"),z)); | |
| } /* sparse array */ | |
| static F1(jtlnoun0){A s,x;B r1; | |
| RZ(w); | |
| r1=1==AR(w); RZ(s=thorn1(shape(w))); | |
| switch(CTTZ(AT(w))){ | |
| default: R over(cstr("i."),s); | |
| case LITX: x=cstr( "''"); R r1?x:over(over(s,scc('$')),x); | |
| case C2TX: x=cstr("u: ''"); R r1?x:over(over(s,scc('$')),x); | |
| case C4TX: x=cstr("10&u: ''"); R r1?x:over(over(s,scc('$')),x); | |
| case BOXX: R over(s,cstr("$a:" )); | |
| case B01X: R over(s,cstr("$0" )); | |
| case FLX: R over(s,cstr("$0.5" )); | |
| case CMPXX: R over(s,cstr("$0j5" )); | |
| case XNUMX: R over(s,cstr("$0x" )); | |
| case RATX: R over(s,cstr("$1r2" )); | |
| case SBTX: R over(s,cstr("$s: ' '")); | |
| }} /* empty dense array */ | |
| static F1(jtlnoun){I t; | |
| RZ(w); | |
| t=AT(w); | |
| if(t&SPARSE)R lsparse(w); | |
| if(!AN(w))R lnoun0(w); | |
| switch(CTTZ(t)){ | |
| case LITX: R lchar(w); | |
| case C2TX: R over(cstr("u: "),lnum(uco2(num[3],w))); | |
| case C4TX: R over(cstr("10&u: "),lnum(uco2(num[3],w))); | |
| case BOXX: R lbox(w); | |
| case SBTX: R over(cstr("s: "),lbox(sb2(num[5],w))); | |
| default: R lnum(w); | |
| }} | |
| static A jtlsymb(J jt,C c,A w){A t;C buf[20],d,*s;I*u;V*v=FAV(w); | |
| if(VDDOP&v->flag){ | |
| u=AV(v->fgh[2]); s=buf; | |
| *s++=' '; *s++='('; s+=sprintf(s,FMTI,*u); spellit(CIBEAM,s); s+=2; s+=sprintf(s,FMTI,u[1]); *s++=')'; | |
| RZ(t=str(s-buf,buf)); | |
| }else RZ(t=spella(w)); | |
| d=cf(t); | |
| R d==CESC1||d==CESC2?over(chr[' '],t):t; | |
| } | |
| static B laa(A a,A w){C c,d; | |
| if(!(a&&w))R 0; | |
| c=ctype[(UC)cl(a)]; d=ctype[(UC)cf(w)]; | |
| R (c==C9||c==CA)&&(d==C9||d==CA); | |
| } | |
| static B lnn(A a,A w){C c; if(!(a&&w))R 0; c=cl(a); R ('x'==c||C9==ctype[(UC)c])&&C9==ctype[(UC)cf(w)];} | |
| static F2(jtlinsert){A*av,f,g,h,t,t0,t1,t2,*u,y;B b,ft,gt,ht;C c,id;I n;V*v; | |
| RZ(a&&w); | |
| n=AN(a); av=AAV(a); | |
| v=VAV(w); id=v->id; | |
| b=id==CCOLON&&VXOP&v->flag; | |
| // ?t tells whether () is needed around the f/g/h component | |
| if(1<=n){f=av[0]; t=v->fgh[0]; c=ID(t); ft=c==CHOOK||c==CFORK||c==CADVF||(b||id==CFORK)&&NOUN&AT(t)&&lp(f);} // f: () is it's hoor fork && or noun left end of nvv or n (op) | |
| if(2<=n){g=av[1]; t=v->fgh[1]; c=ID(t); gt=VERB&AT(w) ?c==CHOOK||c==CFORK:lp(g);} | |
| if(3<=n){h=av[2]; t=v->fgh[2]; c=ID(t); ht=VERB&AT(w)&&!b?c==CHOOK :lp(h);} | |
| switch(!b?id:2==n?CHOOK:CFORK){ | |
| case CADVF: | |
| case CHOOK: | |
| GAT(y,BOX,3,1,0); u=AAV(y); | |
| u[0]=f=CALL2(jt->lcp,ft||lnn(f,g),f,0); | |
| u[2]=g=CALL2(jt->lcp,gt||b, g,0); | |
| u[1]=str(' '==cf(g)||id==CADVF&&!laa(f,g)&&!(lp(f)&&lp(g))?0L:1L," "); | |
| RE(0); R raze(y); | |
| case CFORK: | |
| GAT(y,BOX,5,1,0); u=AAV(y); | |
| RZ(u[0]=f=CALL2(jt->lcp,ft||lnn(f,g), f,0)); | |
| RZ(u[2]=g=CALL2(jt->lcp,gt||lnn(g,h)||b,g,0)); RZ(u[1]=str(' '==cf(g)?0L:1L," ")); | |
| RZ(u[4]=h=CALL2(jt->lcp,ht, h,0)); RZ(u[3]=str(' '==cf(h)?0L:1L," ")); | |
| R raze(y); | |
| default: | |
| t0=CALL2(jt->lcp,ft||NOUN&AT(v->fgh[0])&&!(VGERL&v->flag)&&lp(f),f,0); | |
| t1=lsymb(id,w); | |
| y=over(t0,laa(t0,t1)?over(chr[' '],t1):t1); | |
| if(1==n)R y; | |
| t2=lcpx(g); | |
| R over(y,laa(y,t2)?over(chr[' '],t2):t2); | |
| }} | |
| static F1(jtlcolon){A*v,x,y;C*s,*s0;I m,n; | |
| RZ(y=unparsem(num[1],w)); | |
| n=AN(y); v=AAV(y); RZ(x=lrr(VAV(w)->fgh[0])); | |
| if(2>n||2==n&&1==AN(v[0])&&':'==*CAV(v[0])){ | |
| if(!n)R over(x,str(5L," : \'\'")); | |
| y=lrr(v[2==n]); | |
| if(2==n)y=over(str(5L,"\':\'; "),y); | |
| R over(over(x,str(3L," : ")),lcpx(y)); | |
| } | |
| m=0; DO(n, m+=AN(v[i]);); | |
| GATV(y,LIT,2+n+m,1,0); | |
| s=s0=CAV(y); | |
| DO(n, *s++=CLF; y=v[i]; m=AN(y); MC(s,CAV(y),m); s+=m;); | |
| *s++=CLF; *s++=')'; | |
| RZ(y=str(s-s0,s0)); | |
| jt->ltext=jt->ltext?over(jt->ltext,y):y; | |
| R over(x,str(4L," : 0")); | |
| } | |
| // Main routine for () and linear rep. w is to be represented | |
| static DF1(jtlrr){A fs,gs,hs,t,*tv;C id;I fl,m;V*v; | |
| RZ(w); | |
| // If noun, return the linear rep of the noun. If name, use bare string form of the name UNLESS the name is also flagged as a noun - then treat as a noun (used by ".@'name') | |
| if(AT(w)&NAME){RZ(t=sfn(0,w)); if(!(AT(w)&NOUN))R t; w=t;} | |
| if(AT(w)&NOUN)R lnoun(w); | |
| v=VAV(w); id=v->id; fs=v->fgh[0]; gs=v->fgh[1]; hs=v->fgh[2]; fl=v->flag; if(id==CBOX)gs=0; // ignore gs field in BOX, there to simulate BOXATOP | |
| if(fl&VXOPCALL)R lrr(hs); | |
| m=(I )!!fs+(I )(gs&&id!=CBOX)+(I )(id==CFORK)+(I )(hs&&id==CCOLON&&VXOP&fl); // BOX has g for BOXATOP; ignore it | |
| if(!m)R lsymb(id,w); | |
| if(evoke(w))R sfn(0,fs); | |
| if(!(VXOP&fl)&&hs&&BOX&AT(hs)&&id==CCOLON)R lcolon(w); | |
| GATV(t,BOX,m,1,0); tv=AAV(t); | |
| if(2<m)RZ(tv[2]=lrr(hs)); | |
| // for top-level of gerund (indicated by self!=0), any noun type could not have come from an AR, so return it as is | |
| if(1<m)RZ(tv[1]=fl&VGERR?CALL1(jt->ltie,self?fxeachacv(gs):fxeach(gs),0L):lrr(gs)); | |
| if(0<m)RZ(tv[0]=fl&VGERL?CALL1(jt->ltie,self?fxeachacv(fs):fxeach(fs),0L):lrr(fs)); | |
| R linsert(t,w); | |
| } | |
| // Create linear representation of w. Call lrr, which creates an A for the text plus jt->ltext which is appended to it. | |
| // jt->lcp and jt->ltie are routines for handling adding enclosing () and handling ` | |
| F1(jtlrep){PROLOG(0056);A z; | |
| jt->ltext=0; jt->lcp=(AF)jtlcpa; jt->ltie=jtltiea; | |
| RE(z=jtlrr(jt,w,w)); // the w for self is just any nonzero to indicate top-level call | |
| if(jt->ltext)z=over(z,jt->ltext); | |
| jt->ltext=0; | |
| EPILOG(z); | |
| } | |
| // Create paren representation of w. Call lrr, which creates an A for the text plus jt->ltext which is appended to it. | |
| // jt->lcp and jt->ltie are routines for handling adding enclosing () and handling ` | |
| F1(jtprep){PROLOG(0057);A z; | |
| jt->ltext=0; jt->lcp=(AF)jtlcpb; jt->ltie=jtltieb; | |
| RE(z=jtlrr(jt,w,w)); | |
| if(jt->ltext)z=over(z,jt->ltext); | |
| jt->ltext=0; | |
| EPILOG(z); | |
| } | |