Move Group to its own file
This commit is contained in:
parent
0b1ded14e0
commit
21033fa355
2
makefile
2
makefile
@ -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
225
src/builtins/group.c
Normal 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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user