From ff2af490b83f88e941a749dcffec0f12f2b15da3 Mon Sep 17 00:00:00 2001 From: dzaima Date: Thu, 27 May 2021 20:10:31 +0300 Subject: [PATCH] =?UTF-8?q?special-case=20appending=20atoms=20with=20?= =?UTF-8?q?=E2=88=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/sfns.c | 10 ++++++++-- src/core/fillarr.c | 4 +--- src/core/fillarr.h | 16 +++++++++------- src/utils/mut.h | 17 +++++++++++------ 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/builtins/sfns.c b/src/builtins/sfns.c index 36ab5231..66526067 100644 --- a/src/builtins/sfns.c +++ b/src/builtins/sfns.c @@ -392,9 +392,15 @@ B join_c1(B t, B x) { return c1(rt_join, x); } B join_c2(B t, B w, B x) { + if (isAtm(w)) w = m_atomUnit(w); + ur wr = rnk(w); + if (isAtm(x)) { + if (wr==1 && inplace_add(w, x)) return w; + x = m_atomUnit(x); + } + usz wia = a(w)->ia; usz* wsh = a(w)->sh; + usz xia = a(x)->ia; usz* xsh = a(x)->sh; ur xr = rnk(x); B f = fill_both(w, x); - if (isAtm(w)) w = m_atomUnit(w); ur wr = rnk(w); usz wia = a(w)->ia; usz* wsh = a(w)->sh; - if (isAtm(x)) x = m_atomUnit(x); ur xr = rnk(x); usz xia = a(x)->ia; usz* xsh = a(x)->sh; ur c = wr>xr?wr:xr; if (c==0) { HArr_p r = m_harrUv(2); diff --git a/src/core/fillarr.c b/src/core/fillarr.c index e504337c..744e3465 100644 --- a/src/core/fillarr.c +++ b/src/core/fillarr.c @@ -72,10 +72,8 @@ NOINLINE bool fillEqualR(B w, B x) { // doesn't consume; both args must be array u8 we = TI(w).elType; u8 xe = TI(x).elType; if (we!=el_B && xe!=el_B) { - if (we==xe) return true; if (we==el_c32 ^ xe==el_c32) return false; - assert(we==el_i32|we==el_f64); - assert(xe==el_i32|xe==el_f64); + assert(we==el_c32 & xe==el_c32 || we<=el_f64 & xe<=el_f64); return true; } BS2B xgetU = TI(x).getU; diff --git a/src/core/fillarr.h b/src/core/fillarr.h index a034e469..0dc8fb4f 100644 --- a/src/core/fillarr.h +++ b/src/core/fillarr.h @@ -28,13 +28,15 @@ static bool fillEqual(B w, B x) { static B getFillR(B x) { // doesn't consume; can return bi_noFill if (isArr(x)) { - u8 xe = TI(x).elType; - if (xe<=el_f64) return m_f64(0); - if (xe==el_c32) return m_c32(' '); - u8 t = v(x)->type; - if (t==t_fillarr ) return inc(c(FillArr,x )->fill); - if (t==t_fillslice) return inc(c(FillArr,c(Slice,x)->p)->fill); - return bi_noFill; + switch(TI(x).elType) { default: UD; + case el_f64: case el_i32: return m_i32(0); + case el_c32: return m_c32(' '); + case el_B: + u8 t = v(x)->type; + if (t==t_fillarr ) return inc(c(FillArr,x )->fill); + if (t==t_fillslice) return inc(c(FillArr,c(Slice,x)->p)->fill); + return bi_noFill; + } } if (isF64(x)|isI32(x)) return m_i32(0); if (isC32(x)) return m_c32(' '); diff --git a/src/utils/mut.h b/src/utils/mut.h index bd4998c6..323b739d 100644 --- a/src/utils/mut.h +++ b/src/utils/mut.h @@ -298,7 +298,7 @@ static B vec_join(B w, B x) { // consumes both dec(w); dec(x); return mut_fv(r); } -static B vec_add(B w, B x) { // consumes both +static inline bool inplace_add(B w, B x) { // fails if fills wouldn't be correct usz wia = a(w)->ia; usz ria = wia+1; if (v(w)->refc==1) { @@ -307,25 +307,30 @@ static B vec_add(B w, B x) { // consumes both if (wt==t_i32arr && fsizeof(I32Arr,a,i32,ria)ia = ria; i32arr_ptr(w)[wia] = o2iu(x); - return w; + return true; } if (wt==t_c32arr && fsizeof(C32Arr,a,u32,ria)ia = ria; c32arr_ptr(w)[wia] = o2cu(x); - return w; + return true; } if (wt==t_f64arr && fsizeof(F64Arr,a,f64,ria)ia = ria; f64arr_ptr(w)[wia] = o2fu(x); - return w; + return true; } if (wt==t_harr && fsizeof(HArr,a,B,ria)ia = ria; harr_ptr(w)[wia] = x; - return w; + return true; } } - MAKE_MUT(r, ria); mut_to(r, el_or(TI(w).elType, selfElType(x))); + return false; +} +static B vec_add(B w, B x) { // consumes both; fills may be wrong + if (inplace_add(w, x)) return w; + usz wia = a(w)->ia; + MAKE_MUT(r, wia+1); mut_to(r, el_or(TI(w).elType, selfElType(x))); mut_copy(r, 0, w, 0, wia); mut_set(r, wia, x); dec(w);