slices for ⥊
This commit is contained in:
parent
0eb8b37236
commit
f534115d1c
32
src/h.h
32
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;
|
||||
|
||||
28
src/harr.c
28
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;
|
||||
}
|
||||
|
||||
25
src/i32arr.c
25
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;
|
||||
}
|
||||
|
||||
21
src/sfns.c
21
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");
|
||||
|
||||
6
src/vm.c
6
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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user