Move Group to its own file

This commit is contained in:
Marshall Lochbaum 2022-09-16 10:59:03 -04:00
parent 0b1ded14e0
commit 21033fa355
5 changed files with 277 additions and 267 deletions

View File

@ -198,7 +198,7 @@ ${bd}/%.o: src/jit/%.c
@echo $< | cut -c 5-
@$(CC_INC) $@.d -o $@ -c $<
builtins: ${addprefix ${bd}/, arithm.o arithd.o cmp.o sfns.o squeeze.o select.o slash.o sort.o selfsearch.o md1.o md2.o fns.o sysfn.o internal.o inverse.o}
builtins: ${addprefix ${bd}/, arithm.o arithd.o cmp.o sfns.o squeeze.o select.o slash.o group.o sort.o selfsearch.o md1.o md2.o fns.o sysfn.o internal.o inverse.o}
${bd}/%.o: src/builtins/%.c
@echo $< | cut -c 5-
@$(CC_INC) $@.d -o $@ -c $<

225
src/builtins/group.c Normal file
View File

@ -0,0 +1,225 @@
#include "../core.h"
#include "../utils/talloc.h"
#include "../utils/mut.h"
#include "../builtins.h"
extern B ne_c2(B, B, B);
extern B slash_c1(B, B);
extern B slash_c2(B, B, B);
extern B select_c2(B, B, B);
extern B take_c2(B, B, B);
extern B drop_c2(B, B, B);
extern B join_c2(B, B, B);
extern B rt_group;
B group_c2(B t, B w, B x) {
if (isArr(w)&isArr(x) && RNK(w)==1 && RNK(x)==1 && depth(w)==1) {
usz wia = IA(w);
usz xia = IA(x);
if (wia-xia > 1) thrF("⊔: ≠𝕨 must be either ≠𝕩 or one bigger (%s≡≠𝕨, %s≡≠𝕩)", wia, xia);
u8 we = TI(w,elType);
if (elInt(we)) {
if (we==el_bit) w = taga(cpyI8Arr(w));
i64 ria = 0;
bool bad = false, sort = true;
usz neg = 0, change = 0;
void *wp0 = tyany_ptr(w);
#define CASE(T) case el_##T: { \
T max = -1, prev = -1; \
for (usz i = 0; i < xia; i++) { \
T n = ((T*)wp0)[i]; \
if (n>max) max = n; \
bad |= n < -1; \
neg += n == -1; \
sort &= prev <= n; \
change += prev != n; \
prev = n; \
} \
if (wia>xia) { ria=((T*)wp0)[xia]; bad|=ria<-1; } \
i64 m=(i64)max+1; if (m>ria) ria=m; \
break; }
switch (we) { default:UD; case el_bit: CASE(i8) CASE(i16) CASE(i32) }
#undef CASE
if (bad) thrM("⊔: 𝕨 can't contain elements less than ¯1");
if (ria > (i64)(USZ_MAX)) thrOOM();
Arr* r = arr_shVec(m_fillarrp(ria)); fillarr_setFill(r, m_f64(0));
B* rp = fillarr_ptr(r);
for (usz i = 0; i < ria; i++) rp[i] = m_f64(0); // don't break if allocation errors
B xf = getFillQ(x);
Arr* rf = arr_shVec(m_fillarrp(0)); fillarr_setFill(rf, m_f64(0));
B z = taga(rf);
fillarr_setFill(r, z);
TALLOC(i32, pos, 2*ria+1); i32* len = pos+ria+1;
// Both cases needed to make sure wia>0 for ip[wia-1] below
if (ria==0) goto intvec_ret;
if (neg==xia) {
for (usz i = 0; i < ria; i++) rp[i] = inc(z);
goto intvec_ret;
}
u8 xe = TI(x,elType);
u8 width = elWidth(xe);
u64 xw;
if (xia>64 && (xw=(u64)xia*width)<=I32_MAX && change<xw/32 && xe!=el_bit && xe!=el_B) {
#define C1(F,X ) F##_c1(m_f64(0),X )
#define C2(F,X,W) F##_c2(m_f64(0),X,W)
if (wia>xia) w = C2(take, m_f64(xia), w);
B c = C2(ne, C2(drop, m_f64(-1), inc(w)),
C2(drop, m_f64( 1), inc(w)));
B ind = C1(slash, C2(join, m_f64(-1!=IGetU(w,0).f), c));
w = C2(select, inc(ind), w);
#undef C1
#undef C2
if (TI(ind,elType)!=el_i32) ind = taga(cpyI32Arr(ind));
if (TI(w ,elType)!=el_i32) w = taga(cpyI32Arr(w ));
wia = IA(ind);
i32* ip = i32any_ptr(ind);
i32* wp = i32any_ptr(w);
usz i0 = ip[0];
for (usz i=0; i<wia-1; i++) ip[i] = ip[i+1]-ip[i];
ip[wia-1] = xia-ip[wia-1];
for (usz i = 0; i < ria; i++) len[i] = pos[i] = 0;
for (usz i = 0; i < wia; i++) len[wp[i]]+=ip[i];
void* xp = tyany_ptr(x);
u8 xt = el2t(xe);
for (usz j = 0; j < ria; j++) {
usz l=len[j];
if (!l) rp[j]=inc(z); else m_tyarrv(rp+j, width, l, xt);
}
for (usz i=0, k=i0*width; i<wia; i++) {
usz k0 = k;
usz l = ip[i]*width; k += l;
i32 n = wp[i]; if (n<0) continue;
memcpy((u8*)tyarr_ptr(rp[n])+pos[n], (u8*)xp+k0, l);
pos[n] += l;
}
decG(ind); goto intvec_ret;
}
if (xia>32 && neg>xia/4+xia/8) {
if (wia>xia) w = take_c2(m_f64(0), m_f64(xia), w);
B m = ne_c2(m_f64(0), m_f64(-1), inc(w));
w = slash_c2(m_f64(0), inc(m), w);
x = slash_c2(m_f64(0), m, x); xia = IA(x);
neg = 0;
}
if (TI(w,elType)!=el_i32) w = taga(cpyI32Arr(w));
i32* wp = i32any_ptr(w);
for (usz i = 0; i < ria; i++) len[i] = pos[i] = 0;
for (usz i = 0; i < xia; i++) len[wp[i]]++; // overallocation makes this safe after n<-1 check
switch (xe) { default: UD;
case el_i8: case el_c8:
case el_i16: case el_c16:
case el_i32: case el_c32: case el_f64: {
void* xp = tyany_ptr(x);
u8 xt = el2t(xe);
if (sort) {
for (usz j=0, i=neg*width; j<ria; j++) {
usz l = len[j];
if (!l) { rp[j]=inc(z); continue; }
m_tyarrv(rp+j, width, l, xt);
usz lw = l*width;
memcpy(tyarr_ptr(rp[j]), (u8*)xp+i, lw);
i += lw;
}
break;
}
for (usz j = 0; j < ria; j++) {
usz l=len[j];
if (!l) rp[j]=inc(z); else m_tyarrv(rp+j, width, l, xt);
}
switch(width) { default: UD;
case 1: for (usz i = 0; i < xia; i++) { i32 n = wp[i]; if (n>=0) ((u8* )tyarr_ptr(rp[n]))[pos[n]++] = ((u8* )xp)[i]; } break;
case 2: for (usz i = 0; i < xia; i++) { i32 n = wp[i]; if (n>=0) ((u16*)tyarr_ptr(rp[n]))[pos[n]++] = ((u16*)xp)[i]; } break;
case 4: for (usz i = 0; i < xia; i++) { i32 n = wp[i]; if (n>=0) ((u32*)tyarr_ptr(rp[n]))[pos[n]++] = ((u32*)xp)[i]; } break;
case 8: for (usz i = 0; i < xia; i++) { i32 n = wp[i]; if (n>=0) ((f64*)tyarr_ptr(rp[n]))[pos[n]++] = ((f64*)xp)[i]; } break;
}
break;
}
case el_bit: case el_B: {
for (usz i = 0; i < ria; i++) {
Arr* c = m_fillarrp(len[i]);
c->ia = 0;
fillarr_setFill(c, inc(xf));
arr_shVec(c);
rp[i] = taga(c);
}
SLOW2("𝕨⊔𝕩", w, x);
SGet(x)
for (usz i = 0; i < xia; i++) {
i32 n = wp[i];
if (n>=0) fillarr_ptr(a(rp[n]))[pos[n]++] = Get(x, i);
}
for (usz i = 0; i < ria; i++) a(rp[i])->ia = len[i];
break;
}
}
intvec_ret:
fillarr_setFill(rf, xf);
decG(w); decG(x); TFREE(pos);
return taga(r);
} else {
SLOW2("𝕨⊔𝕩", w, x);
SGetU(w)
i64 ria = wia==xia? 0 : o2i64(GetU(w, xia));
if (ria<-1) thrM("⊔: 𝕨 can't contain elements less than ¯1");
ria--;
for (usz i = 0; i < xia; i++) {
B cw = GetU(w, i);
if (!q_i64(cw)) goto base;
i64 c = o2i64G(cw);
if (c>ria) ria = c;
if (c<-1) thrM("⊔: 𝕨 can't contain elements less than ¯1");
}
if (ria > (i64)(USZ_MAX-1)) thrOOM();
ria++;
TALLOC(i32, lenO, ria+1); i32* len = lenO+1;
TALLOC(i32, pos, ria);
for (usz i = 0; i < ria; i++) len[i] = pos[i] = 0;
for (usz i = 0; i < xia; i++) len[o2i64G(GetU(w, i))]++;
Arr* r = arr_shVec(m_fillarrp(ria)); fillarr_setFill(r, m_f64(0));
B* rp = fillarr_ptr(r);
for (usz i = 0; i < ria; i++) rp[i] = m_f64(0); // don't break if allocation errors
B xf = getFillQ(x);
for (usz i = 0; i < ria; i++) {
Arr* c = m_fillarrp(len[i]);
c->ia = 0;
fillarr_setFill(c, inc(xf));
arr_shVec(c);
rp[i] = taga(c);
}
Arr* rf = m_fillarrp(0); arr_shVec(rf);
fillarr_setFill(rf, xf);
fillarr_setFill(r, taga(rf));
SGet(x)
for (usz i = 0; i < xia; i++) {
i64 n = o2i64G(GetU(w, i));
if (n>=0) fillarr_ptr(a(rp[n]))[pos[n]++] = Get(x, i);
}
for (usz i = 0; i < ria; i++) a(rp[i])->ia = len[i];
decG(w); decG(x); TFREE(lenO); TFREE(pos);
return taga(r);
}
}
base:
return c2(rt_group, w, x);
}
B ud_c1(B, B);
B group_c1(B t, B x) {
if (isArr(x) && RNK(x)==1 && TI(x,arrD1)) {
usz ia = IA(x);
B range = ud_c1(t, m_f64(ia));
return group_c2(m_f64(0), x, range);
}
return c1(rt_group, x);
}

View File

@ -811,222 +811,6 @@ B shifta_c2(B t, B w, B x) {
return qWithFill(mut_fcd(r, x), f);
}
extern B ne_c2(B, B, B);
extern B slash_c1(B, B);
extern B slash_c2(B, B, B);
extern B select_c2(B, B, B);
extern B rt_group;
B group_c2(B t, B w, B x) {
if (isArr(w)&isArr(x) && RNK(w)==1 && RNK(x)==1 && depth(w)==1) {
usz wia = IA(w);
usz xia = IA(x);
if (wia-xia > 1) thrF("⊔: ≠𝕨 must be either ≠𝕩 or one bigger (%s≡≠𝕨, %s≡≠𝕩)", wia, xia);
u8 we = TI(w,elType);
if (elInt(we)) {
if (we==el_bit) w = taga(cpyI8Arr(w));
i64 ria = 0;
bool bad = false, sort = true;
usz neg = 0, change = 0;
void *wp0 = tyany_ptr(w);
#define CASE(T) case el_##T: { \
T max = -1, prev = -1; \
for (usz i = 0; i < xia; i++) { \
T n = ((T*)wp0)[i]; \
if (n>max) max = n; \
bad |= n < -1; \
neg += n == -1; \
sort &= prev <= n; \
change += prev != n; \
prev = n; \
} \
if (wia>xia) { ria=((T*)wp0)[xia]; bad|=ria<-1; } \
i64 m=(i64)max+1; if (m>ria) ria=m; \
break; }
switch (we) { default:UD; case el_bit: CASE(i8) CASE(i16) CASE(i32) }
#undef CASE
if (bad) thrM("⊔: 𝕨 can't contain elements less than ¯1");
if (ria > (i64)(USZ_MAX)) thrOOM();
Arr* r = arr_shVec(m_fillarrp(ria)); fillarr_setFill(r, m_f64(0));
B* rp = fillarr_ptr(r);
for (usz i = 0; i < ria; i++) rp[i] = m_f64(0); // don't break if allocation errors
B xf = getFillQ(x);
Arr* rf = arr_shVec(m_fillarrp(0)); fillarr_setFill(rf, m_f64(0));
B z = taga(rf);
fillarr_setFill(r, z);
TALLOC(i32, pos, 2*ria+1); i32* len = pos+ria+1;
// Both cases needed to make sure wia>0 for ip[wia-1] below
if (ria==0) goto intvec_ret;
if (neg==xia) {
for (usz i = 0; i < ria; i++) rp[i] = inc(z);
goto intvec_ret;
}
u8 xe = TI(x,elType);
u8 width = elWidth(xe);
u64 xw;
if (xia>64 && (xw=(u64)xia*width)<=I32_MAX && change<xw/32 && xe!=el_bit && xe!=el_B) {
#define C1(F,X ) F##_c1(m_f64(0),X )
#define C2(F,X,W) F##_c2(m_f64(0),X,W)
if (wia>xia) w = C2(take, m_f64(xia), w);
B c = C2(ne, C2(drop, m_f64(-1), inc(w)),
C2(drop, m_f64( 1), inc(w)));
B ind = C1(slash, C2(join, m_f64(-1!=IGetU(w,0).f), c));
w = C2(select, inc(ind), w);
#undef C1
#undef C2
if (TI(ind,elType)!=el_i32) ind = taga(cpyI32Arr(ind));
if (TI(w ,elType)!=el_i32) w = taga(cpyI32Arr(w ));
wia = IA(ind);
i32* ip = i32any_ptr(ind);
i32* wp = i32any_ptr(w);
usz i0 = ip[0];
for (usz i=0; i<wia-1; i++) ip[i] = ip[i+1]-ip[i];
ip[wia-1] = xia-ip[wia-1];
for (usz i = 0; i < ria; i++) len[i] = pos[i] = 0;
for (usz i = 0; i < wia; i++) len[wp[i]]+=ip[i];
void* xp = tyany_ptr(x);
u8 xt = el2t(xe);
for (usz j = 0; j < ria; j++) {
usz l=len[j];
if (!l) rp[j]=inc(z); else m_tyarrv(rp+j, width, l, xt);
}
for (usz i=0, k=i0*width; i<wia; i++) {
usz k0 = k;
usz l = ip[i]*width; k += l;
i32 n = wp[i]; if (n<0) continue;
memcpy((u8*)tyarr_ptr(rp[n])+pos[n], (u8*)xp+k0, l);
pos[n] += l;
}
decG(ind); goto intvec_ret;
}
if (xia>32 && neg>xia/4+xia/8) {
if (wia>xia) w = take_c2(m_f64(0), m_f64(xia), w);
B m = ne_c2(m_f64(0), m_f64(-1), inc(w));
w = slash_c2(m_f64(0), inc(m), w);
x = slash_c2(m_f64(0), m, x); xia = IA(x);
neg = 0;
}
if (TI(w,elType)!=el_i32) w = taga(cpyI32Arr(w));
i32* wp = i32any_ptr(w);
for (usz i = 0; i < ria; i++) len[i] = pos[i] = 0;
for (usz i = 0; i < xia; i++) len[wp[i]]++; // overallocation makes this safe after n<-1 check
switch (xe) { default: UD;
case el_i8: case el_c8:
case el_i16: case el_c16:
case el_i32: case el_c32: case el_f64: {
void* xp = tyany_ptr(x);
u8 xt = el2t(xe);
if (sort) {
for (usz j=0, i=neg*width; j<ria; j++) {
usz l = len[j];
if (!l) { rp[j]=inc(z); continue; }
m_tyarrv(rp+j, width, l, xt);
usz lw = l*width;
memcpy(tyarr_ptr(rp[j]), (u8*)xp+i, lw);
i += lw;
}
break;
}
for (usz j = 0; j < ria; j++) {
usz l=len[j];
if (!l) rp[j]=inc(z); else m_tyarrv(rp+j, width, l, xt);
}
switch(width) { default: UD;
case 1: for (usz i = 0; i < xia; i++) { i32 n = wp[i]; if (n>=0) ((u8* )tyarr_ptr(rp[n]))[pos[n]++] = ((u8* )xp)[i]; } break;
case 2: for (usz i = 0; i < xia; i++) { i32 n = wp[i]; if (n>=0) ((u16*)tyarr_ptr(rp[n]))[pos[n]++] = ((u16*)xp)[i]; } break;
case 4: for (usz i = 0; i < xia; i++) { i32 n = wp[i]; if (n>=0) ((u32*)tyarr_ptr(rp[n]))[pos[n]++] = ((u32*)xp)[i]; } break;
case 8: for (usz i = 0; i < xia; i++) { i32 n = wp[i]; if (n>=0) ((f64*)tyarr_ptr(rp[n]))[pos[n]++] = ((f64*)xp)[i]; } break;
}
break;
}
case el_bit: case el_B: {
for (usz i = 0; i < ria; i++) {
Arr* c = m_fillarrp(len[i]);
c->ia = 0;
fillarr_setFill(c, inc(xf));
arr_shVec(c);
rp[i] = taga(c);
}
SLOW2("𝕨⊔𝕩", w, x);
SGet(x)
for (usz i = 0; i < xia; i++) {
i32 n = wp[i];
if (n>=0) fillarr_ptr(a(rp[n]))[pos[n]++] = Get(x, i);
}
for (usz i = 0; i < ria; i++) a(rp[i])->ia = len[i];
break;
}
}
intvec_ret:
fillarr_setFill(rf, xf);
decG(w); decG(x); TFREE(pos);
return taga(r);
} else {
SLOW2("𝕨⊔𝕩", w, x);
SGetU(w)
i64 ria = wia==xia? 0 : o2i64(GetU(w, xia));
if (ria<-1) thrM("⊔: 𝕨 can't contain elements less than ¯1");
ria--;
for (usz i = 0; i < xia; i++) {
B cw = GetU(w, i);
if (!q_i64(cw)) goto base;
i64 c = o2i64G(cw);
if (c>ria) ria = c;
if (c<-1) thrM("⊔: 𝕨 can't contain elements less than ¯1");
}
if (ria > (i64)(USZ_MAX-1)) thrOOM();
ria++;
TALLOC(i32, lenO, ria+1); i32* len = lenO+1;
TALLOC(i32, pos, ria);
for (usz i = 0; i < ria; i++) len[i] = pos[i] = 0;
for (usz i = 0; i < xia; i++) len[o2i64G(GetU(w, i))]++;
Arr* r = arr_shVec(m_fillarrp(ria)); fillarr_setFill(r, m_f64(0));
B* rp = fillarr_ptr(r);
for (usz i = 0; i < ria; i++) rp[i] = m_f64(0); // don't break if allocation errors
B xf = getFillQ(x);
for (usz i = 0; i < ria; i++) {
Arr* c = m_fillarrp(len[i]);
c->ia = 0;
fillarr_setFill(c, inc(xf));
arr_shVec(c);
rp[i] = taga(c);
}
Arr* rf = m_fillarrp(0); arr_shVec(rf);
fillarr_setFill(rf, xf);
fillarr_setFill(r, taga(rf));
SGet(x)
for (usz i = 0; i < xia; i++) {
i64 n = o2i64G(GetU(w, i));
if (n>=0) fillarr_ptr(a(rp[n]))[pos[n]++] = Get(x, i);
}
for (usz i = 0; i < ria; i++) a(rp[i])->ia = len[i];
decG(w); decG(x); TFREE(lenO); TFREE(pos);
return taga(r);
}
}
base:
return c2(rt_group, w, x);
}
B ud_c1(B, B);
B group_c1(B t, B x) {
if (isArr(x) && RNK(x)==1 && TI(x,arrD1)) {
usz ia = IA(x);
B range = ud_c1(t, m_f64(ia));
return group_c2(m_f64(0), x, range);
}
return c1(rt_group, x);
}
extern B rt_reverse;
B reverse_c1(B t, B x) {
if (isAtm(x) || RNK(x)==0) thrM("⌽: Argument cannot be a unit");
@ -1194,54 +978,6 @@ B pick_ucw(B t, B o, B w, B x) {
return qWithFill(mut_fcd(r, x), xf);
}
B slash_ucw(B t, B o, B w, B x) {
if (isAtm(w) || isAtm(x) || RNK(w)!=1 || RNK(x)!=1 || IA(w)!=IA(x)) return def_fn_ucw(t, o, w, x);
usz ia = IA(x);
SGetU(w)
if (!elInt(TI(w,elType))) for (usz i = 0; i < ia; i++) if (!q_i32(GetU(w,i))) return def_fn_ucw(t, o, w, x);
B arg = slash_c2(t, inc(w), inc(x));
usz argIA = IA(arg);
B rep = c1(o, arg);
if (isAtm(rep) || RNK(rep)!=1 || IA(rep) != argIA) thrF("𝔽⌾(a⊸/)𝕩: Result of 𝔽 must have the same shape as a/𝕩 (expected ⟨%s⟩, got %H)", argIA, rep);
MAKE_MUT(r, ia); mut_init(r, el_or(TI(x,elType), TI(rep,elType)));
SGet(x)
SGet(rep)
usz repI = 0;
if (TY(w) == t_bitarr) {
u64* d = bitarr_ptr(w);
if (elInt(TI(x,elType)) && elInt(TI(rep,elType))) {
if (r->fns->elType!=el_i32) mut_to(r, el_i32);
i32* rp = r->ai32;
x = toI32Any(x); i32* xp = i32any_ptr(x);
rep = toI32Any(rep); i32* np = i32any_ptr(rep);
for (usz i = 0; i < ia; i++) {
bool v = bitp_get(d, i);
i32 nc = np[repI];
i32 xc = xp[i];
rp[i] = v? nc : xc;
repI+= v;
}
} else {
MUTG_INIT(r);
for (usz i = 0; i < ia; i++) mut_setG(r, i, bitp_get(d, i)? Get(rep,repI++) : Get(x,i));
}
} else {
SGetU(rep)
MUTG_INIT(r);
for (usz i = 0; i < ia; i++) {
i32 cw = o2iG(GetU(w, i));
if (cw) {
B cr = Get(rep,repI);
if (CHECK_VALID) for (i32 j = 1; j < cw; j++) if (!equal(GetU(rep,repI+j), cr)) { mut_pfree(r,i); thrM("𝔽⌾(a⊸/): Incompatible result elements"); }
mut_setG(r, i, cr);
repI+= cw;
} else mut_setG(r, i, Get(x,i));
}
}
decG(w); decG(rep);
return mut_fcd(r, x);
}
static B takedrop_ucw(i64 wi, B o, u64 am, B x, size_t xr) {
usz xia = IA(x);
usz csz = arr_csz(x);
@ -1327,7 +1063,6 @@ void sfns_init() {
c(BFn,bi_pick)->uc1 = pick_uc1;
c(BFn,bi_reverse)->uc1 = reverse_uc1;
c(BFn,bi_pick)->ucw = pick_ucw;
c(BFn,bi_slash)->ucw = slash_ucw;
c(BFn,bi_select)->ucw = select_ucw; // TODO move to new init fn
c(BFn,bi_shape)->uc1 = shape_uc1;
c(BFn,bi_transp)->uc1 = transp_uc1;

View File

@ -617,6 +617,55 @@ B slash_im(B t, B x) {
}
}
B slash_ucw(B t, B o, B w, B x) {
if (isAtm(w) || isAtm(x) || RNK(w)!=1 || RNK(x)!=1 || IA(w)!=IA(x)) return def_fn_ucw(t, o, w, x);
usz ia = IA(x);
SGetU(w)
if (!elInt(TI(w,elType))) for (usz i = 0; i < ia; i++) if (!q_i32(GetU(w,i))) return def_fn_ucw(t, o, w, x);
B arg = slash_c2(t, inc(w), inc(x));
usz argIA = IA(arg);
B rep = c1(o, arg);
if (isAtm(rep) || RNK(rep)!=1 || IA(rep) != argIA) thrF("𝔽⌾(a⊸/)𝕩: Result of 𝔽 must have the same shape as a/𝕩 (expected ⟨%s⟩, got %H)", argIA, rep);
MAKE_MUT(r, ia); mut_init(r, el_or(TI(x,elType), TI(rep,elType)));
SGet(x)
SGet(rep)
usz repI = 0;
if (TY(w) == t_bitarr) {
u64* d = bitarr_ptr(w);
if (elInt(TI(x,elType)) && elInt(TI(rep,elType))) {
if (r->fns->elType!=el_i32) mut_to(r, el_i32);
i32* rp = r->ai32;
x = toI32Any(x); i32* xp = i32any_ptr(x);
rep = toI32Any(rep); i32* np = i32any_ptr(rep);
for (usz i = 0; i < ia; i++) {
bool v = bitp_get(d, i);
i32 nc = np[repI];
i32 xc = xp[i];
rp[i] = v? nc : xc;
repI+= v;
}
} else {
MUTG_INIT(r);
for (usz i = 0; i < ia; i++) mut_setG(r, i, bitp_get(d, i)? Get(rep,repI++) : Get(x,i));
}
} else {
SGetU(rep)
MUTG_INIT(r);
for (usz i = 0; i < ia; i++) {
i32 cw = o2iG(GetU(w, i));
if (cw) {
B cr = Get(rep,repI);
if (CHECK_VALID) for (i32 j = 1; j < cw; j++) if (!equal(GetU(rep,repI+j), cr)) { mut_pfree(r,i); thrM("𝔽⌾(a⊸/): Incompatible result elements"); }
mut_setG(r, i, cr);
repI+= cw;
} else mut_setG(r, i, Get(x,i));
}
}
decG(w); decG(rep);
return mut_fcd(r, x);
}
void slash_init() {
c(BFn,bi_slash)->im = slash_im;
}
c(BFn,bi_slash)->ucw = slash_ucw;
}

View File

@ -17,6 +17,7 @@
#include "../builtins/sfns.c"
#include "../builtins/select.c"
#include "../builtins/slash.c"
#include "../builtins/group.c"
#include "../builtins/sysfn.c"
#include "../builtins/sort.c"
#include "../builtins/selfsearch.c"