slices for ⥊

This commit is contained in:
dzaima 2021-03-30 12:26:42 +03:00
parent 0eb8b37236
commit f534115d1c
5 changed files with 64 additions and 48 deletions

32
src/h.h
View File

@ -59,8 +59,9 @@ enum Type {
/*10*/ t_md1D, t_md2D, t_md2H, /*10*/ t_md1D, t_md2D, t_md2H,
/*13*/ t_harr, t_i32arr, /*13*/ t_harr, t_i32arr,
/*15*/ t_hslice, t_i32slice,
/*15*/ t_comp, t_block, t_body, t_scope, /*17*/ t_comp, t_block, t_body, t_scope,
Type_MAX Type_MAX
@ -103,7 +104,7 @@ typedef struct Value {
i32 refc; i32 refc;
u16 flags; // incl GC stuff when that's a thing, possibly whether is sorted/a permutation/whatever, bucket size, etc u16 flags; // incl GC stuff when that's a thing, possibly whether is sorted/a permutation/whatever, bucket size, etc
u8 type; // needed globally so refc-- and GC know what to visit u8 type; // needed globally so refc-- and GC know what to visit
u8 extra; // whatever object-specific stuff. Rank for arrays, id for functions ur extra; // whatever object-specific stuff. Rank for arrays, id for functions
} Value; } Value;
typedef struct Arr { typedef struct Arr {
struct Value; struct Value;
@ -112,7 +113,8 @@ typedef struct Arr {
} Arr; } Arr;
// memory manager // memory manager
B mm_alloc(usz sz, u8 type, u64 tag); B mm_alloc (usz sz, u8 type, u64 tag);
void* mm_allocN(usz sz, u8 type);
void mm_free(Value* x); void mm_free(Value* x);
void mm_visit(B x); void mm_visit(B x);
@ -122,15 +124,18 @@ void inc(B x);
void ptr_dec(void* x); void ptr_dec(void* x);
void ptr_inc(void* x); void ptr_inc(void* x);
void print(B x); void print(B x);
void arr_print(B x);
B m_v1(B a ); B m_v1(B a );
B m_v2(B a, B b ); B m_v2(B a, B b );
B m_v3(B a, B b, B c ); B m_v3(B a, B b, B c );
B m_v4(B a, B b, B c, B d); B m_v4(B a, B b, B c, B d);
#define c(T,x) ((T*)((x).u&0xFFFFFFFFFFFFull)) #define c(T,x) ((T*)((x).u&0xFFFFFFFFFFFFull))
#define VT(x,t) assert(isVal(x) && v(x)->type==t)
Value* v(B x) { return c(Value, x); } Value* v(B x) { return c(Value, x); }
Arr* a(B x) { return c(Arr , x); } Arr* a(B x) { return c(Arr , x); }
#define rnk(x) (v(x)->extra) // expects argument to be Arr #define rnk(x ) (v(x)->extra) // expects argument to be Arr
#define srnk(x,v) (x)->extra=(v)
void print_vmStack(); void print_vmStack();
#ifdef DEBUG #ifdef DEBUG
@ -237,8 +242,19 @@ usz o2s (B x) { if ((usz)x.f!=x.f) err("o2s"": expected integer"); return (usz)
i64 o2i64(B x) { if ((i64)x.f!=x.f) err("o2i64: expected integer"); return (i64)x.f; } i64 o2i64(B x) { if ((i64)x.f!=x.f) err("o2i64: expected integer"); return (i64)x.f; }
typedef struct Slice {
struct Arr;
B p;
} Slice;
void slice_free(B x) { dec(c(Slice,x)->p); decSh(x); }
void slice_print(B x) { arr_print(x); }
typedef void (*B2V)(B); typedef void (*B2V)(B);
typedef B (*BS2B)(B, usz); typedef B (* BS2B)(B, usz);
typedef B (*BSS2B)(B, usz, usz);
typedef B (* B2B)(B); typedef B (* B2B)(B);
typedef B (* BB2B)(B, B); typedef B (* BB2B)(B, B);
typedef B (* BBB2B)(B, B, B); typedef B (* BBB2B)(B, B, B);
@ -253,16 +269,18 @@ typedef struct TypeInfo {
BB2B m1_d; // consume all args BB2B m1_d; // consume all args
BBB2B m2_d; // consume all args BBB2B m2_d; // consume all args
B2B decompose; // consumes; must return a HArr B2B decompose; // consumes; must return a HArr
BS2B slice; // consumes; create slice from given starting position; add ia, rank, shape yourself
} TypeInfo; } TypeInfo;
TypeInfo ti[Type_MAX]; TypeInfo ti[Type_MAX];
#define TI(x) (ti[v(x)->type]) #define TI(x) (ti[v(x)->type])
void do_nothing(B x) { } void do_nothing(B x) { }
B get_self(B x, usz n) { return x; }
void def_print(B x) { printf("(type %d)", v(x)->type); } void def_print(B x) { printf("(type %d)", v(x)->type); }
B get_self(B x, usz n) { return x; }
B def_m1_d(B m, B f ) { return err("cannot derive this"); } B def_m1_d(B m, B f ) { return err("cannot derive this"); }
B def_m2_d(B m, B f, B g) { return err("cannot derive this"); } B def_m2_d(B m, B f, B g) { return err("cannot derive this"); }
B def_slice(B x, usz s) { return err("cannot slice non-array!"); }
B def_decompose(B x) { return m_v2(m_i32((isFun(x)|isMd(x))? 0 : -1),x); } B def_decompose(B x) { return m_v2(m_i32((isFun(x)|isMd(x))? 0 : -1),x); }
B bi_nothing, bi_noVar, bi_badHdr, bi_optOut; B bi_nothing, bi_noVar, bi_badHdr, bi_optOut;
@ -274,6 +292,7 @@ void hdr_init() {
ti[i].m1_d = def_m1_d; ti[i].m1_d = def_m1_d;
ti[i].m2_d = def_m2_d; ti[i].m2_d = def_m2_d;
ti[i].decompose = def_decompose; ti[i].decompose = def_decompose;
ti[i].slice = def_slice;
} }
bi_nothing = tag(0, TAG_TAG); bi_nothing = tag(0, TAG_TAG);
bi_noVar = tag(1, TAG_TAG); bi_noVar = tag(1, TAG_TAG);
@ -404,7 +423,6 @@ void arr_print(B x) {
} }
#ifdef DEBUG #ifdef DEBUG
B validate(B x) { B validate(B x) {
if (!isVal(x)) return x; if (!isVal(x)) return x;

View File

@ -34,10 +34,7 @@ HArr_p m_harrp(usz ia) { // doesn't write any shape/size info! be careful!
B* harr_ptr(B x) { B* harr_ptr(B x) { VT(x,t_harr); return c(HArr,x)->a; }
assert(v(x)->type==t_harr);
return c(HArr,x)->a;
}
HArr* toHArr(B x) { HArr* toHArr(B x) {
if (v(x)->type==t_harr) return c(HArr,x); if (v(x)->type==t_harr) return c(HArr,x);
@ -75,22 +72,27 @@ B m_v3(B a, B b, B c ) { HArr_p r = m_harrv(3); r.a[0] = a; r.a[1] = b; r.a[
B m_v4(B a, B b, B c, B d) { HArr_p r = m_harrv(4); r.a[0] = a; r.a[1] = b; r.a[2] = c; r.a[3] = d; return r.b; } B m_v4(B a, B b, B c, B d) { HArr_p r = m_harrv(4); r.a[0] = a; r.a[1] = b; r.a[2] = c; r.a[3] = d; return r.b; }
typedef struct HSlice {
struct Slice;
B* a;
} HSlice;
B m_hslice(B p, B* ptr) { HSlice* r = mm_allocN(sizeof(HSlice), t_hslice); r->p=p; r->a = ptr; return tag(r, ARR_TAG); }
B harr_slice (B x, usz s) { return m_hslice(x, c(HArr,x)->a+s); }
B hslice_slice(B x, usz s) { B r=m_hslice(inci(c(HSlice,x)->p), c(HSlice,x)->a+s); dec(x); return r; }
void harr_print(B x) {
arr_print(x);
}
B harr_get(B x, usz n) {
return inci(c(HArr,x)->a[n]);
}
void harr_free(B x) { void harr_free(B x) {
decSh(x); decSh(x);
B* p = harr_ptr(x); B* p = harr_ptr(x);
usz ia = a(x)->ia; usz ia = a(x)->ia;
for (usz i = 0; i < ia; i++) dec(p[i]); for (usz i = 0; i < ia; i++) dec(p[i]);
} }
B harr_get (B x, usz n) { VT(x,t_harr ); return inci(c(HArr ,x)->a[n]); }
B hslice_get(B x, usz n) { VT(x,t_hslice); return inci(c(HSlice,x)->a[n]); }
void harr_init() { void harr_init() {
ti[t_harr].free = harr_free; ti[t_harr].get = harr_get; ti[t_hslice].get = hslice_get;
ti[t_harr].print = harr_print; ti[t_harr].slice = harr_slice; ti[t_hslice].slice = hslice_slice;
ti[t_harr].get = harr_get; ti[t_harr].free = harr_free; ti[t_hslice].free = slice_free;
ti[t_harr].print = arr_print; ti[t_hslice].print = arr_print;
} }

View File

@ -21,10 +21,7 @@ B m_i32arrp(usz ia) { // doesn't write any shape/size info! be careful!
} }
i32* i32arr_ptr(B x) { i32* i32arr_ptr(B x) { VT(x, t_i32arr); return c(I32Arr,x)->a; }
assert(v(x)->type==t_i32arr);
return c(I32Arr,x)->a;
}
B m_vai32(usz sz, ...) { B m_vai32(usz sz, ...) {
@ -49,12 +46,22 @@ I32Arr* toI32Arr(B x) {
} }
typedef struct I32Slice {
struct Slice;
i32* a;
} I32Slice;
B m_i32slice(B p, i32* ptr) { I32Slice* r = mm_allocN(sizeof(I32Slice), t_i32slice); r->p=p; r->a = ptr; return tag(r, ARR_TAG); }
B i32arr_slice (B x, usz s) { return m_i32slice(x, c(I32Arr,x)->a+s); }
B i32slice_slice(B x, usz s) { B r=m_i32slice(inci(c(I32Slice,x)->p), c(I32Slice,x)->a+s); dec(x); return r; }
B i32slice_get(B x, usz n) { VT(x,t_i32slice); return m_i32(c(I32Slice,x)->a[n]); }
B i32arr_get(B x, usz n) { VT(x,t_i32arr); return m_i32(c(I32Arr,x)->a[n]); }
void i32arr_free(B x) { decSh(x); } void i32arr_free(B x) { decSh(x); }
void i32arr_print(B x) { arr_print(x); }
B i32arr_get(B x, usz n) { assert(v(x)->type==t_i32arr); return m_i32(c(I32Arr,x)->a[n]); }
void i32arr_init() { void i32arr_init() {
ti[t_i32arr].free = i32arr_free; ti[t_i32arr].get = i32arr_get; ti[t_i32slice].get = i32slice_get;
ti[t_i32arr].print = i32arr_print; ti[t_i32arr].slice = i32arr_slice; ti[t_i32slice].slice = i32slice_slice;
ti[t_i32arr].get = i32arr_get; ti[t_i32arr].free = i32arr_free; ti[t_i32slice].free = slice_free;
ti[t_i32arr].print = arr_print; ti[t_i32slice].print = arr_print;
} }

View File

@ -8,11 +8,9 @@ B shape_c1(B t, B x) {
arr_shVec(x, ia); arr_shVec(x, ia);
return x; return x;
} }
HArr_p r = m_harrv(ia); B r = TI(x).slice(x, 0);
BS2B xget = TI(x).get; arr_shVec(r, ia);
for (i32 i = 0; i < ia; i++) r.a[i] = xget(x,i); return r;
dec(x);
return r.b;
} else return err("reshaping non-array"); } else return err("reshaping non-array");
} }
B shape_c2(B t, B w, B x) { B shape_c2(B t, B w, B x) {
@ -22,19 +20,10 @@ B shape_c2(B t, B w, B x) {
ur nr = a(w)->ia; ur nr = a(w)->ia;
usz nia = a(x)->ia; usz nia = a(x)->ia;
B r; B r;
bool reuse = reusable(x); if (reusable(x)) { r = x; decSh(x); }
if (reuse) { else r = TI(x).slice(x, 0);
r = x;
decSh(x);
} else {
HArr_p rg = m_harrp(nia);
BS2B xget = TI(x).get;
for (usz i = 0; i < nia; i++) rg.a[i] = xget(x,i);
r = rg.b;
}
usz* sh = arr_shAlloc(r, nia, nr); usz* sh = arr_shAlloc(r, nia, nr);
if (sh) for (i32 i = 0; i < nr; i++) sh[i] = o2i(wget(w,i)); if (sh) for (i32 i = 0; i < nr; i++) sh[i] = o2i(wget(w,i));
if (!reuse) dec(x);
dec(w); dec(w);
return r; return r;
} else return err("reshaping non-array"); } else return err("reshaping non-array");

View File

@ -211,7 +211,7 @@ B v_set(Scope* sc, B s, B x, bool upd) { // frees s, consumes x, returns previou
} }
sc->vars[(u32)s.u] = x; sc->vars[(u32)s.u] = x;
} else { } else {
assert(isArr(s) && v(s)->type==t_harr); VT(s, t_harr);
if (!shEq(s, x)) return err("spread assignment: mismatched shape"); if (!shEq(s, x)) return err("spread assignment: mismatched shape");
usz ia = a(x)->ia; usz ia = a(x)->ia;
B* sp = harr_ptr(s); B* sp = harr_ptr(s);
@ -228,7 +228,7 @@ B v_get(Scope* sc, B s) { // get value representing s, replacing with bi_optOut;
sc->vars[(u32)s.u] = bi_optOut; sc->vars[(u32)s.u] = bi_optOut;
return r; return r;
} else { } else {
assert(isArr(s) && v(s)->type==t_harr); VT(s, t_harr);
usz ia = a(s)->ia; usz ia = a(s)->ia;
B* sp = harr_ptr(s); B* sp = harr_ptr(s);
HArr_p r = m_harrv(ia); HArr_p r = m_harrv(ia);