From bf618b9b64d0e034230dd71d9cc247196f3325d6 Mon Sep 17 00:00:00 2001 From: dzaima Date: Sun, 29 May 2022 13:23:01 +0300 Subject: [PATCH] =?UTF-8?q?native=20=F0=9D=94=BD=E2=8C=BE(n=E2=8A=B8?= =?UTF-8?q?=E2=86=91)=20&=20=F0=9D=94=BD=E2=8C=BE(n=E2=8A=B8=E2=86=93)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/bqnffi.h | 2 +- src/builtins/sfns.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ src/core/stuff.c | 6 +++--- src/core/stuff.h | 3 +++ 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/include/bqnffi.h b/include/bqnffi.h index f8b6736c..9759ee96 100644 --- a/include/bqnffi.h +++ b/include/bqnffi.h @@ -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 diff --git a/src/builtins/sfns.c b/src/builtins/sfns.c index 37e7d929..141ae053 100644 --- a/src/builtins/sfns.c +++ b/src/builtins/sfns.c @@ -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; } diff --git a/src/core/stuff.c b/src/core/stuff.c index f37ac709..d38d3182 100644 --- a/src/core/stuff.c +++ b/src/core/stuff.c @@ -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)); } } diff --git a/src/core/stuff.h b/src/core/stuff.h index 222a29d6..104a00ac 100644 --- a/src/core/stuff.h +++ b/src/core/stuff.h @@ -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);