summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordzaima <dzaimagit@gmail.com>2024-04-03 05:00:57 +0300
committerdzaima <dzaimagit@gmail.com>2024-04-03 05:59:35 +0300
commitb8730798c13b2faa9eba5118f19709a1a9f55f35 (patch)
tree158d4f379f524c1e2c74b2612a3b2524a88f7fac
parent5ab49ab146fd653accbe61d8018182e21f3b3652 (diff)
explicitly handle empty cells in compress
-rw-r--r--src/builtins/slash.c14
-rw-r--r--test/cases/prims.bqn4
2 files changed, 15 insertions, 3 deletions
diff --git a/src/builtins/slash.c b/src/builtins/slash.c
index 3d268fed..f719e1c6 100644
--- a/src/builtins/slash.c
+++ b/src/builtins/slash.c
@@ -175,7 +175,7 @@ static void where_block_u16(u64* src, u16* dst, usz len, usz sum) {
}
}
-static B compress_grouped(u64* wp, B x, usz wia, usz wsum, u8 xt) { // expected to return a refcount-1 array (at least when rank≥1)
+static B compress_grouped(u64* wp, B x, usz wia, usz wsum, u8 xt) { // expected to return a refcount-1 array (at least when rank≥1), expects argument with non-empty cells
B r;
usz csz = arr_csz(x);
u8 xl = arrTypeBitsLog(TY(x));
@@ -323,23 +323,27 @@ static NOINLINE bool groups_lt(u64* wp, usz len, usz max) {
return 1;
}
-static NOINLINE B zeroCells(B x) { // doesn't consume
+static NOINLINE B reshapeToEmpty(B x, usz leading) { // doesn't consume; changes leading axis to the given one, assumes result is empty
u8 xe = TI(x,elType);
B r; ur xr = RNK(x);
if (xr==1) {
if (xe==el_B) { B xf = getFillR(x); r = noFill(xf)? emptyHVec() : taga(arr_shVec(m_fillarrpEmpty(xf))); }
else r = elNum(xe)? emptyIVec() : emptyCVec();
} else {
+ assert(xr > 1);
Arr* ra;
if (xe==el_B) { B xf = getFillR(x); ra = noFill(xf)? (Arr*)m_harrUp(0).c : m_fillarrpEmpty(xf); }
else m_tyarrp(&ra, 1, 0, elNum(xe)? t_bitarr : t_c8arr);
usz* rsh = arr_shAlloc(ra, xr);
shcpy(rsh+1, SH(x)+1, xr-1);
- rsh[0] = 0;
+ rsh[0] = leading;
r = taga(ra);
}
return r;
}
+static B zeroCells(B x) { // doesn't consume
+ return reshapeToEmpty(x, 0);
+}
B grade_bool(B x, usz xia, bool up) {
#define BRANCHLESS_GRADE(T) \
@@ -429,9 +433,13 @@ static B compress(B w, B x, usz wia, u8 xl, u8 xt) {
wia = 64*(ie+1) - CLZ(we);
usz wsum = bit_sum(wp, wia);
if (wsum == wia0) return incG(x);
+ assert(wsum > 0);
B r;
switch(xl) {
+ case 7:
+ if (IA(x)==0) return reshapeToEmpty(x, wsum); // handle empty cell case
+ // fallthrough
default: r = compress_grouped(wp, x, wia, wsum, xt); break;
case 0: {
u64* xp = bitarr_ptr(x);
diff --git a/test/cases/prims.bqn b/test/cases/prims.bqn
index abfde1b7..9027ba73 100644
--- a/test/cases/prims.bqn
+++ b/test/cases/prims.bqn
@@ -88,6 +88,10 @@
1‿0‿2 / ⋈¨ ["ab","cd","ef"] %% ⋈¨ ["ab","ef","ef"]
(<1‿0‿2) / ⋈¨ ["ab","cd","ef"] %% ⋈¨ ["ab","ef","ef"]
(⋈1‿0‿2) / ⋈¨ ["ab","cd","ef"] %% ⋈¨ ["ab","ef","ef"]
+1‿0‿0/3‿0‿2⥊0 %% 1‿0‿2⥊0
+1‿0‿0/3‿0‿2⥊'a' %% 1‿0‿2⥊' '
+1‿0‿0/3‿0‿2⥊<"a" %% 1‿0‿2⥊<" "
+(10000⥊1‿0)/10000‿0‿2⥊0 %% 5000‿0‿2⥊0
# /𝕩
!"Expected non-negative integer, got ¯1000" % / 4/1000‿¯1000