native 𝔽⌾(n⊸↑) & 𝔽⌾(n⊸↓)
This commit is contained in:
parent
04c2ce7ade
commit
bf618b9b64
@ -72,7 +72,7 @@ BQNV bqn_makeBoundFn2(bqn_boundFn2 f, BQNV obj);
|
||||
|
||||
|
||||
// direct (zero copy) array item access
|
||||
typedef enum { elt_i8, elt_i16, elt_i32, elt_f64, elt_c8, elt_c16, elt_c32, elt_unk } BQNElType;
|
||||
typedef enum { elt_unk, elt_i8, elt_i16, elt_i32, elt_f64, elt_c8, elt_c16, elt_c32 } BQNElType; // note that more types may be added in the future
|
||||
BQNElType bqn_directType(BQNV a);
|
||||
// can only use the functions below if bqn_elType returns the corresponding type
|
||||
// a valid implementation of bqn_elType would be to always return elt_unk, thus disallowing the use of direct access entirely
|
||||
|
||||
@ -1268,6 +1268,55 @@ B slash_ucw(B t, B o, B w, B x) {
|
||||
return mut_fcd(r, x);
|
||||
}
|
||||
|
||||
static B takedrop_ucw(i64 wi, B o, u64 am, B x, size_t xr) {
|
||||
usz xia = a(x)->ia;
|
||||
usz csz = arr_csz(x);
|
||||
usz tk = csz*am; // taken element count
|
||||
usz lv = xia-tk; // elements left alone
|
||||
|
||||
Arr* arg = TI(x,slice)(inc(x), wi<0? lv : 0, tk);
|
||||
usz* ash = arr_shAlloc(arg, xr);
|
||||
if (ash) { ash[0] = am; shcpy(ash+1, a(x)->sh+1, xr-1); }
|
||||
|
||||
B rep = c1(o, taga(arg));
|
||||
if (isAtm(rep)) thrM("𝔽⌾(n⊸↑): 𝔽 returned an atom");
|
||||
usz* repsh = a(rep)->sh;
|
||||
if (rnk(rep)==0 || !eqShPrefix(repsh+1, a(x)->sh+1, xr-1) || repsh[0]!=am) thrM("𝔽⌾(n⊸↑)𝕩: 𝔽 returned an array with a different shape than n↑𝕩");
|
||||
|
||||
MAKE_MUT(r, xia);
|
||||
mut_init(r, el_or(TI(x,elType), TI(rep,elType))); MUTG_INIT(r);
|
||||
if (wi<0) {
|
||||
mut_copyG(r, 0, x, 0, lv);
|
||||
mut_copyG(r, lv, rep, 0, tk);
|
||||
} else {
|
||||
mut_copyG(r, 0, rep, 0, tk);
|
||||
mut_copyG(r, tk, x, tk, lv);
|
||||
}
|
||||
|
||||
dec(rep);
|
||||
return mut_fcd(r, x);
|
||||
}
|
||||
|
||||
B take_ucw(B t, B o, B w, B x) {
|
||||
if (!isF64(w)) return def_fn_ucw(t, o, w, x);
|
||||
i64 wi = o2i64(w);
|
||||
u64 am = wi<0? -wi : wi;
|
||||
if (isAtm(x)) x = m_vec1(x);
|
||||
ur xr = rnk(x); if (xr==0) xr = 1;
|
||||
if (am>a(x)->sh[0]) thrF("𝔽⌾(n⊸↑)𝕩: Cannot modify fill with Under (%l ≡ 𝕨, %H ≡ ≢𝕩)", wi, x);
|
||||
return takedrop_ucw(wi, o, am, x, xr);
|
||||
}
|
||||
|
||||
B drop_ucw(B t, B o, B w, B x) {
|
||||
if (!isF64(w)) return def_fn_ucw(t, o, w, x);
|
||||
i64 wi = o2i64(w);
|
||||
u64 am = wi<0? -wi : wi;
|
||||
if (isAtm(x)) x = m_vec1(x);
|
||||
ur xr = rnk(x); if (xr==0) xr = 1;
|
||||
usz cam = a(x)->sh[0];
|
||||
if (am>cam) am = cam;
|
||||
return takedrop_ucw(-wi, o, cam-am, x, xr);
|
||||
}
|
||||
|
||||
static B shape_uc1_t(B r, usz ia) {
|
||||
if (!isArr(r) || rnk(r)!=1 || a(r)->ia!=ia) thrM("𝔽⌾⥊: 𝔽 changed the shape of the argument");
|
||||
@ -1298,5 +1347,7 @@ void sfns_init() {
|
||||
c(BFn,bi_select)->ucw = select_ucw; // TODO move to new init fn
|
||||
c(BFn,bi_shape)->uc1 = shape_uc1;
|
||||
c(BFn,bi_transp)->uc1 = transp_uc1;
|
||||
c(BFn,bi_take)->ucw = take_ucw;
|
||||
c(BFn,bi_drop)->ucw = drop_ucw;
|
||||
c(BFn,bi_slash)->im = slash_im;
|
||||
}
|
||||
|
||||
@ -846,9 +846,9 @@ void g_pst(void) { vm_pstLive(); }
|
||||
Arr* a = (Arr*)x;
|
||||
if (prnk(x)<=1) assert(a->sh == &a->ia);
|
||||
else {
|
||||
u64 p = 1;
|
||||
for (usz i=0; i < prnk(x); i++) p*= a->sh[i];
|
||||
assert(p == a->ia);
|
||||
u64 shProduct = 1;
|
||||
for (usz i=0; i < prnk(x); i++) shProduct*= a->sh[i];
|
||||
assert(shProduct == a->ia);
|
||||
VALIDATE(tag(shObjP(x),OBJ_TAG));
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,6 +77,9 @@ static void arr_shCopy(Arr* n, B o) { // copy shape & rank from o to n
|
||||
n->sh = a(o)->sh;
|
||||
}
|
||||
}
|
||||
static void shcpy(usz* dst, usz* src, usz len) {
|
||||
memcpy(dst, src, len*sizeof(usz));
|
||||
}
|
||||
|
||||
static usz arr_csz(B x) {
|
||||
ur xr = rnk(x);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user