diff --git a/src/builtins/cells.c b/src/builtins/cells.c index cf7934a6..1378e36c 100644 --- a/src/builtins/cells.c +++ b/src/builtins/cells.c @@ -102,6 +102,21 @@ B select_cells_base(B inds, B x0, ux csz, ux cam) { // consumes inds,x0; Used by return taga(APD_SH_GET(r, '\0')); } +static B scan_cells_stride1(B f, B x, usz m) { + // m is cell size == scan axis length + B xf = getFillR(x); + HArr_p r = m_harr0c(x); + SGet(x) + FC2 fc2 = c2fn(f); + for (usz i=0, ia=IA(x); if)) break; - u8 frtid = RTID(fd->f); + B f = fd->f; + if (!isFun(f)) break; + u8 frtid = RTID(f); if (frtid==n_rtack) return x; - if (TI(x,elType)==el_bit && (isPervasiveDyExt(fd->f)||frtid==n_ltack) - && 1==shProd(xsh, k+1, xr)) { - B r = scan_rows_bit(frtid, x, m); if (!q_N(r)) return r; + if (cr==1 || cam*m == IA(x)) { + if (TI(x,elType)==el_bit && (isPervasiveDy(f) || frtid==n_ltack)) { + B r = scan_rows_bit(frtid, x, m); if (!q_N(r)) return r; + } + if (m <= 6) return scan_cells_stride1(f, x, m); } break; } diff --git a/src/builtins/fold.c b/src/builtins/fold.c index bb9312ca..68d13eec 100644 --- a/src/builtins/fold.c +++ b/src/builtins/fold.c @@ -383,6 +383,68 @@ static B m1c1(B t, B f, B x) { // consumes x } extern B insert_base(B f, B x, bool has_w, B w); // from cells.c +static bool fillNumeric(B x) { + if (x.u==0) return true; + if (isAtm(x)) return false; + u8 xe = TI(x,elType); + usz ia = IA(x); + if (xe!=el_B) return ia==0 || elNum(xe); + if (!fillNumeric(getFillN(x))) return false; + if (ia==0) return true; + SGetU(x) + for (usz i=0; i1) shcpy(rsh, SH(x)+1, rr); + usz xi = xia - csz; + + B xf = getFillN(x); + B rf; + if (has_w) { + // fxw is (⊢˝𝕩)𝔽𝕨 so shape errors have been caught + rf = getFillR(fxw); + COPY_TO(r.a, el_B, 0, fxw, 0, csz); + decG(fxw); + } else { + rf = inc(xf); + COPY_TO(r.a, el_B, 0, x, xi, csz); + } + + SGet(x) + while (xi) { + xi -= csz; + for (usz i=0; i 2); + #if SEMANTIC_CATCH + if (CATCH) { + freeThrown(); + rf = bi_noFill; + } else { + if (!has_w) rf = fc2(f, inc(xf), rf); + if (n%2 == !has_w) rf = fc2(f, inc(xf), rf); + else fc2(f, inc(xf), inc(rf)); // could error, -˜˝"abc" + popCatch(); + } + #else + if (n%2 == 0) { dec(rf); rf = bi_noFill; } + #endif + } + decG(x); + return withFill(r.b, rf); +} + B insert_c1(Md1D* d, B x) { B f = d->f; ur xr; if (isAtm(x) || (xr=RNK(x))==0) thrM("𝔽˝𝕩: 𝕩 must have rank at least 1"); @@ -410,7 +472,8 @@ B insert_c1(Md1D* d, B x) { B f = d->f; if (RARE(!isFun(f))) { decG(x); if (isMd(f)) thrM("Calling a modifier"); return inc(f); } if (isPervasiveDyExt(f)) { if (xr==1) return m_unit(fold_c1(d, x)); - if (len==IA(x)) { + usz xia = IA(x); + if (len==xia) { B r = m_vec1(fold_c1(d, C1(shape, x))); ur rr = xr - 1; if (rr > 1) { @@ -420,6 +483,9 @@ B insert_c1(Md1D* d, B x) { B f = d->f; } return r; } + if (len>2 && xia<6*(u64)len) { + return insert_scal(f, c2fn(f), x, 0, m_f64(0), xia, xr-1); + } } if (RTID(f) != RTID_NONE) { u8 rtid = RTID(f); @@ -448,26 +514,34 @@ B insert_c2(Md1D* d, B w, B x) { B f = d->f; usz len = *SH(x); if (len==0) { decG(x); return w; } if (RARE(!isFun(f))) { dec(w); decG(x); if (isMd(f)) thrM("Calling a modifier"); return inc(f); } - if (isPervasiveDyExt(f) && len==IA(x)) { - // 1-element arrays are always conformable - // final rank is higher of w, cell rank of x + if (isPervasiveDyExt(f)) { + usz xia = IA(x); ur rr = xr - 1; - if (isArr(w)) { - if (IA(w) != 1) goto skip; - ur wr = RNK(w); if (wr>rr) rr = wr; - w = TO_GET(w, 0); - } - if (xr > 1) x = C1(shape, x); - B r = m_unit(fold_c2(d, w, x)); - if (rr > 0) { - if (rr == 1) arr_shVec(a(r)); - else { - ShArr* rsh = m_shArr(rr); - PLAINLOOP for (ur i=0; ia[i] = 1; - arr_shReplace(a(r), rr, rsh); + if (len==xia) { + // 1-element arrays are always conformable + // final rank is higher of w, cell rank of x + if (isArr(w)) { + if (IA(w) != 1) goto skip; + ur wr = RNK(w); if (wr>rr) rr = wr; + w = TO_GET(w, 0); } + if (xr > 1) x = C1(shape, x); + B r = m_unit(fold_c2(d, w, x)); + if (rr > 0) { + if (rr == 1) arr_shVec(a(r)); + else { + ShArr* rsh = m_shArr(rr); + PLAINLOOP for (ur i=0; ia[i] = 1; + arr_shReplace(a(r), rr, rsh); + } + } + return r; + } + if (len>2 && xia<6*(u64)len && !(isArr(w) && RNK(w)>rr)) { + FC2 fc2 = c2fn(f); + w = fc2(f, C2(select, m_f64(-1), incG(x)), w); + return insert_scal(f, fc2, x, 1, w, xia, rr); } - return r; skip:; } if (RTID(f) != RTID_NONE) { diff --git a/test/cases/fills.bqn b/test/cases/fills.bqn index c2f2635f..5cf46826 100644 --- a/test/cases/fills.bqn +++ b/test/cases/fills.bqn @@ -30,6 +30,10 @@ %USE fill ⋄ Fill ⊢¨"" %EACH_FILLS %% ' ' %USE fill ⋄ Fill ⊢∘⊢¨"" %EACH_FILLS %% ' ' +{3↑ -˝𝕩‿2⥊<<'a'}¨ 5‿6 %!HEAPVERIFY %% <¨¨ ⟨"aa ", 3⥊0⟩ +{3↑ (2⥊2)-˝𝕩‿2⥊<<'x'}¨ 5‿6 %!HEAPVERIFY %% <¨¨ ⟨"vv ", 2‿2‿0⟩ +{3↑ "ee"-˝𝕩‿2⥊<<'a'}¨ 5‿6 %!HEAPVERIFY %% <¨¨ ⟨¯4‿¯4‿0, "ee "⟩ + # TODO: # ⟨↑‿3⥊↕10 ⋄ ↑‿3⥊<¨↕10 ⋄ ↑‿3⥊<˘↕10⟩ # 5‿¯5↑⌜⟨↕2 ⋄ "ab" ⋄ <¨↕2 ⋄ <˘↕2⟩ diff --git a/test/cases/prims.bqn b/test/cases/prims.bqn index 758dc5db..589eb8e7 100644 --- a/test/cases/prims.bqn +++ b/test/cases/prims.bqn @@ -515,6 +515,13 @@ a←↕2 ⋄ ! "e" ≡ (↕10){b←a‿a‿a‿a‿a‿a‿a‿a‿a‿a ⋄ # ˝ !"𝔽˝𝕩: 𝕩 must have rank at least 1" % ⊢˝0 !"𝔽˝𝕩: Identity not found" % •internal.Keep˝⟨⟩ +(↕4)+˝↕7 %% 21‿22‿23‿24 +(2‿2⥊↕4)+˝7‿2‿2⥊↕28 %% 2‿2⥊84‿92‿100‿108 +(2‿2⥊↕4)+˝2‿2⥊↕28 %% 2‿2⥊2‿3‿6‿7 ++˝ ↕10‿4 %% 45 ⋈¨ 10×↕4 +( ↕4) +˝ ↕10‿4 %% (↕4) + 45 ⋈¨ 10×↕4 +(<¨ ↕4) +˝ ↕10‿4 %% (↕4) + 45 ⋈¨ 10×↕4 +(0‿5⊸+¨↕4) +˝ ↕10‿4 %% ((↕4) + 45) ⋈¨ 5 + 11×↕4 # ⌜ !"𝕨𝔽⌜𝕩: Result rank too large (200≡=𝕨, 200≡=𝕩)" % +⌜˜(200⥊1)⥊1