diff --git a/src/builtins/scan.c b/src/builtins/scan.c index bca121af..90371f60 100644 --- a/src/builtins/scan.c +++ b/src/builtins/scan.c @@ -133,13 +133,25 @@ B shape_c2(B, B, B); MM_CASE(f64,NAME,C,w.f) \ } \ decG(x); return FL_SET(r, fl_##ORD); -static B scan2_min_num(B w, B x, u8 xe, usz ia) { MINMAX2(min,<,MAX,and,1,dsc) } -static B scan2_max_num(B w, B x, u8 xe, usz ia) { MINMAX2(max,>,MIN,or ,0,asc) } +SHOULD_INLINE B scan2_min_num(B w, B x, u8 xe, usz ia) { MINMAX2(min,<,MAX,and,1,dsc) } +SHOULD_INLINE B scan2_max_num(B w, B x, u8 xe, usz ia) { MINMAX2(max,>,MIN,or ,0,asc) } #undef MINMAX2 #undef MM_CASE #undef MM_CASE2 #undef MINMAX_SCAN +static B scan_lt(B x, u64 p, usz ia) { + u64* xp = bitarr_ptr(x); + u64* rp; B r=m_bitarrv(&rp,ia); usz n=BIT_N(ia); + u64 m10 = 0x5555555555555555; + for (usz i=0; i>63); + rp[i] = p = x & (m10 ^ (x + c)); + } + decG(x); return r; +} + B scan_c1(Md1D* d, B x) { B f = d->f; if (isAtm(x) || RNK(x)==0) thrM("`: Argument cannot have rank 0"); ur xr = RNK(x); @@ -150,36 +162,33 @@ B scan_c1(Md1D* d, B x) { B f = d->f; if (xr==1 && xe<=el_f64 && isFun(f) && v(f)->flags) { u8 rtid = v(f)->flags-1; if (xe==el_bit) { - u64* xp=bitarr_ptr(x); - if (rtid==n_add ) return scan_add_bool(x, ia); - if (rtid==n_or | rtid==n_ceil ) return scan_or(x, ia); - if (rtid==n_and | rtid==n_mul | rtid==n_floor) return scan_and(x, ia); - if (rtid==n_ne ) return scan_ne(x, 0, ia); - if (rtid==n_lt) { - u64* rp; B r=m_bitarrv(&rp,ia); usz n=BIT_N(ia); - u64 m10 = 0x5555555555555555; - u64 p = 0; - for (usz i=0; i>63); - rp[i] = p = x & (m10 ^ (x + c)); - } - decG(x); return r; - } + if (rtid==n_add ) return scan_add_bool(x, ia); // + + if (rtid==n_or | rtid==n_ceil ) return scan_or(x, ia); // ∨⌈ + if (rtid==n_and | rtid==n_mul | rtid==n_floor) return scan_and(x, ia); // ∧×⌊ + if (rtid==n_ne ) return scan_ne(x, 0, ia); // ≠ + if (rtid==n_lt) return scan_lt(x, 0, ia); // < goto base; } if (rtid==n_add) { // + - if (xe==el_i8 ) { i8* xp=i8any_ptr (x); i32* rp; B r=m_i32arrv(&rp, ia); i32 c=0; for (usz i=0; if; return withFill(r.b, xf); } +B add_c2(B, B, B); B scan_c2(Md1D* d, B w, B x) { B f = d->f; if (isAtm(x) || RNK(x)==0) thrM("`: 𝕩 cannot have rank 0"); ur xr = RNK(x); usz* xsh = SH(x); usz ia = IA(x); B wf = getFillQ(w); u8 xe = TI(x,elType); - if (xr==1 && xe<=el_f64 && isFun(f) && v(f)->flags) { + if (xr==1 && elNum(xe) && isFun(f) && v(f)->flags && isF64(w)) { u8 rtid = v(f)->flags-1; + if (rtid==n_floor) return scan2_min_num(w, x, xe, ia); // ⌊ if (rtid==n_ceil ) return scan2_max_num(w, x, xe, ia); // ⌈ - if (!q_i32(w)) goto base; - i32 wv = o2iG(w); - if (xe==el_bit) { - u64* xp=bitarr_ptr(x); - if (rtid==n_add) { i32* rp; B r=m_i32arrv(&rp, ia); i64 c=wv; for (usz i=0; i=(1ULL<<53) || wv+(i64)ia >= (1ULL<<53)) goto base; + B t = scan_add_bool(x, ia); + return wv==0? t : C2(add, w, t); + } + + if (!q_i32(w) || !elInt(xe)) goto base; + i32 c = o2iG(w); + i32* rp; B r = m_i32arrv(&rp, ia); + if (xe==el_i8 ) { i8* xp=i8any_ptr (x); for (usz i=0; i