diff --git a/src/h.h b/src/h.h index 3d1f14b3..eb6aaab9 100644 --- a/src/h.h +++ b/src/h.h @@ -59,8 +59,9 @@ enum Type { /*10*/ t_md1D, t_md2D, t_md2H, /*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 @@ -103,7 +104,7 @@ typedef struct Value { i32 refc; 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 extra; // whatever object-specific stuff. Rank for arrays, id for functions + ur extra; // whatever object-specific stuff. Rank for arrays, id for functions } Value; typedef struct Arr { struct Value; @@ -112,7 +113,8 @@ typedef struct Arr { } Arr; // 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_visit(B x); @@ -122,15 +124,18 @@ void inc(B x); void ptr_dec(void* x); void ptr_inc(void* x); void print(B x); +void arr_print(B x); B m_v1(B a ); B m_v2(B a, B b ); B m_v3(B a, B b, B c ); B m_v4(B a, B b, B c, B d); #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); } 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(); #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; } + +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 B (*BS2B)(B, usz); +typedef B (* BS2B)(B, usz); +typedef B (*BSS2B)(B, usz, usz); typedef B (* B2B)(B); typedef B (* BB2B)(B, B); typedef B (* BBB2B)(B, B, B); @@ -253,16 +269,18 @@ typedef struct TypeInfo { BB2B m1_d; // consume all args BBB2B m2_d; // consume all args B2B decompose; // consumes; must return a HArr + BS2B slice; // consumes; create slice from given starting position; add ia, rank, shape yourself } TypeInfo; TypeInfo ti[Type_MAX]; #define TI(x) (ti[v(x)->type]) 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); } +B get_self(B x, usz n) { return x; } 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_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 bi_nothing, bi_noVar, bi_badHdr, bi_optOut; @@ -274,6 +292,7 @@ void hdr_init() { ti[i].m1_d = def_m1_d; ti[i].m2_d = def_m2_d; ti[i].decompose = def_decompose; + ti[i].slice = def_slice; } bi_nothing = tag(0, TAG_TAG); bi_noVar = tag(1, TAG_TAG); @@ -404,7 +423,6 @@ void arr_print(B x) { } - #ifdef DEBUG B validate(B x) { if (!isVal(x)) return x; diff --git a/src/harr.c b/src/harr.c index ee6c16bd..920428cb 100644 --- a/src/harr.c +++ b/src/harr.c @@ -34,10 +34,7 @@ HArr_p m_harrp(usz ia) { // doesn't write any shape/size info! be careful! -B* harr_ptr(B x) { - assert(v(x)->type==t_harr); - return c(HArr,x)->a; -} +B* harr_ptr(B x) { VT(x,t_harr); return c(HArr,x)->a; } HArr* toHArr(B 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; } +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) { decSh(x); B* p = harr_ptr(x); usz ia = a(x)->ia; 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() { - ti[t_harr].free = harr_free; - ti[t_harr].print = harr_print; - ti[t_harr].get = harr_get; + ti[t_harr].get = harr_get; ti[t_hslice].get = hslice_get; + ti[t_harr].slice = harr_slice; ti[t_hslice].slice = hslice_slice; + ti[t_harr].free = harr_free; ti[t_hslice].free = slice_free; + ti[t_harr].print = arr_print; ti[t_hslice].print = arr_print; } diff --git a/src/i32arr.c b/src/i32arr.c index 47e13a68..b87d4593 100644 --- a/src/i32arr.c +++ b/src/i32arr.c @@ -21,10 +21,7 @@ B m_i32arrp(usz ia) { // doesn't write any shape/size info! be careful! } -i32* i32arr_ptr(B x) { - assert(v(x)->type==t_i32arr); - return c(I32Arr,x)->a; -} +i32* i32arr_ptr(B x) { VT(x, t_i32arr); return c(I32Arr,x)->a; } 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_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() { - ti[t_i32arr].free = i32arr_free; - ti[t_i32arr].print = i32arr_print; - ti[t_i32arr].get = i32arr_get; + ti[t_i32arr].get = i32arr_get; ti[t_i32slice].get = i32slice_get; + ti[t_i32arr].slice = i32arr_slice; ti[t_i32slice].slice = i32slice_slice; + ti[t_i32arr].free = i32arr_free; ti[t_i32slice].free = slice_free; + ti[t_i32arr].print = arr_print; ti[t_i32slice].print = arr_print; } diff --git a/src/sfns.c b/src/sfns.c index f294cca3..e758943d 100644 --- a/src/sfns.c +++ b/src/sfns.c @@ -8,11 +8,9 @@ B shape_c1(B t, B x) { arr_shVec(x, ia); return x; } - HArr_p r = m_harrv(ia); - BS2B xget = TI(x).get; - for (i32 i = 0; i < ia; i++) r.a[i] = xget(x,i); - dec(x); - return r.b; + B r = TI(x).slice(x, 0); + arr_shVec(r, ia); + return r; } else return err("reshaping non-array"); } 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; usz nia = a(x)->ia; B r; - bool reuse = reusable(x); - if (reuse) { - 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; - } + if (reusable(x)) { r = x; decSh(x); } + else r = TI(x).slice(x, 0); usz* sh = arr_shAlloc(r, nia, nr); if (sh) for (i32 i = 0; i < nr; i++) sh[i] = o2i(wget(w,i)); - if (!reuse) dec(x); dec(w); return r; } else return err("reshaping non-array"); diff --git a/src/vm.c b/src/vm.c index a78f49e1..de2f2d28 100644 --- a/src/vm.c +++ b/src/vm.c @@ -8,7 +8,7 @@ enum { ARRM = 4, // N; create a mutable vector of top N items FN1C = 5, // monadic function call ⟨…,x,f ⟩ → F x FN2C = 6, // dyadic function call ⟨…,x,f,w⟩ → w F x - OP1D = 7, // derive 1-modifier to function; ⟨…, _m,f⟩ → (f _m) + OP1D = 7, // derive 1-modifier to function; ⟨…, _m,f⟩ → (f _m) OP2D = 8, // derive 2-modifier to function; ⟨…,g,_m,f⟩ → (f _m_ g) TR2D = 9, // derive 2-train aka atop; ⟨…, g,f⟩ → (f g) TR3D = 10, // derive 3-train aka fork; ⟨…,h,g,f⟩ → (f g h) @@ -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; } else { - assert(isArr(s) && v(s)->type==t_harr); + VT(s, t_harr); if (!shEq(s, x)) return err("spread assignment: mismatched shape"); usz ia = a(x)->ia; 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; return r; } else { - assert(isArr(s) && v(s)->type==t_harr); + VT(s, t_harr); usz ia = a(s)->ia; B* sp = harr_ptr(s); HArr_p r = m_harrv(ia);