From 708e06c0ead6f5c98071a75003e5f1cb72eeaf6f Mon Sep 17 00:00:00 2001 From: dzaima Date: Mon, 19 Jul 2021 04:22:18 +0300 Subject: [PATCH] simplify mut usage where type is guaranteed correct --- src/builtins/sfns.c | 67 +++++++++++++++++++------------------- src/core/stuff.h | 1 + src/h.h | 1 - src/utils/mut.h | 78 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 110 insertions(+), 37 deletions(-) diff --git a/src/builtins/sfns.c b/src/builtins/sfns.c index de599c7e..549b2709 100644 --- a/src/builtins/sfns.c +++ b/src/builtins/sfns.c @@ -163,15 +163,14 @@ B select_c2(B t, B w, B x) { if (rr>UR_MAX) thrF("⊏: Result rank too large (%i≡=𝕨, %i≡=𝕩)", wr, xr); usz csz = arr_csz(x); usz cam = a(x)->sh[0]; - MAKE_MUT(r, wia*csz); - mut_to(r, fillElType(xf)); + MAKE_MUT(r, wia*csz); mut_to(r, TI(x,elType)); 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) { mut_pfree(r, i*csz); thrF("⊏: Indexing out-of-bounds (%R∊𝕨, %s≡≠𝕩)", cw, cam); } - mut_copy(r, i*csz, x, csz*(usz)c, csz); + mut_copyG(r, i*csz, x, csz*(usz)c, csz); } Arr* ra = mut_fp(r); usz* rsh = arr_shAllocR(ra, rr); @@ -349,12 +348,11 @@ B take_c2(B t, B w, B x) { usz ia = a(x)->ia; u64 va = v<0? -v : v; if (va>ia) { - MAKE_MUT(r, va); B xf = getFillE(x); - mut_copy(r, v<0? va-ia : 0, x, 0, ia); + MAKE_MUT(r, va); mut_to(r, TI(x,elType)); + mut_copyG(r, v<0? va-ia : 0, x, 0, ia); mut_fill(r, v<0? 0 : ia, xf, va-ia); - dec(x); - dec(xf); + dec(x); dec(xf); return mut_fv(r); } if (v<0) return slicev(x, ia+v, -v); @@ -466,10 +464,9 @@ B join_c2(B t, B w, B x) { if (rnk(r)==0) srnk(r,1); return qWithFill(r, f); } - MAKE_MUT(r, wia+xia); - mut_to(r, el_or(TI(w,elType), TI(x,elType))); - mut_copy(r, 0, w, 0, wia); - mut_copy(r, wia, x, 0, xia); + MAKE_MUT(r, wia+xia); mut_to(r, el_or(TI(w,elType), TI(x,elType))); + mut_copyG(r, 0, w, 0, wia); + mut_copyG(r, wia, x, 0, xia); Arr* ra = mut_fp(r); usz* sh = arr_shAllocR(ra, c); if (sh) { @@ -513,9 +510,9 @@ B couple_c2(B t, B w, B x) { if (!eqShape(w, x)) thrF("≍: 𝕨 and 𝕩 must have equal shapes (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x); usz ia = a(w)->ia; ur wr = rnk(w); - MAKE_MUT(r, ia*2); - mut_copy(r, 0, w, 0, ia); - mut_copy(r, ia, x, 0, ia); + MAKE_MUT(r, ia*2); mut_to(r, el_or(TI(w,elType), TI(x,elType))); + mut_copyG(r, 0, w, 0, ia); + mut_copyG(r, ia, x, 0, ia); Arr* ra = mut_fp(r); usz* sh = arr_shAllocR(ra, wr+1); if (sh) { sh[0]=2; memcpy(sh+1, a(w)->sh, wr*sizeof(usz)); } @@ -541,7 +538,7 @@ B shiftb_c1(B t, B x) { usz csz = arr_csz(x); MAKE_MUT(r, ia); mut_to(r, TI(x,elType)); - mut_copy(r, csz, x, 0, ia-csz); + mut_copyG(r, csz, x, 0, ia-csz); mut_fill(r, 0, xf, csz); return qWithFill(mut_fcd(r, x), xf); } @@ -554,8 +551,8 @@ B shiftb_c2(B t, B w, B x) { usz xia = a(x)->ia; MAKE_MUT(r, xia); mut_to(r, el_or(TI(w,elType), TI(x,elType))); int mid = wia= (u64)cam) { am%= (i64)cam; if(am<0) am+= cam; } am*= csz; MAKE_MUT(r, xia); mut_to(r, TI(x,elType)); - mut_copy(r, 0, x, am, xia-am); - mut_copy(r, xia-am, x, 0, am); + mut_copyG(r, 0, x, am, xia-am); + mut_copyG(r, xia-am, x, 0, am); return withFill(mut_fcd(r, x), xf); } @@ -761,8 +758,8 @@ B pick_uc1(B t, B o, B x) { B arg = TI(x,get)(x, 0); B rep = c1(o, arg); MAKE_MUT(r, ia); mut_to(r, el_or(TI(x,elType), selfElType(rep))); - mut_set(r, 0, rep); - mut_copy(r, 1, x, 1, ia-1); + mut_setG(r, 0, rep); + mut_copyG(r, 1, x, 1, ia-1); return qWithFill(mut_fcd(r, x), xf); } @@ -795,9 +792,9 @@ B pick_ucw(B t, B o, B w, B x) { } } MAKE_MUT(r, xia); mut_to(r, el_or(TI(x,elType), selfElType(rep))); - mut_set(r, wi, rep); - mut_copy(r, 0, x, 0, wi); - mut_copy(r, wi+1, x, wi+1, xia-wi-1); + mut_setG(r, wi, rep); + mut_copyG(r, 0, x, 0, wi); + mut_copyG(r, wi+1, x, wi+1, xia-wi-1); return qWithFill(mut_fcd(r, x), xf); } @@ -820,9 +817,9 @@ B slash_ucw(B t, B o, B w, B x) { if (cw) { B cr = rget(rep,repI); if (CHECK_VALID) for (i32 j = 1; j < cw; j++) if (!equal(rgetU(rep,repI+j), cr)) { mut_pfree(r,i); thrM("𝔽⌾(a⊸/): Incompatible result elements"); } - mut_set(r, i, cr); + mut_setG(r, i, cr); repI+= cw; - } else mut_set(r, i, xget(x,i)); + } else mut_setG(r, i, xget(x,i)); } dec(w); dec(rep); return mut_fcd(r, x); @@ -875,27 +872,27 @@ B select_ucw(B t, B o, B w, B x) { } } MAKE_MUT(r, xia); mut_to(r, el_or(TI(x,elType), TI(rep,elType))); - mut_copy(r, 0, x, 0, xia); + mut_copyG(r, 0, x, 0, xia); BS2B rget = TI(rep,get); for (usz i = 0; i < wia; i++) { i64 cw = wp[i]; if (cw<0) cw+= (i64)xia; B cr = rget(rep, i); EQ(!equal(mut_getU(r, cw), cr)); mut_rm(r, cw); - mut_setS(r, cw, cr); + mut_setG(r, cw, cr); } dec(w); dec(rep); FREE_CHECK; return mut_fcd(r, x); } MAKE_MUT(r, xia); mut_to(r, el_or(TI(x,elType), TI(rep,elType))); - mut_copy(r, 0, x, 0, xia); + mut_copyG(r, 0, x, 0, xia); BS2B rget = TI(rep,get); for (usz i = 0; i < wia; i++) { i64 cw = o2i64u(wgetU(w, i)); if (cw<0) cw+= (i64)xia; B cr = rget(rep, i); EQ(!equal(mut_getU(r, cw), cr)); mut_rm(r, cw); - mut_set(r, cw, cr); + mut_setG(r, cw, cr); } dec(w); dec(rep); FREE_CHECK; return mut_fcd(r, x); diff --git a/src/core/stuff.h b/src/core/stuff.h index 44309c14..b376493b 100644 --- a/src/core/stuff.h +++ b/src/core/stuff.h @@ -109,6 +109,7 @@ NOINLINE B append_fmt(B s, char* p, ...); // function stuff +char* format_type(u8 u); char* format_pf(u8 u); char* format_pm1(u8 u); char* format_pm2(u8 u); diff --git a/src/h.h b/src/h.h index cb4cfa5a..ad3b7ccd 100644 --- a/src/h.h +++ b/src/h.h @@ -183,7 +183,6 @@ enum ElType { // a⌈b shall return the type that can store both, if possible; a el_MAX=4 // also used for incomplete in mut.c }; -char* format_type(u8 u); typedef struct Value { diff --git a/src/utils/mut.h b/src/utils/mut.h index ad604c27..1b403406 100644 --- a/src/utils/mut.h +++ b/src/utils/mut.h @@ -112,7 +112,7 @@ static void mut_set(Mut* m, usz ms, B x) { // consumes x; sets m[ms] to x } #undef AGAIN } -static void mut_setS(Mut* m, usz ms, B x) { // consumes; sets m[ms] to x, assumes the current type can store it +static void mut_setG(Mut* m, usz ms, B x) { // consumes; sets m[ms] to x, assumes the current type can store it switch(m->type) { default: UD; case el_i32: { assert(q_i32(x)); m->ai32[ms] = o2iu(x); @@ -181,6 +181,37 @@ static void mut_fill(Mut* m, usz ms, B x, usz l) { } #undef AGAIN } +static void mut_fillG(Mut* m, usz ms, B x, usz l) { + switch(m->type) { default: UD; + case el_i32: { + assert(q_i32(x)); + i32* p = m->ai32+ms; + i32 v = o2iu(x); + for (usz i = 0; i < l; i++) p[i] = v; + return; + } + case el_c32: { + assert(isC32(x)); + u32* p = m->ac32+ms; + u32 v = o2cu(x); + for (usz i = 0; i < l; i++) p[i] = v; + return; + } + case el_f64: { + assert(isF64(x)); + f64* p = m->af64+ms; + f64 v = o2fu(x); + for (usz i = 0; i < l; i++) p[i] = v; + return; + } + case el_B: { + B* p = m->aB+ms; + for (usz i = 0; i < l; i++) p[i] = x; + if (isVal(x)) for (usz i = 0; i < l; i++) inc(x); + return; + } + } +} // expects x to be an array, each position must be written to precisely once // doesn't consume x @@ -239,6 +270,51 @@ static void mut_copy(Mut* m, usz ms, B x, usz xs, usz l) { } #undef AGAIN } +static void mut_copyG(Mut* m, usz ms, B x, usz xs, usz l) { // mut_copy but x is guaranteed to be a subtype of m + assert(isArr(x)); + u8 xt = v(x)->type; + switch(m->type) { default: UD; + case el_i32: { + i32* xp = i32any_ptr(x); + memcpy(m->ai32+ms, xp+xs, l*4); + return; + } + case el_c32: { + u32* xp = c32any_ptr(x); + memcpy(m->ac32+ms, xp+xs, l*4); + return; + } + case el_f64: { + f64* xp; + if (xt==t_f64arr) xp = f64arr_ptr(x); + else if (xt==t_f64slice) xp = c(F64Slice,x)->a; + else { + assert(TIi(xt,elType)==el_i32); + i32* xp = i32any_ptr(x); + f64* rp = m->af64+ms; + for (usz i = 0; i < l; i++) rp[i] = xp[i+xs]; + return; + } + memcpy(m->af64+ms, xp+xs, l*8); + return; + } + case el_B: { + B* mpo = m->aB+ms; + B* xp; + if (xt==t_harr) xp = harr_ptr(x); + else if (xt==t_hslice) xp = c(HSlice,x)->a; + else if (xt==t_fillarr) xp = c(FillArr,x)->a; + else { + BS2B xget = TIi(xt,get); + for (usz i = 0; i < l; i++) mpo[i] = xget(x,i+xs); + return; + } + memcpy(mpo, xp+xs, l*sizeof(B*)); + for (usz i = 0; i < l; i++) inc(mpo[i]); + return; + } + } +} static B vec_join(B w, B x) { // consumes both