Skip to content

Commit 9973a6e

Browse files
committed
Clearing unfinished business
1 parent dfaebe9 commit 9973a6e

File tree

13 files changed

+49
-39
lines changed

13 files changed

+49
-39
lines changed

jsrc/ao.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ DF2(jtkeybox){F2PREFIP;PROLOG(0009);A ai,z=0;I nitems;
680680
} // a <./ w
681681

682682

683-
static DF2(jtkeytally);
683+
F2(jtkeytally);
684684

685685
static F1(jtkeytallysp){PROLOG(0015);A b,e,q,x,y,z;I c,d,j,k,*u,*v;P*p;
686686
ARGCHK1(w);
@@ -691,14 +691,15 @@ static F1(jtkeytallysp){PROLOG(0015);A b,e,q,x,y,z;I c,d,j,k,*u,*v;P*p;
691691
e=SPA(p,e); k=i0(e); // k is the sparse element in the rep of i.~ w
692692
j=0; DO(c, if(k<=u[i])break; if(u[i]==v[i])++j;); // j = # unique values in w before the first fill element
693693
RZ(b=ne(e,x)); // b = mask of values in x that are different from the sparse element
694-
RZ(x=repeat(b,x)); RZ(x=keytally(x,x,mark)); u=AV(x); d=AN(x); // u now -> #/.~ of the non-sparse items, d=count thereof
694+
// obsolete RZ(x=repeat(b,x)); RZ(x=keytally(x,x,mark)); u=AV(x); d=AN(x); // u now -> #/.~ of the non-sparse items, d=count thereof
695+
RZ(x=repeat(b,x)); RZ(x=keytally(x,x)); u=AV(x); d=AN(x); // u now -> #/.~ of the non-sparse items, d=count thereof
695696
I nfills=SETIC(w,k)-bsum(c,BAV(b)); // number of cells of fill
696697
GATV0(z,INT,d+(nfills!=0),1); v=AV(z); // allocate result: one for each unique non-fill, plus one for the fills if any
697698
DQ(j, *v++=*u++;); if(nfills)*v++=nfills; DQ(d-j, *v++=*u++;); // copy in the counts
698699
EPILOG(z);
699700
} /* x #/.y , sparse x */
700701

701-
static DF2(jtkeytally){F2PREFIP;PROLOG(0016);A z,q;I at,j,k,n,r,s,*qv,*u,*v;
702+
F2(jtkeytally){F2PREFIP;PROLOG(0016);A z,q;I at,j,k,n,r,s,*qv,*u,*v;
702703
ARGCHK2(a,w); // we don't neep ip, but all jtkey dyads must support it
703704
SETIC(a,n); at=AT(a);
704705
ASSERT(n==SETIC(w,k),EVLENGTH);
@@ -816,7 +817,7 @@ DF2(jtkeyheadtally){F2PREFIP;PROLOG(0017);A f,q,x,y,z;I b;I at,*av,k,n,r,*qv,*u,
816817
}
817818
}
818819
}else{ // no special processing
819-
RZ(q=indexof(a,a)); x=repeat(eq(q,IX(n)),w); y=keytally(q,q,0L); z=stitch(b?x:y,b?y:x); // (((i.~a) = i. # a) # w) ,. (#/.~ i.~ a) for ({. , #)
820+
RZ(q=indexof(a,a)); x=repeat(eq(q,IX(n)),w); y=keytally(q,q); z=stitch(b?x:y,b?y:x); // (((i.~a) = i. # a) # w) ,. (#/.~ i.~ a) for ({. , #)
820821
}
821822
EPILOG(z);
822823
} /* x ({.,#)/.y or x (#,{.)/. y */

jsrc/au.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ B jtprimitive(J jt,A w){A x=w;V*v;
3131
ARGCHK1(w);
3232
v=VAV(w);
3333
if(CTILDE==v->id&&NOUN&AT(v->fgh[0]))RZ(x=fix(w,zeroionei(0)));
34-
R!VAV(x)->fgh[0];
35-
} /* 1 iff w is a primitive */
34+
R((I)VAV(x)->fgh[0]==0&&v->id!=CFORK); // fork has f=0 as a flag
35+
} /* 1 iff w is a primitive, detected as having no f */
3636

3737
// w is a conj, f C n
3838
// Return 1 if f is of the form <@:g (or <@g when g has infinite rank)

jsrc/ca.c

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,25 @@
55

66
#include "j.h"
77

8-
// <.@ >.@ and the like, monad
8+
// [><].@[:]* monad
99
static DF1(jtonf1){PROLOG(0021);DECLFG;A z;I flag=sv->flag,m=jt->xmode;
1010
PREF1(jtonf1);
1111
if(primitive(gs))if(flag&VFLR)jt->xmode=XMFLR; else if(flag&VCEIL)jt->xmode=XMCEIL; // scaf avoid repeated primitive calls inside rank
12-
if(RAT&AT(w))RZ(w=pcvt(XNUM,w));
13-
RZ(z=CALL1(f1,CALL1(g1,w,gs),fs));
14-
jt->xmode=m;
15-
EPILOG(z);
12+
if(RAT&AT(w))RZSUFF(w=pcvt(XNUM,w), z=0; goto restore;);
13+
z=CALL1(f1,CALL1(g1,w,gs),fs); // no RZ...
14+
restore:;
15+
jt->xmode=m; // ...we must restore xmode...
16+
EPILOG(z); // ...and EPILOG will do nothing
1617
}
1718

1819
// <.@ >.@ and the like, dyad
1920
static DF2(jtuponf2){PROLOG(0022);DECLFG;A z;I flag=sv->flag,m=jt->xmode;
2021
ARGCHK2(a,w);
21-
if(primitive(gs))if(flag&VFLR)jt->xmode=XMFLR; else if(flag&VCEIL)jt->xmode=XMCEIL; // scaf avoid repeated primitive calls inside rank
22-
if(RAT&AT(a))RZ(a=pcvt(XNUM,a));
23-
if(RAT&AT(w))RZ(w=pcvt(XNUM,w));
24-
RZ(z=INT&AT(a)&AT(w)&&FAV(gs)->id==CDIV?intdiv(a,w):CALL1(f1,CALL2(g2,a,w,gs),fs));
22+
if(primitive(gs))if(flag&VFLR)jt->xmode=XMFLR; else if(flag&VCEIL)jt->xmode=XMCEIL;
23+
if(RAT&AT(a))RZSUFF(a=pcvt(XNUM,a), z=0; goto restore;);
24+
if(RAT&AT(w))RZSUFF(w=pcvt(XNUM,w), z=0; goto restore;);
25+
z=INT&AT(a)&AT(w)&&FAV(gs)->id==CDIV?intdiv(a,w):CALL1(f1,CALL2(g2,a,w,gs),fs); // no RZ, see above
26+
restore:;
2527
jt->xmode=m;
2628
EPILOG(z);
2729
}
@@ -92,8 +94,8 @@ static DF1(jtmodpow1){A g=FAV(self)->fgh[1]; R rank2ex0(FAV(g)->fgh[0],w,self,jt
9294

9395
// #@> y
9496
static DF1(jttallyatopopen){F1PREFIP; A z; ARGCHK1(w); I an=AN(w); GATV(z,INT,an,AR(w),AS(w)) I *zv=IAV(z);
95-
if(likely(AT(w)&BOX)){A *wv=AAV(w); DO(an, A wc=C(wv[i]); I ic; SETIC(wc,ic); zv[i]=ic;)}
96-
else{mvc(an*SZI, zv, SZI, (iotavec-IOTAVECBEGIN+1));}
97+
if(likely(AT(w)&BOX)){A *wv=AAV(w); DO(an, A wc=C(wv[i]); I ic; SETIC(wc,ic); zv[i]=ic;)} // boxed w, copy item counts
98+
else{mvc(an*SZI, zv, SZI, (iotavec-IOTAVECBEGIN+1));} // all other like 1:"0
9799
RETF(z);
98100
}
99101

@@ -149,7 +151,7 @@ DF2(atcomp){A z;AF f;
149151
z=f(jt,a,w,self);
150152
// postprocessing needed: 0x=none, 10=+./ (result is binary 0 if search completed), 11=*./ (result is binary 1 if search completed)
151153
if(likely(z!=0)){if(postflags&2){z=num((IAV(z)[0]!=AN(AR(a)>=AR(w)?a:w))^(postflags&1));}}
152-
}else z=(FAV(self)->fgh[2]?jtfolk2:jtupon2)(jt,a,w,self); // revert if can't use special code
154+
}else z=(FAV(self)->fgh[2]?jtfolk2:jtupon2)(jt,a,w,self); // revert if can't use special code - not inplace
153155
POPCCT
154156
RETF(z);
155157
}
@@ -198,7 +200,7 @@ F2(jtatop){F2PREFIP;A f,g,h=0,x;AF f1=on1,f2=jtupon2;B b=0,j;C c,d,e;I flag, fla
198200
// We must copy forwarded flags from f to f@][. These are WILLOPEN/USESITEMCOUNT. WILLOPEN/USESITEMCOUNT are copied from the // monad into the monad and (A if @[, W if @])
199201
// BOXATOP is set if a is <
200202
flag2|=(c==CBOX)*(VF2BOXATOP2+VF2BOXATOP1)+(av->flag2&VF2WILLOPEN1+VF2WILLOPEN1PROP+VF2USESITEMCOUNT1)*(1+(d&1)?VF2WILLOPEN2WX/VF2WILLOPEN1:VF2WILLOPEN2AX/VF2WILLOPEN1);
201-
fdeffill(z,flag2,CAT,VERB, onright1,d&1?onright2:onleft2, a,w,0, (av->flag&VASGSAFE)+(av->flag&VJTFLGOK1)*((VJTFLGOK2+VJTFLGOK1)/VJTFLGOK1), RMAX,RMAX,RMAX); R z; // scaf ra not needed on w
203+
fdeffill(z,flag2,CAT,VERB, onright1,d&1?onright2:onleft2, a,0,0, (av->flag&VASGSAFE)+(av->flag&VJTFLGOK1)*((VJTFLGOK2+VJTFLGOK1)/VJTFLGOK1), RMAX,RMAX,RMAX); FAV(z)->fgh[1]=w; R z; // ra not needed on w
202204
}
203205
// Set flag with ASGSAFE status from f/g; keep INPLACE? in sync with f1,f2. But we can turn off inplacing that is not supported by v, which may
204206
// save a few tests during execution and is vital for handling <@v, where we may execute v directly without going through @ and therefore mustn't inplace
@@ -209,7 +211,7 @@ F2(jtatop){F2PREFIP;A f,g,h=0,x;AF f1=on1,f2=jtupon2;B b=0,j;C c,d,e;I flag, fla
209211
#define IDBIT(c) ((UI8)1<<((c)&0x3f)) // mask for c
210212
#define SPECAT (IDBIT(CBOX)|IDBIT(CNOT)|IDBIT(CGRADE)|IDBIT(CSLASH)|IDBIT(CPOUND)|IDBIT(CCEIL)|IDBIT(CFLOOR)|IDBIT(CRAZE)|IDBIT(CQUERY)|IDBIT(CQRYDOT)|IDBIT(CICAP)|IDBIT(CAMP)|IDBIT(CSTAR)|IDBIT(CSLDOT)|IDBIT(CQQ)|IDBIT(CEXP)) // mask for all special cases
211213
if((I)(SPECAT>>(c&0x3f))&BETWEENC(c,CNOT,CQQ)){
212-
switch(c&0x3f){
214+
switch(c&0x3f){ // **** DO NOT add cases without adding them to the SPECAT test above! ****
213215
case CBOX&0x3f: flag2 |= (VF2BOXATOP1|VF2BOXATOP2); break; // mark this as <@f
214216
case CNOT&0x3f: if(d==CMATCH){f2=jtnotmatch; flag+=VIRS2; flag&=~VJTFLGOK2;} break;
215217
case CGRADE&0x3f: if(d==CGRADE){f1=jtranking; flag+=VIRS1; flag&=~VJTFLGOK1;} break;
@@ -307,7 +309,7 @@ F2(jtatco){F2PREFIP;A f,g;AF f1=on1cell,f2=jtupon2cell;C c,d,e;I flag, flag2=0,m
307309
flag = ((av->flag&wv->flag)&VASGSAFE)+(wv->flag&(VJTFLGOK1|VJTFLGOK2));
308310
#define SPECATCO (IDBIT(CEXP)|IDBIT(CBOX)|IDBIT(CGRADE)|IDBIT(CSLASH)|IDBIT(CPOUND)|IDBIT(CCEIL)|IDBIT(CFLOOR)|IDBIT(CSEMICO)|IDBIT(CNOT)|IDBIT(CQUERY)|IDBIT(CQRYDOT)|IDBIT(CICAP)|IDBIT(CAMP)|IDBIT(CSTAR)) // mask for all special cases
309311
if(unlikely((I)(SPECATCO>>(c&0x3f))&BETWEENC(c,CNOT,CPOUND))){
310-
switch(c&0x3f){
312+
switch(c&0x3f){ // **** DO NOT add cases without adding them to the SPECATCO test above! ****
311313
case CBOX&0x3f: flag2 |= (VF2BOXATOP1|VF2BOXATOP2); break; // mark this as <@f
312314
#if SLEEF && (C_AVX2 || EMU_AVX2)
313315
case CEXP&0x3f: if(d==CPOLY){f2=jtpoly2; flag+=VIRS2+(VFATOPPOLYEXP<<VFATOPPOLYX);} break; // ^@:p.

jsrc/ch.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,11 @@ static DF2(jthgeom2){PROLOG(0036);A h,*hv,t,z;B b;I an,*av,j,n;V*sv=FAV(self);
6565
static DF1(jthgeom1){R hgeom2(sc(IMAX),w,self);}
6666

6767
static F2(jtcancel){A c,d,f,x,y;
68-
f=eval("#/.~"); // scaf could call keytally
69-
a=ravel(a); x=nub(a); df1(c,a,f);
70-
w=ravel(w); y=nub(w); df1(d,w,f);
68+
// obsolete f=eval("#/.~"); // scaf could call keytally
69+
// obsolete a=ravel(a); x=nub(a); df1(c,a,f);
70+
// obsolete w=ravel(w); y=nub(w); df1(d,w,f);
71+
a=ravel(a); x=nub(a); c=keytally(a,a); // nub of a, & # times values appear
72+
w=ravel(w); y=nub(w); d=keytally(w,w); // same for w
7173
a=repeat(maximum(num(0),minus(c,from(indexof(y,x),over(d,zeroionei(0))))),x);
7274
w=repeat(maximum(num(0),minus(d,from(indexof(x,y),over(c,zeroionei(0))))),y);
7375
R jlink(a,w);

jsrc/cip.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1462,7 +1462,7 @@ finrle: ;
14621462
if(_mm256_testz_pd(recipbad,sgnbit))break; // testz is 1 if all comparisons false, i. e. all recips in range
14631463
// we wait to test until we have all the reciprocals because we expect few permutations. If there are 0 pivots they may generate NaNs in the L values, but not in recips
14641464

1465-
// falling through, we didn't get all the pivots: we must search for a permutation. scaf The only one that matters takes the largest pivot for each column, in order
1465+
// falling through, we didn't get all the pivots: we must search for a permutation.
14661466

14671467
// if the current permutation is a new best, remember it
14681468
I ngood=CTTZI(_mm256_movemask_pd(recipbad)); // number of leading OK pivots

jsrc/cx.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,17 @@ static B forinitnames(J jt,CDATA*cv,I cwtype,A line,I i, I go){ // i and go are
101101
cv->w=cwtype; // remember type of control struct
102102
cv->i=i, cv->go=go; // remember start/end line#s of control struct
103103
if(cwtype==CFOR){
104-
// for for_xyz., get the symbol indexes for xyz & xyz_index scaf are these preallocated, or should be?
104+
// for for_xyz., get the symbol indexes for xyz & xyz_index. We lookup, though we could put the symbol#s into the CW
105105
I k=AN(line)-5; /* length of item name; -1 if omitted (for.; for_. not allowed) */
106+
ASSERT(k<=255-6,EVILNAME); // max name length is 255, and we must append _index
106107
if(k>0){A x; // if it is a for_xyz.
107-
// We need a string buffer for "xyz_index". Use the stack if the name is short
108-
C ss[20], *s; if(unlikely(k>(I)(sizeof(ss)-6))){GATV0(x,LIT,k+6,1); s=CAV1(x);}else s=ss; // s point to buffer
108+
C ss[255], *s=ss; // We need a string buffer for "xyz_index"; s points to buffer
109+
// obsolete if(unlikely(k>(I)(sizeof(ss)-6))){GATV0(x,LIT,k+6,1); s=CAV1(x);}else s=ss;
109110
MC(s,CAV(line)+4,k); MC(s+k,"_index",6L); // move "xyz_index" into *s
110-
cv->itemsym=(probeislocal(nfs(k,s),jt->locsyms))-SYMORIGIN; // get index of symbol in table, which must have been preallocated
111-
cv->indexsym=(probeislocal(nfs(k+6,s),jt->locsyms))-SYMORIGIN; // also symbol for xyz_index
112-
if(unlikely(k>(I)(sizeof(ss)-6))){ACINITZAP(x); fr(x);} // remove tpop and free, now that we're done. We may be in a loop
111+
A indexnm; RZ(indexnm=nfs(k+6,s)) ASSERT(!(NAV(indexnm)->flag&NMLOC+NMILOC),EVILNAME) cv->indexsym=(probeislocal(indexnm,jt->locsyms))-SYMORIGIN; // get name, verify not locative get (preallocated) index of symbol xyz_index in table
112+
RZ(indexnm=nfs(k,s)) ASSERT(!(NAV(indexnm)->flag&NMLOC+NMILOC),EVILNAME) cv->itemsym=(probeislocal(indexnm,jt->locsyms))-SYMORIGIN; // get name, verify not locative get (preallocated) index of symbol xyz in table
113+
// obsolete NAV(indexnm)->m-=6; cv->itemsym=(probeislocal(nfs(k,s),jt->locsyms))-SYMORIGIN; // also symbol for xyz
114+
// obsolete if(unlikely(k>(I)(sizeof(ss)-6))){ACINITZAP(x); fr(x);} // remove tpop and free, now that we're done. We may be in a loop
113115
}else{cv->itemsym=cv->indexsym=0;} // if not for_xyz., indicate with 0 indexes
114116
}
115117
R 1; // normal return

jsrc/io.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ B jtsesminit(JS jjt, I nthreads){R 1;}
608608

609609
// Main entry point to run the sentence in *lp in the master thread, or in the thread given if jt is not a JS pointer
610610
// Run sentence; result is jt->jerr
611-
// If JE(jt,nfe), loop forever reading sentences scaf this is a kludge, should be a call parameter to engage loop (to allow recursive calls)
611+
// If JE(jt,nfe), loop forever reading sentences (but not if this is a recursive call)
612612
CDPROC int _stdcall JDo(JS jt, C* lp){int r;
613613
SETJTJM(jt,jm)
614614

jsrc/ja.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ extern void jfree4gmp(void*,size_t);
641641
#define keyi(x,y,z) jtkeyi(jt,(x),(y),(z))
642642
#define keysp(x,y,z) jtkeysp(jt,(x),(y),(z))
643643
#define keyrs(x,y) jtkeyrs(jt,(x),(y))
644-
#define keytally(x,y,z) jtkeytally(jt,(x),(y),(z))
644+
#define keytally(x,y) jtkeytally(jt,(x),(y))
645645
#define keytallysp(x) jtkeytallysp(jt,(x))
646646
#define laguerre(x,y,z) jtlaguerre(jt,(x),(y),(z))
647647
#define lamin1(x) jtlamin1(jt,(x))

jsrc/je.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ extern F1(jtgsignal);
146146
extern A jtkeyct(J,A,A,A,D);
147147
extern DF2(jtkeybox);
148148
extern DF2(jtkeyheadtally);
149+
extern F2(jtkeytally);
149150
extern F1(jthalve);
150151
extern F1(jthash);
151152
extern F1(jthead);
@@ -652,6 +653,7 @@ extern DF2(jtpowop);
652653
extern DF2(jtrazecut0);
653654
extern DF2(jtrazecut2);
654655
extern DF2(jtrollk);
656+
extern F2(jtrollksub);
655657
extern DF2(jtrollkx);
656658
extern DF2(jtsumattymes1);
657659
extern DF2(jtxop2);

jsrc/jtype.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1144,7 +1144,7 @@ typedef struct {
11441144
// NOTE: comparison type e. is type 7. If u&n sees bits 0-2=111 in u, it will generate a hashtable. To prevent this from
11451145
// happening incorrectly, leave bit 2=0.
11461146
#define VFCOMPCOMP 0xff // flag bits for comparison compounds, also used for other purposes
1147-
// NOTE: comparison flags pun with VFATOP[RL] in (comp i[.:] [01]:) but that's OK because the constant verbs don't inplace thus they ignore the punned flags scaf this is wrong
1147+
// NOTE: comparison flags pun with VFATOP[RL] in (comp i[.:] [01]:) but that's OK because if the function reverts, it turns off inplacing
11481148
// for other types, they are defined as follows:
11491149
#define VFATOPL JTINPLACEW // (in execution of forks and v0`v1`v2) f/v0 is x@[, so OK to inplace w arg of h
11501150
#define VFATOPR JTINPLACEA // (in execution of forks and v0`v1`v2) f/v0 is x@], so OK to inplace a arg of h

0 commit comments

Comments
 (0)