Move Insert implementation to fold.c, except the generic case

This commit is contained in:
Marshall Lochbaum 2023-04-01 17:37:07 -04:00 committed by dzaima
parent e276779eca
commit b6590b0eab
2 changed files with 66 additions and 72 deletions

View File

@ -1,6 +1,6 @@
// Fold (´) // Fold (´) and Insert (˝)
// Optimized operands: // Fold optimized operands:
// ⊣⊢ on all types // ⊣⊢ on all types
// +-∧∨=≠ and synonyms on booleans // +-∧∨=≠ and synonyms on booleans
// ≤<>≥ on booleans, monadic only, with a search // ≤<>≥ on booleans, monadic only, with a search
@ -13,6 +13,7 @@
#include "../core.h" #include "../core.h"
#include "../builtins.h" #include "../builtins.h"
#include "../utils/calls.h"
#include "../utils/mut.h" #include "../utils/mut.h"
#if SINGELI_SIMD #if SINGELI_SIMD
@ -321,8 +322,63 @@ u64 usum(B x) { // doesn't consume; will error on non-integers, or elements <0,
neg: thrM("Didn't expect negative integer"); neg: thrM("Didn't expect negative integer");
} }
static B m1c1(B t, B f, B x) { // consumes x
B fn = m1_d(inc(t), inc(f));
B r = c1(fn, x);
decG(fn);
return r;
}
extern B rt_insert;
// From md1.c
extern bool isPervasiveDyExt(B x);
extern B insert_base(B f, B x, usz xia, bool has_w, B w);
B insert_c1(Md1D* d, B x) { B f = d->f;
if (isAtm(x) || RNK(x)==0) thrM("˝: 𝕩 must have rank at least 1");
usz xia = IA(x);
if (xia==0) { SLOW2("!𝕎˝𝕩", f, x); return m1c1(rt_insert, f, x); }
if (isFun(f)) {
u8 rtid = v(f)->flags-1;
if (RNK(x)==1 && isPervasiveDyExt(f)) return m_atomUnit(fold_c1(d, x));
if (rtid == n_join) {
ur xr = RNK(x);
if (xr==1) return x;
ShArr* rsh;
if (xr>2) {
rsh = m_shArr(xr-1);
usz* xsh = SH(x);
shcpy(rsh->a+1, xsh+2, xr-2);
rsh->a[0] = xsh[0] * xsh[1];
}
Arr* r = TI(x,slice)(x, 0, IA(x));
if (xr>2) arr_shSetU(r, xr-1, rsh);
else arr_shVec(r);
return taga(r);
}
}
return insert_base(f, x, xia, 0, bi_N);
}
B insert_c2(Md1D* d, B w, B x) { B f = d->f;
if (isAtm(x) || RNK(x)==0) thrM("˝: 𝕩 must have rank at least 1");
usz xia = IA(x);
B r = w;
if (xia==0) { decG(x); return r; }
if (isFun(f)) {
if (RNK(x)==1 && isPervasiveDyExt(f)) {
if (isAtm(w)) {
to_fold: return m_atomUnit(fold_c2(d, w, x));
}
if (RNK(w)==0) {
B w0=w; w = IGet(w,0); decG(w0);
goto to_fold;
}
}
}
return insert_base(f, x, xia, 1, w);
}
// Arithmetic fold/insert on rows of flat rank-2 array x // Arithmetic fold/insert on rows of flat rank-2 array x
B insert_c1(Md1D*, B);
B transp_c1(B, B); B transp_c1(B, B);
B join_c2(B, B, B); B join_c2(B, B, B);
B fold_rows(Md1D* fd, B x) { B fold_rows(Md1D* fd, B x) {

View File

@ -161,19 +161,6 @@ B timed_c1(Md1D* d, B x) { B f = d->f;
} }
static B m1c1(B t, B f, B x) { // consumes x
B fn = m1_d(inc(t), inc(f));
B r = c1(fn, x);
decG(fn);
return r;
}
static B m1c2(B t, B f, B w, B x) { // consumes w,x
B fn = m1_d(inc(t), inc(f));
B r = c2(fn, w, x);
decG(fn);
return r;
}
#pragma GCC diagnostic push #pragma GCC diagnostic push
#ifdef __clang__ #ifdef __clang__
#pragma GCC diagnostic ignored "-Wsometimes-uninitialized" #pragma GCC diagnostic ignored "-Wsometimes-uninitialized"
@ -467,64 +454,15 @@ B cell_c2(Md1D* d, B w, B x) { B f = d->f;
return bqn_merge(r); return bqn_merge(r);
} }
B fold_c1(Md1D* d, B x); // Used by Insert in fold.c
B fold_c2(Md1D* d, B w, B x); B insert_base(B f, B x, usz xia, bool has_w, B w) {
extern B rt_insert;
B insert_c1(Md1D* d, B x) { B f = d->f;
if (isAtm(x) || RNK(x)==0) thrM("˝: 𝕩 must have rank at least 1");
usz xia = IA(x);
if (xia==0) { SLOW2("!𝕎˝𝕩", f, x); return m1c1(rt_insert, f, x); }
if (isFun(f)) {
u8 rtid = v(f)->flags-1;
if (RNK(x)==1 && isPervasiveDyExt(f)) return m_atomUnit(fold_c1(d, x));
if (rtid == n_join) {
ur xr = RNK(x);
if (xr==1) return x;
ShArr* rsh;
if (xr>2) {
rsh = m_shArr(xr-1);
usz* xsh = SH(x);
shcpy(rsh->a+1, xsh+2, xr-2);
rsh->a[0] = xsh[0] * xsh[1];
}
Arr* r = TI(x,slice)(x, 0, IA(x));
if (xr>2) arr_shSetU(r, xr-1, rsh);
else arr_shVec(r);
return taga(r);
}
}
S_SLICES(x)
usz p = xia-x_csz;
B r = SLICE(x, p);
while(p!=0) {
p-= x_csz;
r = c2(f, SLICE(x, p), r);
}
E_SLICES(x)
return r;
}
B insert_c2(Md1D* d, B w, B x) { B f = d->f;
if (isAtm(x) || RNK(x)==0) thrM("˝: 𝕩 must have rank at least 1");
usz xia = IA(x);
B r = w;
if (xia==0) { decG(x); return r; }
if (isFun(f)) {
if (RNK(x)==1 && isPervasiveDyExt(f)) {
if (isAtm(w)) {
to_fold: return m_atomUnit(fold_c2(d, w, x));
}
if (RNK(w)==0) {
B w0=w; w = IGet(w,0); decG(w0);
goto to_fold;
}
}
}
S_SLICES(x) S_SLICES(x)
usz p = xia; usz p = xia;
B r = w;
if (!has_w) {
p -= x_csz;
r = SLICE(x, p);
}
while(p!=0) { while(p!=0) {
p-= x_csz; p-= x_csz;
r = c2(f, SLICE(x, p), r); r = c2(f, SLICE(x, p), r);