Mercurial > hg > jgplsrc
view cx.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 (2013-11-25) |
parents | |
children |
line wrap: on
line source
/* Copyright 1990-2011, Jsoftware Inc. All rights reserved. */ /* License in license.txt. */ /* */ /* Conjunctions: Explicit Definition : and Associates */ /* Usage of the f,g,h fields of : defined verbs: */ /* f character matrix of left argument to : */ /* g character matrix of right argument to : */ /* h 4-element vector of boxes */ /* 0 vector of boxed tokens for f */ /* 1 vector of triples of control information */ /* 2 vector of boxed tokens for g */ /* 3 vector of triples of control information */ #include "j.h" #include "d.h" #include "p.h" #include "w.h" #define BASSERT(b,e) {if(!(b)){jsignal(e); i=-1; z=0; continue;}} #define BGA(v,t,n,r,s) BZ(v=ga(t,(I)(n),(I)(r),(I*)(s))) #define BZ(e) if(!(e)){i=-1; z=0; continue;} #define LINE(sv) {A x; \ h=sv->h; hv=AAV(sv->h); hi=a&&w?HN:0; \ line=AAV(hv[hi]); x=hv[1+hi]; n=AN(x); cw=(CW*)AV(x);} typedef struct{A t,x,line;C*iv,*xv;I j,k,n;} CDATA; /* for_xyz. t do. control data */ /* line 'for_xyz.' */ /* t iteration array */ /* n #t */ /* k length of name xyz */ /* x text xyz_index */ /* xv ptr to text xyz_index */ /* iv ptr to text xyz */ /* j iteration index */ #define WCD (sizeof(CDATA)/sizeof(I)) typedef struct{I d,t,e;} TD; #define WTD (sizeof(TD)/sizeof(I)) #define NTD 17 /* maximum nesting for try/catch */ static B jtforinit(J jt,CDATA*cv,A t){A x;C*s,*v;I k; ASSERT(t,EVCTRL); cv->t=ra(t); /* iteration array */ cv->n=IC(t); /* # of items in t */ cv->j=-1; /* iteration index */ cv->x=0; cv->k=k=AN(cv->line)-5; /* length of item name */ if(0<k&&cv->n){ /* for_xyz. */ s=4+CAV(cv->line); RZ(cv->x=x=ra(str(6+k,s))); cv->xv=v=CAV(x); MC(k+v,"_index",6L); /* index name */ cv->iv=s; /* item name */ } R 1; } /* for. do. end. initializations */ static B jtunstackcv(J jt,CDATA*cv){ if(cv->x){ex(link(cv->x,str(cv->k,cv->iv))); fa(cv->x);} fa(cv->t); memset(cv,C0,WCD*SZI); R 1; } static void jttryinit(J jt,TD*v,I i,CW*cw){I j=i,t=0; v->d=v->t=0; while(t!=CEND){ j=(j+cw)->go; switch(t=(j+cw)->type){ case CCATCHD: v->d=j; break; case CCATCHT: v->t=j; break; case CEND: v->e=j; break; }}} /* processing on hitting try. */ static DF2(jtxdefn){PROLOG;A cd,cl,cn,h,*hv,*line,loc=jt->local,t,td,u,v,z;B b,lk,named,ox=jt->xdefn;CDATA*cv; CW*ci,*cw;DC d=0;I hi,i=0,j,m,n,od=jt->db,old,r=0,st,tdi=0;TD*tdv;V*sv;X y; RE(0); z=mtm; cd=t=u=v=0; sv=VAV(self); st=AT(self); lk=jt->glock||VLOCK&sv->flag; named=VNAMED&sv->flag?1:0; cn=jt->curname; cl=jt->curlocn; d=named&&jt->db&&DCCALL==jt->sitop->dctype?jt->sitop:0; /* stack entry for dbunquote for this fn */ if(VXOP&sv->flag){u=sv->f; v=sv->h; sv=VAV(sv->g);} if(st&ADV+CONJ){u=a; v=w;} LINE(sv); ASSERT(n,EVDOMAIN); RZ(jt->local=stcreate(2,1L,0L,0L)); if(sv->flag&VTRY1+VTRY2){GA(td,INT,NTD*WTD,2,0); *AS(td)=NTD; *(1+AS(td))=WTD; tdv=(TD*)AV(td);} /* do not use error exit after this point; use BASSERT, BGA, BZ */ FDEPINC(1); jt->xdefn=1; IS(xnam,a); if(u){IS(unam,u); if(NOUN&AT(u))IS(mnam,u);} IS(ynam,w); if(v){IS(vnam,v); if(NOUN&AT(v))IS(nnam,v);} if(jt->dotnames){ IS(xdot,a); if(u){IS(udot,u); if(NOUN&AT(u))IS(mdot,u);} IS(ydot,w); if(v){IS(vdot,v); if(NOUN&AT(v))IS(ndot,v);} } if(jt->db&&jt->sitop&&DCCALL==jt->sitop->dctype&&self==jt->sitop->dcf){ jt->sitop->dcloc=jt->local; jt->sitop->dcc=hv[1+hi]; jt->sitop->dci=(I)&i; } old=jt->tbase+jt->ttop; while(0<=i&&i<n){ if(0<jt->pmctr&&C1==jt->pmrec&&named)pmrecord(cn,cl,i,a?VAL2:VAL1); if(jt->redefined&&jt->sitop&&jt->redefined==jt->sitop->dcn&&DCCALL==jt->sitop->dctype&&self!=jt->sitop->dcf){ self=jt->sitop->dcf; sv=VAV(self); LINE(sv); jt->sitop->dcc=hv[1+hi]; jt->redefined=0; if(i>=n)break; } ci=i+cw; switch(ci->type){ case CTRY: BASSERT(tdi<NTD,EVLIMIT); tryinit(tdv+tdi,i,cw); if(jt->db)jt->db=(tdv+tdi)->d?jt->dbuser:DBTRY; ++tdi; ++i; break; case CCATCH: case CCATCHD: case CCATCHT: if(tdi){--tdi; i=1+(tdv+tdi)->e; jt->db=od;}else i=ci->go; break; case CTHROW: BASSERT(0,EWTHROW); case CBBLOCK: tpop(old); z=parsex(vec(BOX,ci->n,line+ci->i),lk,ci,d); if(z||DB1==jt->db||DBERRCAP==jt->db||!jt->jerr)++i; else if(EWTHROW==jt->jerr){if(tdi&&(j=(tdv+tdi-1)->t)){i=1+j; RESETERR;}else BASSERT(0,EWTHROW);} else{i=ci->go; if(i<SMAX){RESETERR; if(tdi){--tdi; jt->db=od;}}} break; case CASSERT: if(!jt->assert){++i; break;} case CTBLOCK: gc(z,old); t=parsex(vec(BOX,ci->n,line+ci->i),lk,ci,d); if(t||DB1==jt->db||DBERRCAP==jt->db||!jt->jerr)++i; else if(EWTHROW==jt->jerr){if(tdi&&(j=(tdv+tdi-1)->t)){i=1+j; RESETERR;}else BASSERT(0,EWTHROW);} else{i=ci->go; if(i<SMAX){RESETERR; if(tdi){--tdi; jt->db=od;}}} break; case CFOR: case CSELECT: if(!r) if(cd){m=AN(cd)/WCD; BZ(cd=ext(1,cd)); cv=(CDATA*)AV(cd)+m-1; r=AN(cd)/WCD-m;} else {r=9; BGA(cd,INT,r*WCD,1,0); cv=(CDATA*)AV(cd)-1; ra(cd);} ++cv; --r; cv->t=cv->x=0; cv->line=line[ci->i]; ++i; break; case CDOF: if(!cv->t){BZ(forinit(cv,t)); t=0;} ++cv->j; if(cv->j<cv->n){ if(cv->x){A x; symbis(nfs(6+cv->k,cv->xv),x=sc(cv->j), jt->local); symbis(nfs( cv->k,cv->iv),from(x,cv->t),jt->local); } ++i; continue; } case CBREAKF: case CENDSEL: rat(z); unstackcv(cv); --cv; ++r; i=ci->go; break; case CRETURN: if(cd){rat(z); DO(AN(cd)/WCD-r, unstackcv(cv); --cv; ++r;);} i=ci->go; break; case CCASE: case CFCASE: if(!cv->t){BASSERT(t&&NOUN&AT(t),EVCTRL); BZ(cv->t=ra(boxopen(t))); t=0;} i=ci->go; break; case CDOSEL: BASSERT(!t||NOUN&AT(t),EVCTRL); i=t&&all0(eps(cv->t,boxopen(t)))?ci->go:1+i; t=0; break; case CDO: ++i; b=1; if(t){ if(SPARSE&AT(t))BZ(t=denseit(t)); BASSERT(NOUN&AT(t),EVCTRL); switch(AN(t)?AT(t):0){ case RAT: case XNUM: y=*XAV(t); b=*AV(y)||1<AN(y); break; case CMPX: b=0!=*DAV(t)||0!=*(1+DAV(t)); break; case FL: b=0!=*DAV(t); break; case INT: b=0!=*AV(t); break; case B01: b=*BAV(t); }} t=0; if(b)break; default: JBREAK0; i=ci->go; }} FDEPDEC(1); z=jt->jerr?0:z?ra(z):mtm; fa(cd); symfreeh(jt->local,0L); jt->local=loc; jt->asgn=0; jt->xdefn=ox; tpop(_ttop); if(z)ASSERT(st&ADV+CONJ||AT(z)&NOUN,EVSYNTAX); tpush(z); R z; } static DF1(xv1){R df1( w,VAV(self)->f);} static DF2(xv2){R df2(a,w,VAV(self)->g);} static DF1(xn1 ){R xdefn(0L,w, self);} static DF1(xadv){R xdefn(w, 0L,self);} static F1(jtxopcall){R jt->db&&DCCALL==jt->sitop->dctype?jt->sitop->dca:mark;} static DF1(xop1){A ff,x; RZ(ff=fdef(CCOLON,VERB, xn1,jtxdefn, w,self,0L, VXOP|VAV(self)->flag, RMAX,RMAX,RMAX)); RZ(x=xopcall(one)); R x==mark?ff:namerefop(x,ff); } static DF2(xop2){A ff,x; RZ(ff=fdef(CCOLON,VERB, xn1,jtxdefn, a,self,w, VXOP|VAV(self)->flag, RMAX,RMAX,RMAX)); RZ(x=xopcall(one)); R x==mark?ff:namerefop(x,ff); } static B jtxop(J jt,A h){A p,x,y;B b,*pv;I*xv; GA(x,INT,jt->dotnames?12:6,1,0); xv=AV(x); xv[0]=(I)mnam; xv[1]=(I)nnam; xv[2]=(I)unam; xv[3]=(I)vnam; xv[ 4]=(I)xnam; xv[ 5]=(I)ynam; if(jt->dotnames){xv[6]=(I)mdot; xv[7]=(I)ndot; xv[8]=(I)udot; xv[9]=(I)vdot; xv[10]=(I)xdot; xv[11]=(I)ydot;} RZ(y=raze(from(v2(0L,HN),h))); AT(y)=INT; RZ(p=eps(x,y)); pv=BAV(p); b=(pv[0]||pv[1]||pv[2]||pv[3])&&(pv[4]||pv[5]); if(!b&&jt->dotnames)b=(pv[6]||pv[7]||pv[8]||pv[9])&&(pv[10]||pv[11]); R b; } /* whether h denotes an explicit derived function */ static F1(jtcolon0){A l,z;C*p,*q,*s;I m,n; n=0; RZ(z=exta(LIT,1L,1L,300L)); s=CAV(z); while(1){ RE(l=jgets("\001")); if(!l)break; m=AN(l); p=q=CAV(l); if(m){while(' '==*p)++p; if(')'==*p){while(' '==*++p); if(p>=m+q)break;}} while(AN(z)<=n+m){RZ(z=ext(0,z)); s=CAV(z);} MC(s+n,q,m); n+=m; *(s+n)=CLF; ++n; } R str(n,s); } /* enter nl terminated lines; ) on a line by itself to exit */ static F1(jtlineit){ R 1<AR(w)?ravel(stitch(w,scc(CLF))):AN(w)&&CLF==cl(w)?w:over(w,scc(CLF)); } static B jtsent12c(J jt,A w,A*m,A*d){C*p,*q,*r,*s,*x; ASSERT(!AN(w)||LIT&AT(w),EVDOMAIN); ASSERT(2>=AR(w),EVRANK); RZ(w=lineit(w)); x=p=r=CAV(w); /* p: monad start; r: dyad start */ q=s=p+AN(w); /* q: monad end; s: dyad end */ while(x<s){ q=x; while(' '==*x)++x; if(':'==*x){while(' '==*++x); if(CLF==*x){r=++x; break;}} while(CLF!=*x++); } if(x==s)q=r=s; *m=df1(str(q-p,p),cut(ds(CBOX),num[-2])); *d=df1(str(s-r,r),cut(ds(CBOX),num[-2])); R 1; } /* literal fret-terminated or matrix sentences into monad/dyad */ static B jtsent12b(J jt,A w,A*m,A*d){A t,*wv,y,*yv;I j,*v,wd; ASSERT(1>=AR(w),EVRANK); wv=AAV(w); wd=(I)w*ARELATIVE(w); GA(y,BOX,AN(w),AR(w),AS(w)); yv=AAV(y); DO(AN(w), RZ(yv[i]=vs(WVR(i)));); RZ(t=indexof(y,link(chr[':'],str(1L,":")))); v=AV(t); j=MIN(*v,*(1+v)); *m=take(sc(j ),y); *d=drop(sc(j+1),y); R 1; } /* boxed sentences into monad/dyad */ F2(jtcolon){A d,h,*hv,m;B b;C*s;I flag=0,n,p; RZ(a&&w); if(VERB&AT(a)&&VERB&AT(w)){V*v; v=VAV(a); if(CCOLON==v->id&&VERB&AT(v->f)&&VERB&AT(v->g))a=v->f; v=VAV(w); if(CCOLON==v->id&&VERB&AT(v->f)&&VERB&AT(v->g))w=v->g; R fdef(CCOLON,VERB,xv1,xv2,a,w,0L,0L,mr(a),lr(w),rr(w)); } RE(n=i0(a)); if(equ(w,zero)){RZ(w=colon0(mark)); if(!n)R w;} if(C2T&AT(w))RZ(w=cvt(LIT,w)); if(10<n){s=CAV(w); p=AN(w); if(p&&CLF==s[p-1])RZ(w=str(p-1,s));} else{ RZ(BOX&AT(w)?sent12b(w,&m,&d):sent12c(w,&m,&d)); if(4==n){if(AN(m)&&!AN(d))d=m; m=mtv;} GA(h,BOX,2*HN,1,0); hv=AAV(h); RE(b=preparse(m,hv, hv+1 )); if(b)flag|=VTRY1; hv[2 ]=jt->retcomm?m:mtv; RE(b=preparse(d,hv+HN,hv+HN+1)); if(b)flag|=VTRY2; hv[2+HN]=jt->retcomm?d:mtv; } if(!n)R ca(w); if(2>=n){ RE(b=xop(h)); if(b)flag|=VXOPR; else if(2==n&&AN(m)&&!AN(d)){A*u=hv,*v=hv+HN,x; DO(HN, x=*u; *u++=*v; *v++=x;);} } flag|=VFIX; switch(n){ case 1: R fdef(CCOLON, ADV, b?xop1:xadv,0L, num[n],0L,h, flag, RMAX,RMAX,RMAX); case 2: R fdef(CCOLON, CONJ, 0L,b?xop2:jtxdefn, num[n],0L,h, flag, RMAX,RMAX,RMAX); case 3: R fdef(CCOLON, VERB, xn1,jtxdefn, num[n],0L,h, flag, RMAX,RMAX,RMAX); case 4: R fdef(CCOLON, VERB, xn1,jtxdefn, num[n],0L,h, flag, RMAX,RMAX,RMAX); case 13: R vtrans(w); default: ASSERT(0,EVDOMAIN); }}