From 6afd425f243e98e410c66d35d2d04eea2426fa74 Mon Sep 17 00:00:00 2001 From: dzaima Date: Fri, 30 Apr 2021 00:21:22 +0300 Subject: [PATCH] =?UTF-8?q?reenable=20native=20=E2=8A=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/h.h | 2 +- src/main.c | 2 +- src/mut.c | 4 +++ src/sfns.c | 96 +++++++++++++++++++++++++++++++++--------------------- 4 files changed, 64 insertions(+), 40 deletions(-) diff --git a/src/h.h b/src/h.h index 3a19c4fe..2d9c3edd 100644 --- a/src/h.h +++ b/src/h.h @@ -369,7 +369,7 @@ typedef struct TypeInfo { BS2B getU; // like get, but doesn't increment result (mostly equivalent to `B t=get(…); dec(t); t`) BB2B m1_d; // consume all args; (m, f) BBB2B m2_d; // consume all args; (m, f, g) - BS2B slice; // consumes; create slice from given starting position; add ia, rank, shape yourself; may not actually be a Slice object + BS2B slice; // consumes, but keeps original object alive; create slice from given starting position; add ia, rank, shape yourself; may not actually be a Slice object B2B identity; // return identity element of this function; doesn't consume B2b canStore; // doesn't consume diff --git a/src/main.c b/src/main.c index 1871fb85..3fab8514 100644 --- a/src/main.c +++ b/src/main.c @@ -114,7 +114,7 @@ int main() { /* +-×÷⋆√⌊⌈|¬ */ 1,1,1,1,1,0,1,1,1,1, /* ∧∨<>≠=≤≥≡≢ */ 1,1,1,1,1,1,1,1,1,1, /* ⊣⊢⥊∾≍↑↓↕«» */ 1,1,0,0,0,0,0,0,0,0, - /* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ 0,0,1,0,0,0,0,0,0,0, + /* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ 0,0,1,0,0,1,0,0,0,0, /* ⍷⊔!˙˜˘¨⌜⁼´ */ 0,0,1,1,1,0,1,1,0,1, /* ˝`∘○⊸⟜⌾⊘◶⎉ */ 0,1,1,1,1,1,0,1,0,0, /* ⚇⍟⎊ */ 0,1,1 diff --git a/src/mut.c b/src/mut.c index 8ad6b684..ee67e650 100644 --- a/src/mut.c +++ b/src/mut.c @@ -52,6 +52,10 @@ u8 el_or(u8 a, u8 b) { #undef M } +void mut_pfree(Mut* m, usz n) { // free the first n elements + if (m->type==el_B) harr_pfree(tag(m->val,ARR_TAG), n); +} + // expects x to be an array, each position must be written to precisely once // doesn't consume x void mut_copy(Mut* m, usz ms, B x, usz xs, usz l) { diff --git a/src/sfns.c b/src/sfns.c index 81bf009e..d388e01b 100644 --- a/src/sfns.c +++ b/src/sfns.c @@ -206,7 +206,6 @@ B select_c1(B t, B x) { ur xr = rnk(x); if (xr==0) thrM("⊏: Argument cannot be rank 0"); if (a(x)->sh[0]==0) thrM("⊏: Argument shape cannot start with 0"); - inc(x); B r = TI(x).slice(x,0); usz* sh = arr_shAllocR(r, xr-1); usz ia = 1; @@ -215,18 +214,39 @@ B select_c1(B t, B x) { ia*= a(x)->sh[i]; } a(r)->ia = ia; - dec(x); return r; } B select_c2(B t, B w, B x) { - if (isArr(w) && isArr(x)) { - B xf = getFill(inc(x)); - BS2B wgetU = TI(w).getU; - BS2B xget = TI(x).get; - if (rnk(x)==1) { - usz wia = a(w)->ia; - usz xia = a(x)->ia; - HArr_p r = m_harrUc(w); + if (!isArr(x)) thrM("⊏: 𝕩 cannot be an atom"); + ur xr = rnk(x); + if (!isArr(w)) { + if (xr==0) thrM("⊏: 𝕩 cannot be a unit"); + usz csz = arr_csz(x); + usz cam = a(x)->sh[0]; + i64 wi = o2i64(w); + if (wi<0) wi+= cam; + if ((usz)wi >= cam) thrM("⊏: Indexing out-of-bounds"); + B r = TI(x).slice(x, wi*csz); + usz* sh = arr_shAllocI(r, csz, xr-1); + if (sh) memcpy(sh, a(x)->sh+1, (xr-1)*sizeof(usz)); + return r; + } + B xf = getFill(inc(x)); + BS2B xget = TI(x).get; + if (xr==1) { + usz wia = a(w)->ia; + usz xia = a(x)->ia; + HArr_p r = m_harrUc(w); + if(v(w)->type==t_i32arr | v(w)->type==t_i32slice) { + i32* wp = v(w)->type==t_i32arr? i32arr_ptr(w) : c(I32Slice,w)->a; + for (usz i = 0; i < wia; i++) { + i64 c = wp[i]; + if (c<0) c+= xia; + if (c<0 | c>=xia) thrM("⊏: Indexing out-of-bounds"); + r.a[i] = xget(x, c); + } + } else { + BS2B wgetU = TI(w).getU; for (usz i = 0; i < wia; i++) { B cw = wgetU(w, i); if (!isNum(cw)) { harr_pfree(r.b, i); goto base; } @@ -235,35 +255,35 @@ B select_c2(B t, B w, B x) { if ((usz)c >= xia) thrM("⊏: Indexing out-of-bounds"); r.a[i] = xget(x, c); } - dec(w); dec(x); - return withFill(r.b,xf); - } else { - ur wr = rnk(w); usz wia = a(w)->ia; - ur xr = rnk(x); - u32 rr = wr+xr-1; - if (xr==0) thrM("⊏: 𝕩 cannot be a unit"); - if (rr>UR_MAX) thrM("⊏: Result rank too large"); - usz csz = arr_csz(x); - usz cam = a(x)->sh[0]; - MAKE_MUT(r, wia*csz); - mut_to(r, fillElType(xf)); - for (usz i = 0; i < wia; i++) { - B cw = wgetU(w, i); - if (!isNum(cw)) { harr_pfree(mut_fp(r), i*csz); goto base; } - f64 c = o2f(cw); - if (c<0) c+= cam; - if ((usz)c >= cam) thrM("⊏: Indexing out-of-bounds"); - mut_copy(r, i*csz, x, csz*(usz)c, csz); - } - B rb = mut_fp(r); - usz* rsh = arr_shAllocR(rb, rr); - if (rsh) { - memcpy(rsh , a(w)->sh , wr *sizeof(usz)); - memcpy(rsh+wr, a(x)->sh+1, (xr-1)*sizeof(usz)); - } - dec(w); dec(x); - return withFill(rb,xf); } + dec(w); dec(x); + return withFill(r.b,xf); + } else { + BS2B wgetU = TI(w).getU; + ur wr = rnk(w); usz wia = a(w)->ia; + u32 rr = wr+xr-1; + if (xr==0) thrM("⊏: 𝕩 cannot be a unit"); + if (rr>UR_MAX) thrM("⊏: Result rank too large"); + usz csz = arr_csz(x); + usz cam = a(x)->sh[0]; + MAKE_MUT(r, wia*csz); + mut_to(r, fillElType(xf)); + for (usz i = 0; i < wia; i++) { + B cw = wgetU(w, i); + if (!isNum(cw)) { mut_pfree(r, i*csz); goto base; } + f64 c = o2f(cw); + if (c<0) c+= cam; + if ((usz)c >= cam) thrM("⊏: Indexing out-of-bounds"); + mut_copy(r, i*csz, x, csz*(usz)c, csz); + } + B rb = mut_fp(r); + usz* rsh = arr_shAllocR(rb, rr); + if (rsh) { + memcpy(rsh , a(w)->sh , wr *sizeof(usz)); + memcpy(rsh+wr, a(x)->sh+1, (xr-1)*sizeof(usz)); + } + dec(w); dec(x); + return withFill(rb,xf); } base: return c2(rt_select, w, x);