From 723ca38816ab4861671893895a134c8bb22b896b Mon Sep 17 00:00:00 2001 From: dzaima Date: Tue, 20 May 2025 23:14:58 +0300 Subject: [PATCH] =?UTF-8?q?make=20native=20=E2=8C=BE(is=E2=8A=B8=E2=8A=8F)?= =?UTF-8?q?=20&=20=E2=8C=BE(m=E2=8A=B8/)=20compare=20NaNs=20as=20equal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/select.c | 22 ++++++++++++---------- src/builtins/slash.c | 2 +- src/core/stuff.h | 6 ++++++ test/cases/under.bqn | 10 +++++----- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/builtins/select.c b/src/builtins/select.c index 059e48a9..cb7c4858 100644 --- a/src/builtins/select.c +++ b/src/builtins/select.c @@ -480,14 +480,14 @@ B select_replace(u32 chr, B w, B x, B rep, usz wia, usz cam, usz csz) { // consu for (usz i = 0; i < wia; i++) { READ_W(cw, i); B cn = Get(rep, i); - EQ1(!equal(mut_getU(r, cw), cn)); + EQ1(!compatible(mut_getU(r, cw), cn)); mut_rm(r, cw); mut_setG(r, cw, cn); } } else { for (usz i = 0; i < wia; i++) { READ_W(cw, i); - EQ(for (usz j = 0; j < csz; j++), !equal(mut_getU(r, cw*csz + j), Get(rep, i*csz + j))); + EQ(for (usz j = 0; j < csz; j++), !compatible(mut_getU(r, cw*csz + j), Get(rep, i*csz + j))); for (usz j = 0; j < csz; j++) mut_rm(r, cw*csz + j); mut_copyG(r, cw*csz, rep, i*csz, csz); } @@ -538,14 +538,14 @@ B select_replace(u32 chr, B w, B x, B rep, usz wia, usz cam, usz csz) { // consu for (usz i = 0; i < wia; i++) { READ_W(cw, i); B cn = Get(rep, i); - EQ1(!equal(cn,rp[cw])); + EQ1(!compatible(cn,rp[cw])); dec(rp[cw]); rp[cw] = cn; } } else { for (usz i = 0; i < wia; i++) { READ_W(cw, i); - EQ(for (usz j = 0; j < csz; j++), !equal(Get(rep, i*csz + j), rp[cw*csz + j])); + EQ(for (usz j = 0; j < csz; j++), !compatible(Get(rep, i*csz + j), rp[cw*csz + j])); for (usz j = 0; j < csz; j++) dec(rp[cw*csz + j]); COPY_TO(rp, el_B, cw*csz, rep, i*csz, csz); } @@ -554,23 +554,25 @@ B select_replace(u32 chr, B w, B x, B rep, usz wia, usz cam, usz csz) { // consu } } - #define IMPL(T) do { \ + #define IMPL(T, COMPATIBLE) do { \ if (csz!=1) goto do_tycell; \ T* rp = tyarrv_ptr((TyArr*)ra); \ T* np = tyany_ptr(rep); \ for (usz i = 0; i < wia; i++) { \ READ_W(cw, i); \ T cn = np[i]; \ - EQ1(cn != rp[cw]); \ + EQ1(!COMPATIBLE(cn, rp[cw])); \ rp[cw] = cn; \ } \ goto dec_ret_ra; \ } while(0) - do_u8: IMPL(u8); - do_u16: IMPL(u16); - do_u32: IMPL(u32); - do_f64: IMPL(f64); + #define INT_EQ(A,B) ((A)==(B)) + do_u8: IMPL(u8, INT_EQ); + do_u16: IMPL(u16, INT_EQ); + do_u32: IMPL(u32, INT_EQ); + do_f64: IMPL(f64, compatibleFloats); + #undef INT_EQ #undef IMPL do_tycell:; diff --git a/src/builtins/slash.c b/src/builtins/slash.c index 5f9b6ef3..512d2312 100644 --- a/src/builtins/slash.c +++ b/src/builtins/slash.c @@ -1175,7 +1175,7 @@ B slash_ucw(B t, B o, B w, B x) { i32 cw = o2iG(GetU(w, i)); if (cw) { B cr = Get(rep,repI); - if (CHECK_VALID) for (i32 j = 1; j < cw; j++) if (!equal(GetU(rep,repI+j), cr)) { mut_pfree(r,i); thrM("𝔽⌾(a⊸/): Incompatible result elements"); } + if (CHECK_VALID) for (i32 j = 1; j < cw; j++) if (!compatible(GetU(rep,repI+j), cr)) { mut_pfree(r,i); thrM("𝔽⌾(a⊸/): Incompatible result elements"); } mut_setG(r, i, cr); repI+= cw; } else mut_setG(r, i, Get(x,i)); diff --git a/src/core/stuff.h b/src/core/stuff.h index 4dccfffe..a30a40b1 100644 --- a/src/core/stuff.h +++ b/src/core/stuff.h @@ -338,6 +338,12 @@ static bool atomEqual(B w, B x) { // doesn't consume if (!isVal(w) | !isVal(x)) return false; return atomEqualF(w, x); } +static bool compatible(B w, B x) { + return eequal(w, x); +} +static bool compatibleFloats(f64 a, f64 b) { + return a==b || (a!=a && b!=b); +} NOINLINE usz depthF(B x); static usz depth(B x) { // doesn't consume diff --git a/test/cases/under.bqn b/test/cases/under.bqn index a7bb8b13..e4387483 100644 --- a/test/cases/under.bqn +++ b/test/cases/under.bqn @@ -111,7 +111,7 @@ n←500 ⋄ a←↕n ⋄ i←(-n)+↕2×n ⋄ r←⌽(2×n)⥊a ⋄ ! (⌽a) ≡ %USE eqvar ⋄ 1⊸+⌾((2/↕5)⊸⊏) _eqvar ≍˘ ↕10 %% ≍˘ <⟜5⊸+ ↕10 %USE eqvar ⋄ •internal.Keep⌾((2/↕5)⊸⊏) _eqvar 10‿0‿4⥊0 %% 10‿0‿4⥊0 %USE eqvar ⋄ (<⟨⟩) {•internal.Keep⌾(𝕨⊸⊏) 𝕩}_eqvar¨ ⟨0‿1, "ab"‿"cd"⟩ %% ⟨0‿1, "ab"‿"cd"⟩ -!"𝔽⌾(a⊸⊏): Incompatible result elements" % %USE evar ⋄ ⟨0÷0,0÷0⟩ {𝕨⌾(0‿0⊸⊏) 𝕩}_evar 3⥊0 +%USE eqvar ⋄ ⟨0÷0,0÷0⟩ {𝕨⌾(0‿0⊸⊏) 𝕩}_eqvar 3⥊0 %% ⟨0÷0,0,0⟩ %USE eqvar ⋄ %USE nz ⋄ 0‿0 {(0 InsNZ 2⥊0)⌾(𝕨⊸⊏)𝕩}_eqvar 3⥊3 %% 0‿3‿3 @@ -248,12 +248,12 @@ n←500 ⋄ a←↕n ⋄ i←(-n)+↕2×n ⋄ r←⌽(2×n)⥊a ⋄ ! (⌽a) ≡ ! •Show "I should not be called!" } Batch¨ ⟨ - ⟨0‿0, 1‿1, 0÷0⟩ - ⟨0‿0, 1‿1, <0÷0⟩ - ⟨0‿0, 1‿1, ⟨3,0÷0,4⟩⟩ + ⟨1‿1, 1‿1, 0÷0⟩ + ⟨1‿1, 1‿1, <0÷0⟩ + ⟨1‿1, 1‿1, ⟨3,0÷0,4⟩⟩ ⟨1‿1, 1‿1, {𝕊: ShouldNotBeCalled}⟩ ⟨1‿1, 1‿1, ShouldNotBeCalled˙⟩ - ⟨0‿1, 0‿1, {𝕊: ShouldNotBeCalled⟜(0÷0)}⟩ + ⟨1‿1, 0‿1, {𝕊: ShouldNotBeCalled⟜(0÷0)}⟩ ⟨1‿1, 1‿1, ShouldNotBeCalled⟜(0÷0)˙⟩ ⟨1‿1, 1‿1, ∞⟩ ⟩