From 7a501ffbdfce50c63af16e672368d414498043dc Mon Sep 17 00:00:00 2001 From: dzaima Date: Fri, 28 Apr 2023 20:17:44 +0300 Subject: [PATCH] =?UTF-8?q?use=20APD=20for=20=E2=88=BElist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/sfns.c | 18 +++--------------- src/utils/mut.c | 39 +++++++++++++++++++++------------------ src/utils/mut.h | 6 +++--- 3 files changed, 27 insertions(+), 36 deletions(-) diff --git a/src/builtins/sfns.c b/src/builtins/sfns.c index e1fe554f..d4901ab9 100644 --- a/src/builtins/sfns.c +++ b/src/builtins/sfns.c @@ -762,21 +762,9 @@ B join_c1(B t, B x) { if (rm==0) thrM("∾: Some item rank must be equal or greater than rank of argument"); usz csz = shProd(esh, 0, rr-1); - MAKE_MUT(r, cam*csz); - usz ri = 0; - for (usz i = 0; i < xia; i++) { - B c = GetU(x, i); - if (isArr(c)) { - usz cia = IA(c); - mut_copy(r, ri, c, 0, cia); - ri+= cia; - } else { - mut_set(r, ri, inc(c)); - ri++; - } - } - assert(ri==cam*csz); - Arr* ra = mut_fp(r); + M_APD_TOT(r, cam*csz); + for (usz i = 0; i < xia; i++) APD(r, GetU(x, i)); + Arr* ra = APD_TOT_GET(r); usz* sh = arr_shAlloc(ra, rr); if (sh) { sh[0] = cam; diff --git a/src/utils/mut.c b/src/utils/mut.c index d127d330..6a9b0666 100644 --- a/src/utils/mut.c +++ b/src/utils/mut.c @@ -496,33 +496,36 @@ ApdFn* apd_tot_fns[]; ApdFn* apd_sh0_fns[]; ApdFn* apd_sh1_fns[]; ApdFn* apd_ #define APD_POS_1() m->obj->ia #define APD_POS(EB) APD_CAT(APD_POS_,EB)() -#define APD_MK0(E, EB, TY, TARR, CIA, CS) \ - NOINLINE void apd_##TY##_##E(ApdMut* m, B x) { \ - usz cia=CIA; CS; u8 xe=TI(x,elType); (void)xe; \ - if (RARE(!(TARR))) { \ - apd_widen(m, x, apd_##TY##_fns); return; \ - } \ - APD_OR_FILL(EB, x); \ - usz p0 = APD_POS(EB); APD_POS(EB) = p0+cia; \ - COPY_TO_2(m->a, E, p0, x, xe, cia); \ +#define APD_WIDEN(TY) do { apd_widen(m, x, apd_##TY##_fns); return; } while(0) +#define APD_INC_POS(EB) +#define APD_MK0(E, FEB, EB, TY, TARR, CIA, T0, CS) \ + NOINLINE void apd_##TY##_##E(ApdMut* m, B x) { T0 \ + usz cia=CIA; CS; u8 xe=TI(x,elType); (void)xe; \ + if (RARE(!(TARR))) APD_WIDEN(TY); \ + APD_OR_FILL(FEB, x); \ + usz p0 = APD_POS(EB); APD_POS(EB) = p0+cia; \ + COPY_TO_2(m->a, E, p0, x, xe, cia); \ } #define APD_SH1_CHK(N) if (RARE(isAtm(x) || RNK(x)!=1 || cia!=IA(x) )) { apd_sh_fail(m,x,N); return; } #define APD_SHH_CHK(N) if (RARE(isAtm(x) || RNK(x)!=m->cr || !eqShPart(m->csh, SH(x), m->cr))) { apd_sh_fail(m,x,N); return; } -#define APD_MK(E, EB, W, TATOM, TARR) \ - APD_MK0(E, EB, tot, TARR, IA(x), ) \ - APD_MK0(E, EB, sh1, TARR, m->cia, APD_SH1_CHK(1)) \ - APD_MK0(E, EB, sh2, TARR, m->cia, assert(m->cr>=2); APD_SHH_CHK(2)) \ +#define APD_WATOM(N, EB, TATOM, WATOM) \ + if (RARE(!TATOM)) APD_WIDEN(N); \ + usz p0 = APD_POS(EB); \ + APD_POS(EB) = p0+1; \ + void* a = m->a; WATOM; + +#define APD_MK(E, EB, WATOM, TATOM, TARR) \ + APD_MK0(E, EB, EB, sh1, TARR, m->cia, , APD_SH1_CHK(1)) \ + APD_MK0(E, EB, EB, sh2, TARR, m->cia, , assert(m->cr>=2); APD_SHH_CHK(2)) \ + APD_MK0(E, 0, EB, tot, TARR, IA(x), if (isAtm(x)) { APD_WATOM(tot, EB, TATOM, WATOM); return; }, if (cia==0) return; ) \ NOINLINE void apd_sh0_##E(ApdMut* m, B x) { \ APD_OR_FILL(EB, x); \ if (isArr(x)) { \ if (RARE(RNK(x)!=0)) { apd_sh_fail(m,x,0); return; } \ x = IGetU(x,0); \ } \ - if (RARE(!TATOM)) { apd_widen(m, x, apd_sh0_fns); return; } \ - usz p0 = APD_POS(EB); \ - APD_POS(EB) = p0+1; \ - void* a = m->a; W; \ + APD_WATOM(sh0, EB, TATOM, WATOM); \ } APD_MK(bit, 0, bitp_set((u64*)a,p0,o2bG(x)), q_bit(x), xe==el_bit) @@ -554,7 +557,7 @@ SHOULD_INLINE Arr* apd_setArr(ApdMut* m, usz ia, u8 xe) { return m->obj; } NOINLINE void apd_tot_init(ApdMut* m, B x) { - u8 xe = TI(x,elType); + u8 xe = isArr(x)? TI(x,elType) : selfElType(x); m->apd = apd_tot_fns[xe]; Arr* a = apd_setArr(m, m->ia0, xe); if (xe==el_B) { a->ia = 0; NOGC_E; } diff --git a/src/utils/mut.h b/src/utils/mut.h index 0ef7bbd8..2ee5d364 100644 --- a/src/utils/mut.h +++ b/src/utils/mut.h @@ -258,10 +258,10 @@ ApdFn apd_tot_init, apd_sh_init; #else #define M_APD_BASE(M) ApdMut M; #endif -#define M_APD_TOT(M, IA) M_APD_BASE(M) M.apd = apd_tot_init; M.ia0 = (IA); // assumes elements will be arrays; end gives uninitialized shape -#define M_APD_SH(M, RR, RSH) M_APD_BASE(M) M.apd = apd_sh_init; M.rsh0 = (RSH); M.rr0 = (RR); // appended things can be anything, will error on invalid; end gives full shape; rsh must be alive until at least the first APD call +#define M_APD_TOT(M, IA) M_APD_BASE(M) M.apd = apd_tot_init; M.ia0 = (IA); // end gives uninitialized shape +#define M_APD_SH(M, RR, RSH) M_APD_BASE(M) M.apd = apd_sh_init; M.rsh0 = (RSH); M.rr0 = (RR); // end gives full shape; will error on invalid at the end; rsh must be alive until at least the first APD call #define M_APD_SH1(M, RIA) usz M##_sh0 = (RIA); M_APD_SH(M, 1, &M##_sh0); #define APD(M, A) M.apd(&M, A) // doesn't consume A #define APDD(M, A) ({ B av_ = (A); M.apd(&M, av_); dec(av_); }) // consumes A #define APD_SH_GET(M, TY) (M.end(&M, TY)) -#define APD_TOT_GET(M) ({ NOGC_E; M.obj; }) +#define APD_TOT_GET(M) (M.obj)