new squeeze functions

This commit is contained in:
dzaima 2025-05-13 06:21:48 +03:00
parent 9d11fc0cde
commit f1cb141f56
21 changed files with 146 additions and 118 deletions

View File

@ -52,7 +52,7 @@ static B divint_AA(B w, B x) { // consumes both
w = toI32Any(w);
x = toI32Any(x); i32* xp = tyany_ptr(x);
DIVLOOP(f64, i32, wp[i]/(f64)xp[i]);
r = num_squeeze(r); decG(w); decG(x); return r;
r = squeeze_numNewTy(el_f64,r); decG(w); decG(x); return r;
}
static B divint_AS(B w, i32 xv) { // consumes
w = toI32Any(w);
@ -60,7 +60,7 @@ static B divint_AS(B w, i32 xv) { // consumes
if (xv==-1) return C1(sub, w);
if (xv==0) return C2(mul, w, m_f64(1.0/0.0));
DIVLOOP(f64, i32, wp[i]/(f64)xv);
r = num_squeeze(r); decG(w); return r;
r = squeeze_numNewTy(el_f64,r); decG(w); return r;
}
static B floordiv_AA(B w, B x) { // consumes both
@ -70,7 +70,7 @@ static B floordiv_AA(B w, B x) { // consumes both
w = taga(cpyI16Arr(w));
x = toI32Any(x); i32* xp = i32any_ptr(x);
DIVLOOP(f64, i16, floorf((f32)wp[i] / (f32)xp[i]));
r = num_squeeze(r); decG(w); decG(x); return r;
r = squeeze_numNewTy(el_f64,r); decG(w); decG(x); return r;
}
return C1(floor, divint_AA(w, x));
}
@ -96,8 +96,8 @@ static B floordiv_AS(B w, i32 xv) { // consumes
}
#undef DIVLOOP
static B modint_AA(B w, B x) { return num_squeeze(C2(sub, x, C2(mul, w, floordiv_AA(incG(x), incG(w))))); } // consumes both
static B modint_SA(i32 wv, B x) { return num_squeeze(C2(sub, x, C2(mul, m_i32(wv), floordiv_AS(incG(x), wv)))); } // consumes
static B modint_AA(B w, B x) { return squeeze_numNew(C2(sub, x, C2(mul, w, floordiv_AA(incG(x), incG(w))))); } // consumes both
static B modint_SA(i32 wv, B x) { return squeeze_numNew(C2(sub, x, C2(mul, m_i32(wv), floordiv_AS(incG(x), wv)))); } // consumes
static B modint_AS(B w, B xv) { return modint_AA(w, C2(shape, C1(fne, incG(w)), xv)); } // consumes w, assumes xv is number
@ -157,14 +157,14 @@ static B modint_AS(B w, B xv) { return modint_AA(w, C2(shape, C1(fne, incG(w))
if (xe==el_i32) { DECOR vfor (usz i = 0; i < ia; i++) { w.f=((f64*)wp)[i]; x.f=((i32*)xp)[i]; rp[i]=EXPR; } } \
else { DECOR vfor (usz i = 0; i < ia; i++) { w.f=((f64*)wp)[i]; x.f=((f64*)xp)[i]; rp[i]=EXPR; } } \
} \
decG(w); decG(x); return num_squeeze(r); \
decG(w); decG(x); return squeeze_numNewTy(el_f64,r); \
} \
} else if (isF64(w)&isArr(x)) { usz ia=IA(x); u8 xe=TI(x,elType); \
if (elInt(xe)) {INT_SA Rf64(x); x=toI32Any(x); PI32(x) DECOR vfor (usz i=0; i<ia; i++) {B x/*shadow*/;x.f=xp[i];rp[i]=EXPR;} decG(x); return num_squeeze(r); } \
if (xe==el_f64){ Rf64(x); PF(x) FLT_SAI DECOR vfor (usz i=0; i<ia; i++) {B x/*shadow*/;x.f=xp[i];rp[i]=EXPR;} decG(x); return num_squeeze(r); } \
if (elInt(xe)) {INT_SA Rf64(x); x=toI32Any(x); PI32(x) DECOR vfor (usz i=0; i<ia; i++) {B x/*shadow*/;x.f=xp[i];rp[i]=EXPR;} decG(x); return squeeze_numNewTy(el_f64,r); } \
if (xe==el_f64){ Rf64(x); PF(x) FLT_SAI DECOR vfor (usz i=0; i<ia; i++) {B x/*shadow*/;x.f=xp[i];rp[i]=EXPR;} decG(x); return squeeze_numNewTy(el_f64,r); } \
} else if (isF64(x)&isArr(w)) { usz ia=IA(w); u8 we=TI(w,elType); ANY_AS \
if (elInt(we)) {INT_AS Rf64(w); w=toI32Any(w); PI32(w) DECOR vfor (usz i=0; i<ia; i++) {B w/*shadow*/;w.f=wp[i];rp[i]=EXPR;} decG(w); return num_squeeze(r); } \
if (we==el_f64){ Rf64(w); PF(w) DECOR vfor (usz i=0; i<ia; i++) {B w/*shadow*/;w.f=wp[i];rp[i]=EXPR;} decG(w); return num_squeeze(r); } \
if (elInt(we)) {INT_AS Rf64(w); w=toI32Any(w); PI32(w) DECOR vfor (usz i=0; i<ia; i++) {B w/*shadow*/;w.f=wp[i];rp[i]=EXPR;} decG(w); return squeeze_numNewTy(el_f64,r); } \
if (we==el_f64){ Rf64(w); PF(w) DECOR vfor (usz i=0; i<ia; i++) {B w/*shadow*/;w.f=wp[i];rp[i]=EXPR;} decG(w); return squeeze_numNewTy(el_f64,r); } \
} \
P2(NAME) \
} \
@ -175,7 +175,7 @@ static B modint_AS(B w, B xv) { return modint_AA(w, C2(shape, C1(fne, incG(w))
, /*INT_AS*/ if(q_i32(x)) { r = divint_AS(w, o2iG(x)); /*decG(w); */ return r; }
, /*INT_AA*/ r = divint_AA(w, x); /*decG(w); decG(x);*/ return r;
, /*FLT_SAI*/
, /*ANY_AS*/ if((r_f64u(o2fG(x)) & ((1ULL<<52)-1)) == 0 && elNum(we)) return num_squeeze(C2(mul, w, m_f64(1/(o2fG(x)+0))));
, /*ANY_AS*/ if((r_f64u(o2fG(x)) & ((1ULL<<52)-1)) == 0 && elNum(we)) return squeeze_numNew(C2(mul, w, m_f64(1/(o2fG(x)+0))));
)
GC2f("", root , pow(x.f+0, 1.0/(w.f+0)), NOUNROLL,,,,,)
GC2f("", pow , pow(w.f+0, x.f), NOUNROLL,,,,,)
@ -307,7 +307,7 @@ static B modint_AS(B w, B xv) { return modint_AA(w, C2(shape, C1(fne, incG(w))
if (xei) { PI32(x) DOF(EXPR,w,wp[i],xp[i]) } \
else { PF(x) DOF(EXPR,w,wp[i],xp[i]) } \
} else {PF(w)PI32(x) DOF(EXPR,w,wp[i],xp[i]) } \
decG(w); decG(x); return num_squeeze(r); \
decG(w); decG(x); return squeeze_numNewTy(el_f64,r); \
} \
EXTRA \
if(we==el_i8 & xe==el_i8 ) { PI8 (w) PI8 (x) DOI8 (EXPR,w,wp[i],xp[i],bad) } \

View File

@ -79,11 +79,11 @@ B add_c1(B t, B x) {
assert(xe==el_f64); f64* xp = f64any_ptr(x); \
f64* rp; B r = m_f64arrc(&rp, x); \
vfor (usz i = 0; i < ia; i++) { f64 v=xp[i]; rp[i]=FEXPR; } \
decG(x); return num_squeeze(r); \
decG(x); return squeeze_numNewTy(el_f64,r); \
}
B sub_c2(B,B,B);
#define SUB_BODY(FEXPR) return sub_c2(t, m_f64(0), x);
#define NOT_BODY(FEXPR) x = num_squeezeChk(x); return TI(x,elType)==el_bit? bit_negate(x) : C2(sub, m_f64(1), x);
#define NOT_BODY(FEXPR) x = squeeze_numTry(x, &xe); return xe==el_bit? bit_negate(x) : C2(sub, m_f64(1), x);
GC1i("-", sub, -v, el_bit, bit_sel(x,m_f64(0),m_f64(-1)), SUB_BODY)
GC1i("|", stile, fabs(v), el_bit, x, STILE_BODY)

View File

@ -729,8 +729,9 @@ NOINLINE B for_cells_SA(B f, B w, B x, ur xcr, ur xr, u32 chr) { // w⊸F⎉xcr
case n_select:
if (isArr(w) && xcr==1) {
if (!TI(w,arrD1)) {
w = num_squeezeChk(w);
if (!TI(w,arrD1)) break;
u8 xe;
w = squeeze_numTry(w, &xe);
if (xe==el_B) break;
}
assert(xr > 1);
ur wr = RNK(w);

View File

@ -492,7 +492,7 @@ B GRADE_CAT(c2)(B t, B w, B x) {
GRADE_UD(bp[0]=0; bp[1]=1;, bp[0]=1; bp[1]=0;)
B i = C2(GRADE_NAME, b01, x);
f64* c; B rw = m_f64arrv(&c, 3); c[0]=0; c[1]=c1; c[2]=wia;
r = C2(select, i, num_squeeze(rw));
r = C2(select, i, squeeze_numNewTy(el_f64,rw));
}
} else { // xe==el_bit: 2-element lookup table
i8* bp; B b01 = m_i8arrv(&bp, 2); bp[0]=0; bp[1]=1;

View File

@ -280,10 +280,7 @@ B group_c2(B t, B w, B x) {
ur xr = RNK(x);
if (isArr(w) && RNK(w)==1 && xr>=1) {
u8 we = TI(w,elType);
if (!elInt(we)) {
w = num_squeeze(w);
we = TI(w,elType);
}
if (!elInt(we)) w = squeeze_numTry(w, &we);
if (elInt(we)) {
usz wia = IA(w);
usz* xsh = SH(x);

View File

@ -9,7 +9,7 @@
static NOINLINE B homFil1(B f, B r, B xf) {
assert(EACH_FILLS);
if (isPureFn(f)) {
if (f.u==bi_eq.u || f.u==bi_ne.u || f.u==bi_feq.u) { dec(xf); return num_squeeze(r); }
if (f.u==bi_eq.u || f.u==bi_ne.u || f.u==bi_feq.u) { dec(xf); return squeeze_numNew(r); }
if (f.u==bi_fne.u) { dec(xf); return withFill(r, emptyHVec()); }
if (!noFill(xf)) {
if (CATCH) { freeThrown(); return r; }
@ -24,7 +24,7 @@ static NOINLINE B homFil1(B f, B r, B xf) {
static NOINLINE B homFil2(B f, B r, B wf, B xf) {
assert(EACH_FILLS);
if (isPureFn(f)) {
if (f.u==bi_feq.u || f.u==bi_fne.u) { dec(wf); dec(xf); return num_squeeze(r); }
if (f.u==bi_feq.u || f.u==bi_fne.u) { dec(wf); dec(xf); return squeeze_numNew(r); }
if (!noFill(wf) && !noFill(xf)) {
if (CATCH) { freeThrown(); return r; }
B rf = asFill(c2(f, wf, xf));

View File

@ -337,7 +337,7 @@ B scan_c1(Md1D* d, B x) { B f = d->f;
if (xe==el_i32) { i32* xp=i32any_ptr(x); for (usz i=1; i<ia; i++) { c = c!=xp[i]; bitp_set(rp,i,c); } decG(x); return r; }
UD;
}
if (rtid==n_or) { x=num_squeezeChk(x); xe=TI(x,elType); if (xe==el_bit) return scan_or(x, ia); }
if (rtid==n_or) { x=squeeze_numTry(x, &xe); if (xe==el_bit) return scan_or(x, ia); }
}
base:;
if (ia!=n && ia >= 6 * (u64)n && isPervasiveDy(f)) return scan_arith(f, m_f64(0), x, SH(x));

View File

@ -222,11 +222,13 @@ B select_c2(B t, B w, B x) {
if (sh) PLAINLOOP for (ux i = 0; i < wr; i++) sh[i] = 1;
return r;
} else if (isArr(w0) && wr<=1) {
// try to fast-path ⟨numarr⟩ ⊏ 𝕩; if not possible, 𝕨 is definitely erroneous
inc(w0);
decG(w);
if (elNum(TI(w0,elType))) return C2(select, w0, x);
w0 = num_squeeze(w0);
if (elNum(TI(w0,elType))) return C2(select, w0, x);
u8 w0e = TI(w0,elType);
if (elNum(w0e)) return C2(select, w0, x);
w0 = squeeze_numTry(w0, &w0e);
if (elNum(w0e)) return C2(select, w0, x);
w = m_vec1(w0);
}
goto base;
@ -367,8 +369,7 @@ B select_c2(B t, B w, B x) {
// else fallthrough - want to do integer 𝕨 if possible
}
case el_B: case el_c8: case el_c16: case el_c32: {
w = num_squeezeChk(w);
we = TI(w,elType);
w = squeeze_numTry(w, &we);
if (elNum(we)) goto retry;
goto def_xf_base;
}
@ -952,8 +953,7 @@ B select_rows_B(B x, ux csz, ux cam, B inds) { // consumes inds,x; ⥊ inds⊸
}
u8 ie = TI(inds,elType);
if (csz<=2? ie!=el_bit : csz<=128? ie>el_i8 : !elInt(ie)) {
inds = num_squeeze(inds);
ie = TI(inds,elType);
inds = squeeze_numTry(inds, &ie);
if (!elInt(ie)) goto generic;
}
void* ip = tyany_ptr(inds);
@ -977,7 +977,7 @@ B select_ucw(B t, B o, B w, B x) {
} else {
we = TI(w,elType);
if (!elInt(we) && IA(w)!=0) {
w = num_squeezeChk(w); we = TI(w,elType);
w = squeeze_numTry(w, &we);
if (!elNum(we)) goto def;
}
}

View File

@ -341,11 +341,11 @@ B count_c1(B t, B x) {
else for (usz j=0; j<tn; j++) tab[j]=0; \
for (usz i=0; i<n; i++) rp[i]=tab[xp[i]]++; \
decG(x); TFREE(tab); \
return num_squeeze(r)
return squeeze_numNewTy(el_i32,r)
if (lw==3) { if (n<12) { BRUTE(8); } else { LOOKUP(8); } }
if (lw==4) { if (n<12) { BRUTE(16); } else { LOOKUP(16); } }
#undef LOOKUP
#define TRY_HASHTAB(W) TRY_HASHTAB_RET(count, W, num_squeeze(r))
#define TRY_HASHTAB(W) TRY_HASHTAB_RET(count, W, squeeze_numNewTy(el_i32,r))
if (lw==5) {
if (n<20) { BRUTE(32); }
i32* rp; B r = m_i32arrv(&rp, n);
@ -369,7 +369,7 @@ B count_c1(B t, B x) {
u32 *tab= (u32*)v1; // tn [+] tab 4*tn ###########
RADIX_LOOKUP_32(0, ++)
return num_squeeze(r);
return squeeze_numNewTy(el_i32,r);
}
if (lw==6 && canCompare64_norm(&x, &xv, n)) {
if (n<20) { BRUTE(64); }
@ -392,7 +392,7 @@ B count_c1(B t, B x) {
rp[i] = had? ++map->a[p].val : (map->a[p].val = 0);
}
decG(x); free_b2i(map);
return num_squeeze(r);
return squeeze_numNewTy(el_i32,r);
}
static B reduceI32WidthBelow(B r, usz after) {

View File

@ -1205,11 +1205,12 @@ NOINLINE B rotate_highrank(bool inv, B w, B x) {
if (wia>xr) goto badlen;
if (wia==0) { r=x; goto decW_ret; }
if (!elNum(TI(w,elType))) {
w = num_squeeze(w);
if (!elNum(TI(w,elType))) thrF("𝕨⌽%U𝕩: 𝕨 contained non-number", INV);
u8 we = TI(w,elType);
if (!elNum(we)) {
w = squeeze_numTry(w, &we);
if (!elNum(we)) thrF("𝕨⌽%U𝕩: 𝕨 contained non-number", INV);
}
bool origF64 = TI(w,elType)==el_f64;
bool origF64 = we==el_f64;
w = toF64Any(w);
f64* wp = tyany_ptr(w);
if (origF64) for (ux i = 0; i < wia; i++) o2i64(m_f64(wp[i]));
@ -1398,7 +1399,7 @@ B pick_ucw(B t, B o, B w, B x) {
if (RARE(c==USZ_MAX)) { mut_pfree(r, i); goto def; }
mut_setG(r, i, m_usz(c));
}
w = num_squeeze(mut_fcd(r, w));
w = squeeze_numNew(mut_fcd(r, w));
B rep = isArr(o)? incG(o) : c1(o, C2(select, incG(w), C1(shape, incG(x))));
// error messages will need to get more non-trivial for deeper mismatches
if (isAtm(rep) || !eqShape(w, rep)) thrF("𝔽⌾(nested⊸⊑)𝕩: 𝔽 must return an array with the same shape as its input (expected %0H, got %0H)", w, rep);

View File

@ -577,7 +577,7 @@ B slash_c1(B t, B x) {
usz xia = IA(x);
B r;
u8 xe = TI(x,elType);
if (xe!=el_bit && s<=xia) { x = num_squeezeChk(x); xe = TI(x,elType); }
if (xe!=el_bit && s<=xia) x = squeeze_numTry(x, &xe);
if (xe==el_bit) {
r = where(x, xia, s);
} else if (RARE(xia > (usz)I32_MAX+1)) {
@ -651,7 +651,7 @@ B slash_c2(B t, B w, B x) {
u64 s;
u8 we = TI(w,elType);
if (!elInt(we)) {
w=any_squeeze(w); we=TI(w,elType);
w=any_squeeze(w); we=TI(w,elType); // TODO move squeeze to before depth(w)
if (!elInt(we)) {
s = usum(w);
goto arrW_base;
@ -666,7 +666,7 @@ B slash_c2(B t, B w, B x) {
if (xl>6 || (xl<3 && xl!=0)) goto arrW_base;
if (s<=wia) {
if (s==0) { r = zeroCells(x); goto decWX_ret; }
w=num_squeezeChk(w); we=TI(w,elType);
w = squeeze_numTry(w, &we);
if (we==el_bit) goto wbool;
}
// s≠0 now
@ -842,7 +842,7 @@ static B finish_small_count(B r, u16* ov) {
// Need to add 1<<15 to r at i for each index i in ov
u16 e = -1; // ov end marker
if (*ov == e) {
r = num_squeeze(r);
r = squeeze_numNew(r);
} else {
r = taga(cpyI32Arr(r)); i32* rp = tyany_ptr(r);
usz on = 0; u16 ovi;
@ -901,7 +901,7 @@ B slash_im(B t, B x) {
usz ria = 1 + (sum>0);
f64* rp; r = m_f64arrv(&rp, ria);
rp[sum>0] = sum; rp[0] = xia - sum;
r = num_squeeze(r); break;
r = squeeze_numNewTy(el_f64,r); break;
}
#if SINGELI_SIMD
#define INIT_RES(N,RIA) \
@ -946,7 +946,7 @@ B slash_im(B t, B x) {
if (rmax<128) { /* xia<128 or xia<ria/8, fine to process x slowly */ \
INIT_RES(8,ria) \
for (usz i = 0; i < xia; i++) rp[xp[i]]++; \
r = num_squeeze(r); break; \
r = squeeze_numNewTy(el_i8,r); break; \
}
#define CASE_SMALL(N) \
case el_i##N: { \
@ -976,7 +976,7 @@ B slash_im(B t, B x) {
if (xia>I32_MAX) thrM("/⁼𝕩: 𝕩 too large");
INIT_RES(32,ria)
simd_count_i32_i32(rp, xp, xia);
r = num_squeeze(r); break;
r = squeeze_numNewTy(el_i32,r); break;
}
#undef TRY_SMALL_OUT
#undef INIT_RES
@ -993,7 +993,7 @@ B slash_im(B t, B x) {
if (xia<=I32_MAX) { i32* rp; r = m_i32arrv(&rp, ria); vfor (usz i=0; i<ria; i++) rp[i]=t[i]; } \
else { f64* rp; r = m_f64arrv(&rp, ria); vfor (usz i=0; i<ria; i++) rp[i]=t[i]; } \
TFREE(t); \
r = num_squeeze(r); break; }
r = squeeze_numNew(r); break; }
CASE(8) CASE(16) CASE(32)
#undef CASE
#endif
@ -1014,8 +1014,7 @@ B slash_im(B t, B x) {
break;
}
case el_c8: case el_c16: case el_c32: case el_B: {
x = num_squeezeChk(x);
xe = TI(x,elType);
x = squeeze_numTry(x, &xe);
if (elNum(xe)) goto retry;
B* xp = TO_BPTR(x);
for (usz i=0; i<xia; i++) o2i64(xp[i]);
@ -1066,15 +1065,16 @@ B slash_ucw(B t, B o, B w, B x) {
}
usz ia = IA(x);
SGetU(w)
if (TI(w,elType) != el_bit) {
w = num_squeezeChk(w);
if (!elInt(TI(w,elType))) goto base;
u8 we = TI(w,elType);
if (we != el_bit) {
w = squeeze_numTry(w, &we);
if (!elInt(we)) goto base;
}
// (c ; C˙)¨⌾(w⊸/) x
#if SINGELI_SIMD
if (isFun(o) && TY(o)==t_md1D) {
if (TI(w,elType) != el_bit) goto notConstEach; // TODO could do w↩w≠0 after range checking
if (we != el_bit) goto notConstEach; // TODO could do w↩w≠0 after range checking
u8 xe = TI(x,elType);
if (xe==el_B) goto notConstEach;
@ -1130,8 +1130,7 @@ B slash_ucw(B t, B o, B w, B x) {
u8 re = el_or(TI(x,elType), TI(rep,elType));
MAKE_MUT_INIT(r, ia, re? re : 1);
usz repI = 0;
bool wb = TI(w,elType) == el_bit;
if (wb && re!=el_B) {
if (we==el_bit && re!=el_B) {
u64* d = bitany_ptr(w);
void* rp = r->a;
switch (re) { default: UD;
@ -1164,7 +1163,7 @@ B slash_ucw(B t, B o, B w, B x) {
} else {
SGet(x) SGet(rep) MUTG_INIT(r);
if (wb) {
if (we == el_bit) {
u64* d = bitany_ptr(w);
for (usz i = 0; i < ia; i++) mut_setG(r, i, bitp_get(d, i)? Get(rep,repI++) : Get(x,i));
} else {

View File

@ -244,31 +244,54 @@ NOINLINE B int_squeeze_sorted(B x, Arr* xa, u8 type, ux ia) {
NOINLINE B any_squeeze(B x) {
assert(isArr(x));
if (FL_HAS(x, fl_squoze|fl_asc|fl_dsc)) {
if (FL_HAS(x, fl_squoze)) return x;
if (elInt(TI(x,elType))) return int_squeeze_sorted(x, a(x), TY(x), IA(x));
// could check for sorted character arrays (even from a TI(x,el_B) input) but sorted character arrays aren't worth it
}
#define SQ_FAST(RET) if (FL_HAS(x, fl_squoze)) { RET; }
#define SQ_FAST_EXT(NEW, RET) \
if (FL_HAS(x, fl_squoze|fl_asc|fl_dsc)) { \
SQ_FAST(RET) \
if (elInt(TI(x,elType))) { x = int_squeeze_sorted(x, a(x), TY(x), ia); NEW; RET; } \
} // could check for sorted character arrays (even from a TI(x,el_B) input) but sorted character arrays aren't worth it
#define SQ_READ \
assert(isArr(x)); \
u8 xe = TI(x,elType); \
usz ia = IA(x);
NOINLINE B any_squeeze(B x) {
SQ_READ;
SQ_FAST_EXT(, return x);
if (ia==0) return FL_SET(x, fl_squoze); // TODO return a version of the smallest type?
return squeeze_anyFns[TI(x,elType)](x, a(x), TY(x), ia);
return squeeze_anyFns[xe](x, a(x), TY(x), ia);
}
NOINLINE B num_squeeze(B x) {
assert(isArr(x));
u8 xe = TI(x,elType);
if (IA(x) == 0) return xe==el_bit? x : emptyNumsWithShape(x);
return squeeze_numFns[xe](x,a(x),TY(x),IA(x));
NOINLINE B squeeze_numNew(B x) {
SQ_READ;
if (ia==0) return xe==el_bit? x : emptyNumsWithShape(x);
return squeeze_numFns[xe](x,a(x),TY(x),ia);
}
NOINLINE B chr_squeeze(B x) {
assert(isArr(x));
u8 xe = TI(x,elType);
if (IA(x) == 0) return xe==el_c8? x : emptyChrsWithShape(x);
return squeeze_chrFns[xe](x,a(x),TY(x),IA(x));
NOINLINE B squeeze_chrNew(B x) {
SQ_READ;
if (ia==0) return xe==el_c8? x : emptyChrsWithShape(x);
return squeeze_chrFns[xe](x,a(x),TY(x),ia);
}
SqRes squeeze_numTryImpl(B x) {
SQ_READ;
if (ia==0) return (SqRes){xe==el_bit? x : emptyNumsWithShape(x), el_bit};
SQ_FAST_EXT(xe=TI(x,elType), return ((SqRes){x, xe}));
x = squeeze_numFns[xe](x,a(x),TY(x),ia);
return (SqRes){x, TI(x,elType)};
}
SqRes squeeze_chrTryImpl(B x) {
SQ_READ;
SQ_FAST(return ((SqRes){x, xe}));
if (ia==0) return (SqRes){xe==el_c8? x : emptyChrsWithShape(x), el_c8};
x = squeeze_chrFns[xe](x,a(x),TY(x),ia);
return (SqRes){x, TI(x,elType)};
}
B squeeze_numOut(B x) { return squeeze_numTryImpl(x).r; }
B squeeze_chrOut(B x) { return squeeze_chrTryImpl(x).r; }
B squeeze_deep(B x) {

View File

@ -120,15 +120,17 @@ B parseFloat_c1(B t, B x) { thrM("•ParseFloat 𝕩: Not supported with Ryu dis
B parseFloat_c1(B t, B x) {
if (isAtm(x)) thrM("•ParseFloat 𝕩: Expected a character list argument");
if (TI(x,elType)!=el_c8) {
x = chr_squeeze(x);
if (TI(x,elType)!=el_c8) {
if (elChr(TI(x,elType))) malformed: thrM("•ParseFloat 𝕩: Malformed input");
u8 xe;
x = squeeze_chrTry(x, &xe);
if (xe!=el_c8) {
if (IA(x)==0) goto empty;
if (elChr(xe)) malformed: thrM("•ParseFloat 𝕩: Malformed input");
thrM("•ParseFloat 𝕩: Expected a character list argument");
}
}
usz ia = IA(x);
if (RNK(x)!=1) thrM("•ParseFloat 𝕩: Input must have rank 1");
if (ia==0) thrM("•ParseFloat 𝕩: Input was empty");
if (ia==0) empty: thrM("•ParseFloat 𝕩: Input was empty");
if (ia >= (1<<20)) thrM("•ParseFloat 𝕩: Input too long"); // assumption by ryu_s2d_n
u8* data = c8any_ptr(x);
f64 res;

View File

@ -129,14 +129,13 @@ B withFill(B x, B fill) { // consumes both
}
usz ia = IA(x);
if (!FL_HAS(x,fl_squoze)) {
u8 xe;
if (isNum(fill)) {
x = num_squeeze(x);
if (elNum(TI(x,elType))) return x;
FL_KEEP(x, ~fl_squoze);
x = squeeze_numTry(x, &xe);
if (elNum(xe)) return x;
} else if (isC32(fill)) {
x = chr_squeeze(x);
if (elChr(TI(x,elType))) return x;
FL_KEEP(x, ~fl_squoze);
x = squeeze_chrTry(x, &xe);
if (elChr(xe)) return x;
}
}
Arr* r;

View File

@ -209,12 +209,7 @@ i32 num_fmt(char buf[30], f64 x) {
}
static B appendRaw(B s, B x) { assert(isArr(x) && RNK(x)==1); // consumes x
if (TI(x,elType)==el_c32) AJOIN(x);
else {
B sq = chr_squeezeChk(x);
if (!elChr(TI(sq,elType))) FL_KEEP(sq, ~fl_squoze);
AJOIN(sq);
}
AJOIN(squeeze_chrOut(x));
return s;
}
NOINLINE B do_fmt(B s, char* p, va_list a) {

View File

@ -277,15 +277,26 @@ bool isPureFn(B x); // doesn't consume
bool isStr(B x); // doesn't consume; returns if x is a rank 1 array of characters (includes any empty array)
B bqn_merge(B x, u32 type); // consumes
B any_squeeze(B x); // consumes; accepts any array, returns one with the smallest type (doesn't recurse!)
B squeeze_deep(B x); // consumes; accepts any object, returns an object with all parts necessary for equality checking & hashing squeezed; if this function errors due to OOM, the argument won't yet be consumed
B num_squeeze(B x); // consumes; always returns a bitarr on empty input
B chr_squeeze(B x); // consumes; always returns a c8arr on empty input
typedef struct { B r; u8 re; } SqRes;
#define SQ_UNPACK(F) SqRes r = F(x); *re_out = r.re; assert(r.re == TI(r.r,elType)); return r.r;
SqRes squeeze_numTryImpl(B x);
SqRes squeeze_chrTryImpl(B x);
// these return an arbitrary-type array on empty input
static inline B num_squeezeChk(B x) { return FL_HAS(x,fl_squoze)? x : num_squeeze(x); }
static inline B chr_squeezeChk(B x) { return FL_HAS(x,fl_squoze)? x : chr_squeeze(x); }
B squeeze_numNew(B x); // consumes; doesn't try using any existing flags; primarily intended for squeezing a newly-created array; returns bitarr for IA(x)==0
B squeeze_chrNew(B x); // consumes; doesn't try using any existing flags; primarily intended for squeezing a newly-created array; returns c8arr for IA(x)==0
static B squeeze_numNewTy(u8 xe, B x) { debug_assert(TI(x,elType)==xe); return squeeze_numNew(x); } // squeeze_numNew but with a known eltype; currently eltype isn't used for anything
static B squeeze_numTry(B x, u8* re_out) { SQ_UNPACK(squeeze_numTryImpl) } // consumes; always returns bitarr for IA(x)==0; utilizes squoze/sortedness flags
static B squeeze_chrTry(B x, u8* re_out) { SQ_UNPACK(squeeze_chrTryImpl) } // consumes; always returns bitarr for IA(x)==0; utilizes squoze/sortedness flags
B squeeze_numOut(B x); // consumes; squeeze_numTry but without re_out
B squeeze_chrOut(B x); // consumes; squeeze_chrTry but without re_out
B def_fn_uc1(B t, B o, B x); B def_fn_ucw(B t, B o, B w, B x);
B def_m1_uc1(Md1* t, B o, B f, B x); B def_m1_ucw(Md1* t, B o, B f, B w, B x);

View File

@ -315,8 +315,7 @@ static u32 styG(B x) {
if (buf[1]>max) thrF("FFI: Array provided for %S%S contained %l", ref, desc, buf[1]);
decG(x);
}
static bool elChrOk(B x, u64 max) {
u8 xe = TI(x,elType);
static bool elChrOk(B x, u64 max, u8 xe) {
if (xe==el_c8) return true;
if (xe==el_c16 && max>=U16_MAX) return true;
if (xe==el_c32 && max>=U32_MAX) return true;
@ -329,9 +328,10 @@ static u32 styG(B x) {
if (IA(x)==0) return;
B nonChr = nonChar(x);
if (nonChr.u!=bi_N.u) thrF("FFI: Array provided for :c%S contained %S", desc+1, genericDesc(nonChr));
if (elChrOk(x, umax)) return;
B sq = chr_squeeze(incG(x));
bool ok = elChrOk(sq, umax);
u8 xe = TI(x,elType);
if (elChrOk(x, umax, xe)) return;
B sq = squeeze_chrTry(incG(x), &xe);
bool ok = elChrOk(sq, umax, xe);
decG(sq);
if (!ok) thrF("FFI: Array provided for :c%S contained %S", desc+1, genericDesc(nonChr));
}
@ -579,7 +579,7 @@ DecoratedType ffi_parseDecoratedType(B arg, bool forRes) { // doesn't consume; p
if (!forRes) thrM("Type parser: Type was empty");
return (DecoratedType){{.o=m_c32(sty_void), .resSingle=false}, .ffitype = ffi_type_void};
}
arg = chr_squeezeChk(incG(arg));
arg = squeeze_chrOut(incG(arg));
u32* xp0 = parseType_pre(arg, ia);
u32* xp = xp0;
@ -659,9 +659,9 @@ static B toU16Bits(B x) { return TI(x,elType)==el_i16? x : cpyU16Bits(x); }
static B toU8Bits(B x) { return TI(x,elType)==el_i8? x : cpyU8Bits(x); }
// read x as the specified type (assuming a container of the respective width signed integer array); consumes x
NOINLINE B readU8Bits(B x) { usz ia=IA(x); u8* xp=tyarr_ptr(x); i16* rp; B r=m_i16arrv(&rp, ia); vfor (usz i=0; i<ia; i++) rp[i]=xp[i]; return num_squeeze(r); }
NOINLINE B readU16Bits(B x) { usz ia=IA(x); u16* xp=tyarr_ptr(x); i32* rp; B r=m_i32arrv(&rp, ia); vfor (usz i=0; i<ia; i++) rp[i]=xp[i]; return num_squeeze(r); }
NOINLINE B readU32Bits(B x) { usz ia=IA(x); u32* xp=tyarr_ptr(x); f64* rp; B r=m_f64arrv(&rp, ia); vfor (usz i=0; i<ia; i++) rp[i]=xp[i]; return num_squeeze(r); }
NOINLINE B readU8Bits(B x) { usz ia=IA(x); u8* xp=tyarr_ptr(x); i16* rp; B r=m_i16arrv(&rp, ia); vfor (usz i=0; i<ia; i++) rp[i]=xp[i]; return squeeze_numNewTy(el_i16,r); }
NOINLINE B readU16Bits(B x) { usz ia=IA(x); u16* xp=tyarr_ptr(x); i32* rp; B r=m_i32arrv(&rp, ia); vfor (usz i=0; i<ia; i++) rp[i]=xp[i]; return squeeze_numNewTy(el_i32,r); }
NOINLINE B readU32Bits(B x) { usz ia=IA(x); u32* xp=tyarr_ptr(x); f64* rp; B r=m_f64arrv(&rp, ia); vfor (usz i=0; i<ia; i++) rp[i]=xp[i]; return squeeze_numNewTy(el_f64,r); }
NOINLINE B readF32Bits(B x) { usz ia=IA(x); f32* xp=tyarr_ptr(x); f64* rp; B r=m_f64arrv(&rp, ia); vfor (usz i=0; i<ia; i++) rp[i]=xp[i]; return r; }
B m_ptrobj_s(void* ptr, B o); // consumes o, sets stride to size of o
B m_ptrobj(void* ptr, B o, ux stride); // consumes o

View File

@ -135,7 +135,7 @@ INS B i_LST_p(B el0, i64 sz, B* cStack) { assert(sz>0);
r.a[sz-1] = el0;
for (i64 i = 1; i < sz; i++) if (!isNum(r.a[sz-i-1] = GSP)) allNum = false;
NOGC_E; GS_UPD;
if (allNum) return num_squeeze(r.b);
if (allNum) return squeeze_numNew(r.b);
return r.b;
}
INS B i_ARMO(B el0, i64 sz, u32* bc, B* cStack) { assert(sz>0); POS_UPD;
@ -399,7 +399,7 @@ static OptRes opt(u32* bc0) {
RM(c.p);
}
NOGC_E;
B r = allNum? num_squeeze(h.b) : h.b;
B r = allNum? squeeze_numNew(h.b) : h.b;
cact = 5;
TSADD(data, r.u);
stk[TSSIZE(stk)-1] = SREF(r, pos);

View File

@ -234,7 +234,7 @@ static NOINLINE void comps_push(B src, B state, B re) {
#define COMPS_POP ({ ptr_dec(comps_curr); comps_curr = NULL; })
static NOINLINE Block* bqn_compc(B str, B state, B re) { // consumes str,state
str = chr_squeeze(str);
str = squeeze_chrOut(str);
COMPS_PUSH(str, state, re);
B* o = harr_ptr(re);
Block* r = load_buildBlock(c2G(o[re_compFn], incG(o[re_compOpts]), inc(str)), str, COMPS_CREF(path), COMPS_CREF(name), NULL, 0);
@ -245,7 +245,7 @@ Block* bqn_comp(B str, B state) {
return bqn_compc(str, state, def_re);
}
Block* bqn_compScc(B str, B state, B re, Scope* sc, bool loose, bool noNS) {
str = chr_squeeze(str);
str = squeeze_chrOut(str);
COMPS_PUSH(str, state, re);
B* o = harr_ptr(re);
B vName = emptyHVec();

View File

@ -85,7 +85,7 @@ NOINLINE B dyArith_AA(DyTableAA* table, B w, B x) {
case u_call_wxf64sq: {
f64* rp; r = m_f64arrc(&rp, x);
fn->uFn(rp, tyany_ptr(w = toF64Any(w)), tyany_ptr(x = toF64Any(x)), ia);
r = num_squeeze(r);
r = squeeze_numNewTy(el_f64,r);
goto decG_ret;
}
case c_call_wxi8: {
@ -95,9 +95,9 @@ NOINLINE B dyArith_AA(DyTableAA* table, B w, B x) {
goto c_call_rbyte;
}
case e_call_sqx: {
assert(TI(x,elType)==el_f64);
x = num_squeezeChk(x);
u8 xe = TI(x,elType);
assert(xe==el_f64);
x = squeeze_numTry(x, &xe);
if (xe==el_f64) goto rec;
e = &table->entsAA[TI(w,elType)*8 + xe];
goto newEnt;
@ -189,7 +189,7 @@ NOINLINE B dyArith_SA(DyTableSA* table, B w, B x) {
case el_i8: if (wa==( u8)wa) { e=&table->ents[el_i8 ]; width=0; type=t_c8arr; goto f1; } else goto cwiden_i8;
case el_i16: if (wa==(u16)wa) { e=&table->ents[el_i16]; width=1; type=t_c16arr; goto f1; } else goto cwiden_i16;
case el_i32: e=&table->ents[el_i32]; width=2; type=t_c32arr; goto f1;
case el_f64: x=num_squeezeChk(x); xe=TI(x,elType); if (xe!=el_f64) goto newXEc; else goto rec;
case el_f64: x=squeeze_numTry(x, &xe); if (xe!=el_f64) goto newXEc; else goto rec;
case el_c8: if (wa==( u8)wa) { e=&table->ents[el_c8 ]; width=0; type=t_i8arr; goto f1; } goto cwiden_c8; // TODO check for & use unsigned w
case el_c16: if (wa==(u16)wa) { e=&table->ents[el_c16]; width=1; type=t_i16arr; goto f1; } goto cwiden_c16;
case el_c32: e=&table->ents[el_c32]; width=2; type=t_i32arr; goto f1;
@ -282,13 +282,13 @@ B sub_c2R(B t, B w, B x) { return sub_c2(t, x, w); }
static NOINLINE B or_SA(B t, B w, B x) {
if (!isF64(w)) return arith_recd(or_c2, w, x);
if (LIKELY(TI(x,elType)==el_bit)) {
u8 xe = TI(x,elType);
if (LIKELY(xe==el_bit)) {
bitsel:;
f64 wf = o2fG(w);
return bit_sel(x, m_f64(bqn_or(wf, 0)), m_f64(bqn_or(wf, 1)));
}
x = num_squeezeChk(x);
u8 xe = TI(x,elType);
x = squeeze_numTry(x, &xe);
if (xe==el_bit) goto bitsel;
if (!elNum(xe)) return arith_recd(or_c2, w, x);
x = toF64Any(x);

View File

@ -807,7 +807,7 @@ B evalBC(Body* b, Scope* sc, Block* bl) { // doesn't consume
NOGC_E;
if (allNum) {
GS_UPD;
ADD(num_squeeze(r.b));
ADD(squeeze_numNew(r.b));
} else ADD(r.b);
}
break;