From 3e6e158696bc48d53eda164302deab3a56008c63 Mon Sep 17 00:00:00 2001 From: dzaima Date: Thu, 24 Aug 2023 19:38:23 +0300 Subject: [PATCH] =?UTF-8?q?native=20=F0=9D=95=A8=E2=8D=B7=F0=9D=95=A9=20wh?= =?UTF-8?q?en=201=E2=89=A5=3D=F0=9D=95=A8=20and=202=E2=89=A5=3D?= =?UTF-8?q?=F0=9D=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/cells.c | 2 +- src/builtins/fns.c | 34 +++++++++++++++++++++++++++++----- test/cases/prims.bqn | 9 +++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/builtins/cells.c b/src/builtins/cells.c index a767a7a4..9f9357b6 100644 --- a/src/builtins/cells.c +++ b/src/builtins/cells.c @@ -329,7 +329,7 @@ static B const_cells(B x, ur k, usz* xsh, B v, u32 chr) { // consumes v, x NOINLINE B for_cells_AS(B f, B w, B x, ur wcr, ur wr, u32 chr); -NOINLINE B for_cells_SA(B f, B w, B x, ur xcr, ur xr, u32 chr); +NOINLINE B for_cells_SA(B f, B w, B x, ur xcr, ur xr, u32 chr); // referenced in fns.c NOINLINE B for_cells_AA(B f, B w, B x, ur wcr, ur xcr, u32 chr); static NOINLINE B c1wrap(B f, B x) { B r = c1(f, x); return isAtm(r)? m_unit(r) : r; } diff --git a/src/builtins/fns.c b/src/builtins/fns.c index 18664dec..e8adcaae 100644 --- a/src/builtins/fns.c +++ b/src/builtins/fns.c @@ -3,6 +3,7 @@ #include "../utils/calls.h" #include "../utils/mut.h" #include "../utils/talloc.h" +#include "../utils/each.h" #include "../builtins.h" #include "../nfns.h" @@ -224,19 +225,21 @@ B fne_c2(B t, B w, B x) { } -extern B eq_c2(B, B, B); -extern B slash_c1(B, B); +NOINLINE B for_cells_SA(B f, B w, B x, ur xcr, ur xr, u32 chr); // from cells.c +B eq_c2(B, B, B); +B feq_c2(B, B, B); +B slash_c1(B, B); extern B rt_find; B find_c2(B t, B w, B x) { ur wr = isAtm(w) ? 0 : RNK(w); ur xr = isAtm(x) ? 0 : RNK(x); if (wr > xr) thrF("⍷: Rank of 𝕨 must be at most rank of 𝕩 (%i≡=𝕨, %i≡=𝕩)", wr, xr); u8 xe, we ONLY_GCC(= 0); + B r; if (xr==1 && (xe=TI(x,elType))!=el_B && xe!=el_bit && (isAtm(w) || (we=TI(w,elType))!=el_B)) { if (wr == 0) return C2(eq, w, x); usz wl = IA(w); usz xl = IA(x); - B r; if (wl > xl) { r = emptyIVec(); goto dec_ret; } if (wl == 0) { r = taga(arr_shVec(allOnes(xl+1))); goto dec_ret; } // Compare elements of w to slices of x @@ -271,10 +274,31 @@ B find_c2(B t, B w, B x) { } } TFREE(eq_res); - dec_ret:; - decG(x); decG(w); return r; + goto dec_ret; + } + if (wr==0) { assert(wr==0); return eachd_fn(bi_feq, w, x, feq_c2); } + assert(wr>0 && xr>0); + + if (IA(x)==0) { + emptyres:; + Arr* ra = allZeroes(0); + usz* rsh = arr_shAlloc(ra, xr); + usz* wsh=SH(w); usz* xsh=SH(x); + shcpy(rsh, xsh, xr-wr); + xsh+=xr-wr; rsh+=xr-wr; + PLAINLOOP for (ux i = 0; i < wr; i++) rsh[i] = wsh[i]>xsh[i]? 0 : xsh[i]-wsh[i]+1; + r = taga(ra); + goto dec_ret; + } + + if (wr==1 && xr==2) { + if (IA(w) > SH(x)[1]) goto emptyres; + return for_cells_SA(bi_find, w, x, 1, 2, 0); } return c2rt(find, w, x); + + dec_ret:; + decG(x); decG(w); return r; } static H_b2i* prevImports; diff --git a/test/cases/prims.bqn b/test/cases/prims.bqn index d8d1c99d..f2af5b8c 100644 --- a/test/cases/prims.bqn +++ b/test/cases/prims.bqn @@ -250,6 +250,15 @@ w←1‿1⥊1 ⋄ x←2⥊1 ⋄ w‿x <¨↩ ⋄ {! (∾⟨•Repr𝕩,": Expe # 𝕨⥊𝕩 !"⥊: Result rank too large" % (0∾300⥊2)⥊0 +# 𝕨⍷𝕩 +"ab" ⍷ 0‿5⥊"ab" %% 0‿4⥊0 +'a'‿1 ⍷ 0‿5⥊⟨⟩ %% 0‿4⥊0 +"abc" ⍷ 5‿1⥊'a' %% 5‿0⥊0 +⟨(<"ab")⍷<"aa", (<"ab")⍷<"ab"⟩ %% ⟨<0,<1⟩ +{(=𝕨)≤=𝕩?𝕨⍷𝕩;'e'}⌜˜ ⟨'a','b',<'a','b',"a","b","aa","bb"⟩ %% (8‿8⥊⟨<1,<0,<1,<0,⟨1⟩,⟨0⟩,1‿1,0‿0,<0,<1,<0,<1,⟨0⟩,⟨1⟩,0‿0,1‿1,<1,<0,<1,<0,⟨1⟩,⟨0⟩,1‿1,0‿0,<0,<1,<0,<1,⟨0⟩,⟨1⟩,0‿0,1‿1,'e','e','e','e',⟨1⟩,⟨0⟩,1‿1,0‿0,'e','e','e','e',⟨0⟩,⟨1⟩,0‿0,1‿1,'e','e','e','e',⟨⟩,⟨⟩,⟨1⟩,⟨0⟩,'e','e','e','e',⟨⟩,⟨⟩,⟨0⟩,⟨1⟩⟩) +0∘⍷⎊1⌜˜ ⟨'a','b',<'a','b',"a","b","aa","bb",2‿2⥊'a'⟩ %% 9‿9⥊0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿0‿1‿1‿1‿1‿0‿0‿0‿0‿0‿1‿1‿1‿1‿0‿0‿0‿0‿0‿1‿1‿1‿1‿0‿0‿0‿0‿0‿1‿1‿1‿1‿0‿0‿0‿0‿0‿1‿1‿1‿1‿1‿1‿1‿1‿0 +(5‿999‿0‿9‿10‿11‿12⥊"a") ⍷ 10‿20‿30‿0‿40‿50‿60‿70‿80‿10‿10‿10‿10⥊0 %% 10‿20‿30‿0‿40‿50‿56‿0‿81‿2‿1‿0‿0⥊0 + # ⊐𝕩 ⊐ ∾⟜-0‿1.5 %% 0‿1‿0‿2