mut
This commit is contained in:
parent
6c2ed64ab4
commit
4783812eaf
@ -29,6 +29,7 @@ B getFill(B x) { // consumes; can return bi_noFill
|
||||
if (t==t_fillslice) { B r = inc(c(FillArr,c(Slice,x)->p)->fill); dec(x); return r; }
|
||||
if (t==t_c32arr || t==t_c32slice) { dec(x); return m_c32(' '); }
|
||||
if (t==t_i32arr || t==t_i32slice) { dec(x); return m_f64(0 ); }
|
||||
if (t==t_f64arr || t==t_f64slice) { dec(x); return m_f64(0 ); }
|
||||
dec(x);
|
||||
return bi_noFill;
|
||||
}
|
||||
@ -118,8 +119,9 @@ B withFill(B x, B fill) { // consumes both
|
||||
#endif
|
||||
if (noFill(fill) && v(x)->type!=t_fillarr && v(x)->type!=t_fillslice) return x;
|
||||
switch(v(x)->type) {
|
||||
case t_i32arr : case t_i32slice : if(fill.u == m_i32(0 ).u) return x; break;
|
||||
case t_c32arr : case t_c32slice : if(fill.u == m_c32(' ').u) return x; break;
|
||||
case t_f64arr : case t_f64slice:
|
||||
case t_i32arr : case t_i32slice: if(fill.u == m_i32(0 ).u) return x; break;
|
||||
case t_c32arr : case t_c32slice: if(fill.u == m_c32(' ').u) return x; break;
|
||||
case t_fillslice: if (equal(c(FillArr,c(Slice,x)->p)->fill, fill)) { dec(fill); return x; } break;
|
||||
case t_fillarr: if (equal(c(FillArr,x)->fill, fill)) { dec(fill); return x; }
|
||||
if (reusable(x)) {
|
||||
|
||||
28
src/h.h
28
src/h.h
@ -72,6 +72,15 @@ enum Type {
|
||||
#endif
|
||||
t_COUNT
|
||||
};
|
||||
|
||||
enum ElType { // a⌈b shall return the type that can store both, if possible
|
||||
el_i32=0,
|
||||
el_f64=1,
|
||||
el_c32=2,
|
||||
el_B =3,
|
||||
el_MAX=4 // also used for incomplete in mut.c
|
||||
};
|
||||
|
||||
char* format_type(u8 u) {
|
||||
switch(u) { default: return"(unknown type)";
|
||||
case t_empty:return"empty"; case t_shape:return"shape";
|
||||
@ -204,6 +213,7 @@ void printRaw(B x); // doesn't consume
|
||||
void print(B x); // doesn't consume
|
||||
bool equal(B w, B x); // doesn't consume
|
||||
void arr_print(B x); // doesn't consume
|
||||
u8 fillElType(B x); // doesn't consume
|
||||
bool eqShape(B w, B x); // doesn't consume
|
||||
usz arr_csz(B x); // doesn't consume
|
||||
bool eqShPrefix(usz* w, usz* x, ur len);
|
||||
@ -228,12 +238,14 @@ B catchMessage;
|
||||
|
||||
|
||||
|
||||
#define c(T,x) ((T*)((x).u&0xFFFFFFFFFFFFull))
|
||||
#define v(x) c(Value, x)
|
||||
#define a(x) c(Arr , x)
|
||||
#define rnk(x ) (v(x)->extra) // expects argument to be Arr
|
||||
#define srnk(x,r) (v(x)->extra=(r))
|
||||
#define VT(x,t) assert(isVal(x) && v(x)->type==t)
|
||||
#define c(T,X) ((T*)((X).u&0xFFFFFFFFFFFFull))
|
||||
#define v(X) c(Value, X)
|
||||
#define a(X) c(Arr , X)
|
||||
#define prnk(X ) (X->extra)
|
||||
#define sprnk(X,R) (X->extra=(R))
|
||||
#define rnk(X ) prnk(v(X))
|
||||
#define srnk(X,R) sprnk(v(X),R)
|
||||
#define VT(X,T) assert(isVal(X) && v(X)->type==(T))
|
||||
|
||||
void print_vmStack();
|
||||
#ifdef DEBUG
|
||||
@ -358,9 +370,11 @@ typedef struct TypeInfo {
|
||||
BB2B m1_d; // consume all args; (m, f)
|
||||
BBB2B m2_d; // consume all args; (m, f, g)
|
||||
BS2B slice; // consumes; create slice from given starting position; add ia, rank, shape yourself; may not actually be a Slice object
|
||||
B2b canStore; // doesn't consume
|
||||
B2B identity; // return identity element of this function; doesn't consume
|
||||
|
||||
B2b canStore; // doesn't consume
|
||||
u8 elType;
|
||||
|
||||
B2v print; // doesn't consume
|
||||
B2v visit; // call mm_visit for all referents
|
||||
B2B decompose; // consumes; must return a HArr
|
||||
|
||||
@ -74,5 +74,6 @@ static inline void i32arr_init() {
|
||||
ti[t_i32arr].print = arr_print; ti[t_i32slice].print = arr_print;
|
||||
ti[t_i32arr].isArr = true; ti[t_i32slice].isArr = true;
|
||||
ti[t_i32arr].arrD1 = true; ti[t_i32slice].arrD1 = true;
|
||||
ti[t_i32arr].elType = el_i32; ti[t_i32slice].elType = el_i32;
|
||||
ti[t_i32arr].canStore = i32arr_canStore;
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "i32arr.c"
|
||||
#include "c32arr.c"
|
||||
#include "f64arr.c"
|
||||
#include "mut.c"
|
||||
#include "utf.c"
|
||||
#include "derv.c"
|
||||
#include "fns.c"
|
||||
|
||||
108
src/mut.c
Normal file
108
src/mut.c
Normal file
@ -0,0 +1,108 @@
|
||||
typedef struct Mut {
|
||||
u8 type;
|
||||
usz ia;
|
||||
Arr* val;
|
||||
} Mut;
|
||||
#define MAKE_MUT(N, IA) Mut N##_val; N##_val.type = el_MAX; N##_val.ia = (IA); Mut* N = &N##_val;
|
||||
|
||||
void mut_to(Mut* m, u8 n) {
|
||||
u8 o = m->type;
|
||||
m->type = n;
|
||||
if (o==el_MAX) {
|
||||
switch(n) { default: UD;
|
||||
case el_i32: m->val = a(m_i32arrp(m->ia)) ; return;
|
||||
case el_f64: m->val = a(m_f64arrp(m->ia)) ; return;
|
||||
case el_c32: m->val = a(m_c32arrp(m->ia)) ; return;
|
||||
case el_B : m->val = (Arr*)m_harrUp(m->ia).c; return;
|
||||
}
|
||||
} else {
|
||||
sprnk(m->val, 1);
|
||||
m->val->sh = &m->val->ia;
|
||||
switch(n) { default: UD;
|
||||
case el_i32: m->val = (Arr*)toI32Arr(tag(m->val, ARR_TAG)); return;
|
||||
case el_f64: m->val = (Arr*)toF64Arr(tag(m->val, ARR_TAG)); return;
|
||||
case el_c32: m->val = (Arr*)toC32Arr(tag(m->val, ARR_TAG)); return;
|
||||
case el_B : m->val = (Arr*)toHArr (tag(m->val, ARR_TAG)); return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
B mut_fv(Mut* m) {
|
||||
assert(m->type!=el_MAX);
|
||||
m->val->sh = &m->val->ia;
|
||||
B r = tag(m->val, ARR_TAG);
|
||||
srnk(r, 1);
|
||||
return r;
|
||||
}
|
||||
B mut_fp(Mut* m) {
|
||||
assert(m->type!=el_MAX);
|
||||
return tag(m->val, ARR_TAG);
|
||||
}
|
||||
|
||||
u8 el_or(u8 a, u8 b) {
|
||||
#define M(X) if(b==X) return b>X?b:X;
|
||||
switch (a) {
|
||||
case el_c32: M(el_c32); return el_B;
|
||||
case el_i32: M(el_i32); M(el_f64); return el_B;
|
||||
case el_f64: M(el_i32); M(el_f64); return el_B;
|
||||
case el_B: return el_B;
|
||||
case el_MAX: return b;
|
||||
default: UD;
|
||||
}
|
||||
#undef M
|
||||
}
|
||||
|
||||
// expects x to be an array, each position must be written to precisely once
|
||||
// doesn't consume x
|
||||
void mut_copy(Mut* m, usz ms, B x, usz xs, usz l) {
|
||||
assert(isArr(x));
|
||||
u8 xt = v(x)->type;
|
||||
u8 xe = ti[xt].elType;
|
||||
// printf("mut_%d[%d…%d] ← %s[%d…%d]\n", m->type, ms, ms+l, format_type(xt), xs, xs+l); fflush(stdout);
|
||||
again:
|
||||
#define AGAIN { mut_to(m, el_or(m->type, xe)); goto again; }
|
||||
// TODO try harder to not bump type
|
||||
switch(m->type) {
|
||||
case el_MAX: AGAIN;
|
||||
|
||||
case el_i32: {
|
||||
i32* xp;
|
||||
if (xt==t_i32arr) xp = i32arr_ptr(x);
|
||||
else if (xt==t_i32slice) xp = c(I32Slice,x)->a;
|
||||
else AGAIN;
|
||||
memcpy(((I32Arr*)m->val)->a+ms, xp+xs, l*4);
|
||||
return;
|
||||
}
|
||||
case el_c32: {
|
||||
u32* xp;
|
||||
if (xt==t_c32arr) xp = c32arr_ptr(x);
|
||||
else if (xt==t_c32slice) xp = c(C32Slice,x)->a;
|
||||
else AGAIN;
|
||||
memcpy(((C32Arr*)m->val)->a+ms, xp+xs, l*4);
|
||||
return;
|
||||
}
|
||||
case el_f64: {
|
||||
f64* xp;
|
||||
if (xt==t_f64arr) xp = f64arr_ptr(x);
|
||||
else if (xt==t_f64slice) xp = c(F64Slice,x)->a;
|
||||
else AGAIN;
|
||||
memcpy(((F64Arr*)m->val)->a+ms, xp+xs, l*8);
|
||||
return;
|
||||
}
|
||||
case el_B: {
|
||||
B* mpo = ((HArr*)m->val)->a+ms;
|
||||
B* xp;
|
||||
if (xt==t_harr) xp = harr_ptr(x);
|
||||
else if (xt==t_hslice) xp = c(HSlice,x)->a;
|
||||
else {
|
||||
BS2B xget = ti[xt].get;
|
||||
for (usz i = 0; i < l; i++) mpo[i] = xget(x,i+xs);
|
||||
return;
|
||||
}
|
||||
memcpy(mpo, xp+xs, l*sizeof(B*));
|
||||
for (usz i = 0; i < l; i++) inc(mpo[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#undef AGAIN
|
||||
}
|
||||
38
src/sfns.c
38
src/sfns.c
@ -245,23 +245,24 @@ B select_c2(B t, B w, B x) {
|
||||
if (rr>UR_MAX) thrM("⊏: Result rank too large");
|
||||
usz csz = arr_csz(x);
|
||||
usz cam = a(x)->sh[0];
|
||||
usz ria = wia*csz;
|
||||
HArr_p r = m_harrUp(ria);
|
||||
usz* rsh = arr_shAllocR(r.b, rr);
|
||||
MAKE_MUT(r, wia*csz);
|
||||
mut_to(r, fillElType(xf));
|
||||
for (usz i = 0; i < wia; i++) {
|
||||
B cw = wgetU(w, i);
|
||||
if (!isNum(cw)) { harr_pfree(mut_fp(r), i*csz); goto base; }
|
||||
f64 c = o2f(cw);
|
||||
if (c<0) c+= cam;
|
||||
if ((usz)c >= cam) thrM("⊏: Indexing out-of-bounds");
|
||||
mut_copy(r, i*csz, x, csz*(usz)c, csz);
|
||||
}
|
||||
B rb = mut_fp(r);
|
||||
usz* rsh = arr_shAllocR(rb, rr);
|
||||
if (rsh) {
|
||||
memcpy(rsh , a(w)->sh , wr *sizeof(usz));
|
||||
memcpy(rsh+wr, a(x)->sh+1, (xr-1)*sizeof(usz));
|
||||
}
|
||||
for (usz i = 0; i < wia; i++) {
|
||||
B cw = wgetU(w, i);
|
||||
if (!isNum(cw)) { harr_pfree(r.b, i); goto base; }
|
||||
f64 c = o2f(cw);
|
||||
if (c<0) c+= cam;
|
||||
if ((usz)c >= cam) thrM("⊏: Indexing out-of-bounds");
|
||||
for (usz j = 0; j < csz; j++) r.a[i*csz+j] = xget(x, c*csz+j);
|
||||
}
|
||||
dec(w); dec(x);
|
||||
return withFill(r.b,xf);
|
||||
return withFill(rb,xf);
|
||||
}
|
||||
}
|
||||
base:
|
||||
@ -342,13 +343,14 @@ B drop_c2(B t, B w, B x) {
|
||||
}
|
||||
B join_c2(B t, B w, B x) {
|
||||
if (!isArr(w)|!isArr(x) || rnk(w)!=1 | rnk(x)!=1) thrM("∾: NYI non-vector args");
|
||||
usz wia = a(w)->ia; BS2B wget = TI(w).get;
|
||||
usz xia = a(x)->ia; BS2B xget = TI(x).get;
|
||||
HArr_p r = m_harrUv(wia+xia);
|
||||
for (i64 i = 0; i < wia; i++) r.a[i ] = wget(w, i);
|
||||
for (i64 i = 0; i < xia; i++) r.a[i+wia] = xget(x, i);
|
||||
usz wia = a(w)->ia;
|
||||
usz xia = a(x)->ia;
|
||||
MAKE_MUT(r, wia+xia);
|
||||
mut_to(r, el_or(TI(w).elType, TI(x).elType));
|
||||
mut_copy(r, 0, w, 0, wia);
|
||||
mut_copy(r, wia, x, 0, xia);
|
||||
dec(x); dec(w);
|
||||
return r.b;
|
||||
return mut_fv(r);
|
||||
}
|
||||
|
||||
#define ba(N) bi_##N = mm_alloc(sizeof(BFn), t_funBI, ftag(FUN_TAG)); c(Fun,bi_##N)->c2 = N##_c2 ;c(Fun,bi_##N)->c1 = N##_c1 ; c(Fun,bi_##N)->extra=pf_##N; c(BFn,bi_##N)->ident=bi_N; gc_add(bi_##N);
|
||||
|
||||
@ -118,6 +118,12 @@ usz arr_csz(B x) {
|
||||
return r;
|
||||
}
|
||||
|
||||
u8 fillElType(B x) {
|
||||
if (isNum(x)) return el_i32;
|
||||
if (isC32(x)) return el_c32;
|
||||
return el_B;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -182,7 +188,8 @@ static inline void hdr_init() {
|
||||
ti[i].m2_d = def_m2_d;
|
||||
ti[i].isArr = false;
|
||||
ti[i].arrD1 = false;
|
||||
ti[i].identity = def_identity;
|
||||
ti[i].elType = el_B;
|
||||
ti[i].identity = def_identity;
|
||||
ti[i].decompose = def_decompose;
|
||||
ti[i].slice = def_slice;
|
||||
ti[i].canStore = def_canStore;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user