From e3fe87d0400b67eecfc5f880cecb79d7076aba1e Mon Sep 17 00:00:00 2001 From: dzaima Date: Mon, 4 Apr 2022 16:16:29 +0300 Subject: [PATCH] =?UTF-8?q?optimize=20eequal=20&=20expose=20as=20=E2=80=A2?= =?UTF-8?q?internal.EEqual?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/system.md | 4 +++- src/builtins.h | 2 +- src/builtins/internal.c | 11 +++++++++-- src/core/stuff.c | 17 +++++++++++++++++ 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/docs/system.md b/docs/system.md index 598fc583..78ceaf4b 100644 --- a/docs/system.md +++ b/docs/system.md @@ -99,4 +99,6 @@ Namespace of various internal functions. May change at any time. | `•internal.ListVariations` | List the possible type variations of the argument array | | `•internal.Variation` | Convert `𝕩` to the variation specified in `𝕨` | | `•internal.ClearRefs` | Clear references `•internal.Variation` made for `*Inc` variations | -| `•internal.Unshare` | Get a unique, reference count 1 version of the argument; recursively unshares array items, doesn't touch namespaces | \ No newline at end of file +| `•internal.Unshare` | Get a unique, reference count 1 version of the argument; recursively unshares array items, doesn't touch namespaces | +| `•internal.EEqual` | exactly equal (NaN equals NaN); 0 and ¯0 aren't equal, but can be made so with the C compile-time flag `-DEEQUAL_NEGZERO` | +| `•internal.Temp` | place to test new features or temporarily expose some internal function | \ No newline at end of file diff --git a/src/builtins.h b/src/builtins.h index 134efd8f..1e18ca0e 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -15,7 +15,7 @@ /* sysfn.c*/M(tRawMode,"•term.RawMode") M(tFlush,"•term.Flush") M(tCharB,"•term.CharB") M(tCharN,"•term.CharN") M(tOutRaw,"•term.OutRaw") M(tErrRaw,"•term.ErrRaw") \ /* inverse.c*/M(setInvReg, "(SetInvReg)") M(setInvSwap, "(SetInvSwap)") M(nativeInvReg, "(NativeInvReg)") M(nativeInvSwap, "(NativeInvSwap)") \ /*internal.c*/M(itype,"•internal.Type") M(elType,"•internal.ElType") M(refc,"•internal.Refc") M(isPure,"•internal.IsPure") A(info,"•internal.Info") M(heapDump,"•internal.HeapDump") \ -/*internal.c*/M(squeeze,"•internal.Squeeze") M(deepSqueeze,"•internal.DeepSqueeze") A(internalTemp,"•internal.Temp") \ +/*internal.c*/M(squeeze,"•internal.Squeeze") M(deepSqueeze,"•internal.DeepSqueeze") D(eequal,"•internal.EEqual") A(internalTemp,"•internal.Temp") \ /*internal.c*/D(variation,"•internal.Variation") A(listVariations,"•internal.ListVariations") M(clearRefs,"•internal.ClearRefs") M(unshare,"•internal.Unshare") \ /* arithm.c*/M(sin,"•math.Sin") M(cos,"•math.Cos") M(tan,"•math.Tan") M(asin,"•math.Asin") M(acos,"•math.Acos") M(atan,"•math.Atan") diff --git a/src/builtins/internal.c b/src/builtins/internal.c index 07e49345..6a53a836 100644 --- a/src/builtins/internal.c +++ b/src/builtins/internal.c @@ -259,6 +259,13 @@ static B unshare(B x) { } } + + +B eequal_c2(B t, B w, B x) { + bool r = eequal(w, x); + dec(w); dec(x); + return m_i32(r); +} B internalTemp_c1(B t, B x) { @@ -290,8 +297,8 @@ B getInternalNS() { listVariations_def = m_str8l("if"); gc_addFn(variation_gcRoot); #define F(X) inc(bi_##X), - Body* d = m_nnsDesc("type","eltype","refc","squeeze","ispure","info","listvariations","variation","clearrefs","unshare","deepsqueeze","heapdump","temp"); - internalNS = m_nns(d,F(itype)F(elType)F(refc)F(squeeze)F(isPure)F(info)F(listVariations)F(variation)F(clearRefs)F(unshare)F(deepSqueeze)F(heapDump)F(internalTemp)); + Body* d = m_nnsDesc("type","eltype","refc","squeeze","ispure","info","listvariations","variation","clearrefs","unshare","deepsqueeze","heapdump","eequal","temp"); + internalNS = m_nns(d,F(itype)F(elType)F(refc)F(squeeze)F(isPure)F(info)F(listVariations)F(variation)F(clearRefs)F(unshare)F(deepSqueeze)F(heapDump)F(eequal)F(internalTemp)); #undef F gc_add(internalNS); } diff --git a/src/core/stuff.c b/src/core/stuff.c index 36fbe298..9075266b 100644 --- a/src/core/stuff.c +++ b/src/core/stuff.c @@ -524,6 +524,23 @@ bool eequal(B w, B x) { // doesn't consume // dec(wf); dec(xf); // if (!feq) return false; if (!eqShape(w,x)) return false; + u8 we = TI(w,elType); + u8 xe = TI(x,elType); + if (we==el_f64 && xe==el_f64) { + usz ia = a(x)->ia; + f64* wp = f64any_ptr(w); + f64* xp = f64any_ptr(x); + u64 r = 1; + for (usz i = 0; i < ia; i++) { + #if EEQUAL_NEGZERO + r&= (wp[i]==xp[i]) | (wp[i]!=wp[i] & xp[i]!=xp[i]); + #else + r&= ((u64*)wp)[i] == ((u64*)xp)[i]; + #endif + } + return r; + } + if (we!=el_B && xe!=el_B) return equal(w, x); usz ia = a(x)->ia; SGetU(x) SGetU(w)