partially written arrays

This commit is contained in:
dzaima 2021-04-27 19:43:39 +03:00
parent ca3ff89a4d
commit 9003a5df99
10 changed files with 183 additions and 109 deletions

View File

@ -8,7 +8,7 @@ typedef struct FillArr {
B asFill(B x) { // consumes B asFill(B x) { // consumes
if (isArr(x)) { if (isArr(x)) {
HArr_p r = m_harrc(x); HArr_p r = m_harrUc(x);
usz ia = r.c->ia; usz ia = r.c->ia;
BS2B xget = TI(x).get; BS2B xget = TI(x).get;
bool noFill = false; bool noFill = false;
@ -88,7 +88,7 @@ static inline void fillarr_init() {
B m_unit(B x) { B m_unit(B x) {
B xf = asFill(inc(x)); B xf = asFill(inc(x));
if (noFill(xf)) { if (noFill(xf)) {
HArr_p r = m_harrp(1); HArr_p r = m_harrUp(1);
arr_shAllocR(r.b, 0); arr_shAllocR(r.b, 0);
r.a[0] = x; r.a[0] = x;
return r.b; return r.b;

View File

@ -65,7 +65,7 @@ enum Type {
/*17*/ t_hslice, t_i32slice, t_fillslice, t_c32slice, /*17*/ t_hslice, t_i32slice, t_fillslice, t_c32slice,
/*21*/ t_comp, t_block, t_body, t_scope, /*21*/ t_comp, t_block, t_body, t_scope,
/*25*/ t_freed, /*25*/ t_freed, t_harrPartial,
#ifdef RT_PERF #ifdef RT_PERF
/*26*/ t_funPerf, t_md1Perf, t_md2Perf, /*26*/ t_funPerf, t_md1Perf, t_md2Perf,
#endif #endif
@ -187,6 +187,8 @@ B mm_alloc(usz sz, u8 type, u64 tag) {
return b((u64)mm_allocN(sz,type) | tag); return b((u64)mm_allocN(sz,type) | tag);
} }
void gsAdd(B x);
B gsPop();
// some primitive actions // some primitive actions
void dec(B x); void dec(B x);

View File

@ -16,24 +16,57 @@ HArr_p harr_parts(B b) {
} }
HArr_p m_harrv(usz ia) { HArr_p m_harrs(usz ia, usz* ctr) { // writes just ia
B r = m_arr(fsizeof(HArr,a,B,ia), t_harrPartial);
a(r)->ia = ia;
a(r)->sh = ctr;
gsAdd(r);
return harr_parts(r);
}
B harr_fv(HArr_p p) { VT(p.b, t_harrPartial);
p.c->type = t_harr;
p.c->sh = &p.c->ia;
srnk(p.b, 1);
gsPop();
return p.b;
}
B harr_fc(HArr_p p, B x) { VT(p.b, t_harrPartial);
p.c->type = t_harr;
arr_shCopy(p.b, x);
gsPop();
return p.b;
}
B harr_fcd(HArr_p p, B x) { VT(p.b, t_harrPartial);
p.c->type = t_harr;
arr_shCopy(p.b, x);
dec(x);
gsPop();
return p.b;
}
usz* harr_fa(HArr_p p, ur r) { VT(p.b, t_harrPartial);
p.c->type = t_harr;
gsPop();
return arr_shAllocR(p.b, r);
}
HArr_p m_harrUv(usz ia) {
B r = m_arr(fsizeof(HArr,a,B,ia), t_harr); B r = m_arr(fsizeof(HArr,a,B,ia), t_harr);
arr_shVec(r, ia); arr_shVec(r, ia);
return harr_parts(r); return harr_parts(r);
} }
HArr_p m_harrc(B x) { assert(isArr(x)); HArr_p m_harrUc(B x) { assert(isArr(x));
B r = m_arr(fsizeof(HArr,a,B,a(x)->ia), t_harr); B r = m_arr(fsizeof(HArr,a,B,a(x)->ia), t_harr);
arr_shCopy(r, x); arr_shCopy(r, x);
return harr_parts(r); return harr_parts(r);
} }
HArr_p m_harrp(usz ia) { // doesn't write shape/rank HArr_p m_harrUp(usz ia) { // doesn't write shape/rank
B r = m_arr(fsizeof(HArr,a,B,ia), t_harr); B r = m_arr(fsizeof(HArr,a,B,ia), t_harr);
a(r)->ia = ia; a(r)->ia = ia;
return harr_parts(r); return harr_parts(r);
} }
B m_hunit(B x) { B m_hunit(B x) {
HArr_p r = m_harrp(1); HArr_p r = m_harrUp(1);
arr_shAllocR(r.b, 0); arr_shAllocR(r.b, 0);
r.a[0] = x; r.a[0] = x;
return r.b; return r.b;
@ -44,7 +77,7 @@ B* harr_ptr(B x) { VT(x,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);
HArr_p r = m_harrc(x); HArr_p r = m_harrUc(x);
usz ia = r.c->ia; usz ia = r.c->ia;
BS2B xget = TI(x).get; BS2B xget = TI(x).get;
for (usz i = 0; i < ia; i++) r.a[i] = xget(x,i); for (usz i = 0; i < ia; i++) r.a[i] = xget(x,i);
@ -52,30 +85,23 @@ HArr* toHArr(B x) {
return r.c; return r.c;
} }
NOINLINE void harr_pfree(B x, usz am) { // am - item after last written
B* p = harr_ptr(x);
for (usz i = 0; i < am; i++) dec(p[i]);
mm_free(v(x));
}
B m_caB(usz ia, B* a) { B m_caB(usz ia, B* a) {
HArr_p r = m_harrv(ia); HArr_p r = m_harrUv(ia);
for (usz i = 0; i < ia; i++) r.a[i] = a[i]; for (usz i = 0; i < ia; i++) r.a[i] = a[i];
return r.b; return r.b;
} }
B m_caf64(usz sz, f64* a) { B m_caf64(usz sz, f64* a) {
HArr_p r = m_harrv(sz); HArr_p r = m_harrUv(sz);
for (usz i = 0; i < sz; i++) r.a[i] = m_f64(a[i]); for (usz i = 0; i < sz; i++) r.a[i] = m_f64(a[i]);
return r.b; return r.b;
} }
// consumes all // consumes all
B m_v1(B a ) { HArr_p r = m_harrv(1); r.a[0] = a; return r.b; } B m_v1(B a ) { HArr_p r = m_harrUv(1); r.a[0] = a; return r.b; }
B m_v2(B a, B b ) { HArr_p r = m_harrv(2); r.a[0] = a; r.a[1] = b; return r.b; } B m_v2(B a, B b ) { HArr_p r = m_harrUv(2); r.a[0] = a; r.a[1] = b; return r.b; }
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[2] = c; return r.b; } B m_v3(B a, B b, B c ) { HArr_p r = m_harrUv(3); r.a[0] = a; r.a[1] = b; r.a[2] = c; 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; } B m_v4(B a, B b, B c, B d) { HArr_p r = m_harrUv(4); r.a[0] = a; r.a[1] = b; r.a[2] = c; r.a[3] = d; return r.b; }
typedef struct HSlice { typedef struct HSlice {
@ -109,13 +135,47 @@ void harr_visit(B x) {
} }
bool harr_canStore(B x) { return true; } bool harr_canStore(B x) { return true; }
NOINLINE void harr_pfree(B x, usz am) { // am - item after last written
B* p = harr_ptr(x);
for (usz i = 0; i < am; i++) dec(p[i]);
mm_free(v(x));
}
void harrP_free(B x) { assert(v(x)->type==t_harrPartial|v(x)->type==t_freed);
assert(rnk(x)>1? true : a(x)->sh!=&a(x)->ia);
B* p = c(HArr,x)->a;
usz am = *c(HArr,x)->sh;
// printf("partfree %d/%d %p\n", am, a(x)->ia, (void*)x.u);
for (usz i = 0; i < am; i++) dec(p[i]);
}
void harrP_visit(B x) { VT(x, t_harrPartial);
assert(rnk(x)>1? true : a(x)->sh!=&a(x)->ia);
B* p = c(HArr,x)->a;
usz am = *c(HArr,x)->sh;
for (usz i = 0; i < am; i++) mm_visit(p[i]);
}
B harrP_get(B x, usz n) { return err("getting item from t_harrPartial"); }
void harrP_print(B x) {
B* p = c(HArr,x)->a;
usz am = *c(HArr,x)->sh;
usz ia = a(x)->ia;
printf("(partial HArr %d/%d %p %p: ?⥊⟨", am, ia, c(HArr,x)->sh, &a(x)->ia);
for (usz i = 0; i < ia; i++) {
if (i) printf(", ");
if (i>=am) printf("(…)\n");
else print(p[i]);
}
printf("⟩)");
}
static inline void harr_init() { static inline void harr_init() {
ti[t_harr].get = harr_get; ti[t_hslice].get = hslice_get; ti[t_harr].get = harr_get; ti[t_hslice].get = hslice_get; ti[t_harrPartial].get = harrP_get;
ti[t_harr].getU = harr_getU; ti[t_hslice].getU = hslice_getU; ti[t_harr].getU = harr_getU; ti[t_hslice].getU = hslice_getU; ti[t_harrPartial].getU = harrP_get;
ti[t_harr].slice = harr_slice; ti[t_hslice].slice = hslice_slice; 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].free = harr_free; ti[t_hslice].free = slice_free; ti[t_harrPartial].free = harrP_free;
ti[t_harr].visit = harr_visit; ti[t_hslice].visit = slice_visit; ti[t_harr].visit = harr_visit; ti[t_hslice].visit = slice_visit; ti[t_harrPartial].visit = harrP_visit;
ti[t_harr].print = arr_print; ti[t_hslice].print = arr_print; ti[t_harr].print = arr_print; ti[t_hslice].print = arr_print; ti[t_harrPartial].print = harrP_print;
ti[t_harr].isArr = true; ti[t_hslice].isArr = true; ti[t_harr].isArr = true; ti[t_hslice].isArr = true;
ti[t_harr].canStore = harr_canStore; ti[t_harr].canStore = harr_canStore;
} }

View File

@ -128,7 +128,7 @@ int main() {
dec(rtRes); dec(rtRes);
runtimeLen = c(Arr,rtObjRaw)->ia; runtimeLen = c(Arr,rtObjRaw)->ia;
HArr_p runtimeH = m_harrc(rtObjRaw); HArr_p runtimeH = m_harrUc(rtObjRaw);
BS2B rtObjGet = TI(rtObjRaw).get; BS2B rtObjGet = TI(rtObjRaw).get;
rt_sortAsc = rtObjGet(rtObjRaw, 10); gc_add(rt_sortAsc); rt_sortAsc = rtObjGet(rtObjRaw, 10); gc_add(rt_sortAsc);

View File

@ -10,22 +10,22 @@ B tbl_c2(B d, B w, B x) { B f = c(Md1D,d)->f;
usz xia = a(x)->ia; ur xr = rnk(x); usz xia = a(x)->ia; ur xr = rnk(x);
usz ria = wia*xia; ur rr = wr+xr; usz ria = wia*xia; ur rr = wr+xr;
if (rr<xr) thrM("⌜: Required result rank too large"); if (rr<xr) thrM("⌜: Required result rank too large");
HArr_p r = m_harrp(ria);
usz* rsh = arr_shAllocR(r.b, rr);
if (rsh) {
memcpy(rsh , a(w)->sh, wr*sizeof(usz));
memcpy(rsh+wr, a(x)->sh, xr*sizeof(usz));
}
BS2B wgetU = TI(w).getU; BS2B wgetU = TI(w).getU;
BS2B xget = TI(x).get; BS2B xget = TI(x).get;
usz ri = 0; usz ri = 0;
HArr_p r = m_harrs(ria, &ri);
for (usz wi = 0; wi < wia; wi++) { for (usz wi = 0; wi < wia; wi++) {
B cw = wgetU(w,wi); B cw = wgetU(w,wi);
for (usz xi = 0; xi < xia; xi++) { for (usz xi = 0; xi < xia; xi++,ri++) {
r.a[ri++] = c2(f, inc(cw), xget(x,xi)); r.a[ri] = c2(f, inc(cw), xget(x,xi));
} }
} }
usz* rsh = harr_fa(r, rr);
if (rsh) {
memcpy(rsh , a(w)->sh, wr*sizeof(usz));
memcpy(rsh+wr, a(x)->sh, xr*sizeof(usz));
}
dec(w); dec(x); dec(w); dec(x);
return r.b; return r.b;
} }
@ -44,43 +44,47 @@ B scan_c1(B d, B x) { B f = c(Md1D,d)->f;
ur xr = rnk(x); ur xr = rnk(x);
usz ia = a(x)->ia; usz ia = a(x)->ia;
if (ia==0) return x; if (ia==0) return x;
bool reuse = v(x)->type==t_harr && reusable(x); bool reuse = v(x)->type==t_harr && reusable(x);
HArr_p r = reuse? harr_parts(inc(x)) : m_harrc(x); usz i = 0;
HArr_p r = reuse? harr_parts(x) : m_harrs(a(x)->ia, &i);
BS2B xget = reuse? TI(x).getU : TI(x).get; BS2B xget = reuse? TI(x).getU : TI(x).get;
if (xr==1) { if (xr==1) {
r.a[0] = xget(x,0); r.a[i] = xget(x,0); i++;
for (usz i = 1; i < ia; i++) r.a[i] = c2(f, inc(r.a[i-1]), xget(x,i)); for (i = 1; i < ia; i++) r.a[i] = c2(f, inc(r.a[i-1]), xget(x,i));
} else { } else {
usz csz = arr_csz(x); usz csz = arr_csz(x);
for (usz i = 0; i < csz; i++) r.a[i] = xget(x,i); for (; i < csz; i++) r.a[i] = xget(x,i);
for (usz i = csz; i < ia; i++) r.a[i] = c2(f, inc(r.a[i-csz]), xget(x,i)); for (; i < ia; i++) r.a[i] = c2(f, inc(r.a[i-csz]), xget(x,i));
} }
dec(x); return withFill(reuse? x : harr_fcd(r, x), xf);
return withFill(r.b, xf);
} }
B scan_c2(B d, B w, B x) { B f = c(Md1D,d)->f; B scan_c2(B d, B w, B x) { B f = c(Md1D,d)->f;
if (!isArr(x) || rnk(x)==0) thrM("`: 𝕩 cannot have rank 0"); if (!isArr(x) || rnk(x)==0) thrM("`: 𝕩 cannot have rank 0");
ur xr = rnk(x); usz* xsh = a(x)->sh; usz ia = a(x)->ia; ur xr = rnk(x); usz* xsh = a(x)->sh; usz ia = a(x)->ia;
bool reuse = v(x)->type==t_harr && reusable(x);
HArr_p r = reuse? harr_parts(inc(x)) : m_harrc(x); bool reuse = (v(x)->type==t_harr && reusable(x)) | !ia;
usz i = 0;
HArr_p r = reuse? harr_parts(x) : m_harrs(a(x)->ia, &i);
BS2B xget = reuse? TI(x).getU : TI(x).get; BS2B xget = reuse? TI(x).getU : TI(x).get;
if (isArr(w)) { if (isArr(w)) {
ur wr = rnk(w); usz* wsh = a(w)->sh; BS2B wget = TI(w).get; ur wr = rnk(w); usz* wsh = a(w)->sh; BS2B wget = TI(w).get;
if (wr+1 != xr) thrM("`: Shape of 𝕨 must match the cell of 𝕩"); if (wr+1 != xr) thrM("`: Shape of 𝕨 must match the cell of 𝕩");
if (memcmp(wsh, xsh+1, wr)) thrM("`: Shape of 𝕨 must match the cell of 𝕩"); if (memcmp(wsh, xsh+1, wr)) thrM("`: Shape of 𝕨 must match the cell of 𝕩");
if (ia==0) { ptr_dec(r.c); return x; } // only safe as r would have 0 items too if (ia==0) return x;
usz csz = arr_csz(x); usz csz = arr_csz(x);
for (usz i = 0; i < csz; i++) r.a[i] = c2(f, wget(w,i), xget(x,i)); for (; i < csz; i++) r.a[i] = c2(f, wget(w,i), xget(x,i));
for (usz i = csz; i < ia; i++) r.a[i] = c2(f, inc(r.a[i-csz]), xget(x,i)); for (; i < ia; i++) r.a[i] = c2(f, inc(r.a[i-csz]), xget(x,i));
dec(w); dec(w);
} else { } else {
if (xr!=1) thrM("`: Shape of 𝕨 must match the cell of 𝕩"); if (xr!=1) thrM("`: Shape of 𝕨 must match the cell of 𝕩");
if (ia==0) { ptr_dec(r.c); return x; } if (ia==0) return x;
B pr = r.a[0] = c2(f, w, xget(x,0)); B pr = r.a[0] = c2(f, w, xget(x,0)); i++;
for (usz i = 1; i < ia; i++) r.a[i] = pr = c2(f, inc(pr), xget(x,i)); for (; i < ia; i++) r.a[i] = pr = c2(f, inc(pr), xget(x,i));
} }
dec(x); return reuse? x : harr_fcd(r, x);
return r.b;
} }
B fold_c1(B d, B x) { B f = c(Md1D,d)->f; B fold_c1(B d, B x) { B f = c(Md1D,d)->f;

View File

@ -51,7 +51,7 @@ B repeat_replace(B g, B* q) { // doesn't consume
if (isArr(g)) { if (isArr(g)) {
BS2B ggetU = TI(g).getU; BS2B ggetU = TI(g).getU;
usz ia = a(g)->ia; usz ia = a(g)->ia;
HArr_p r = m_harrc(g); HArr_p r = m_harrUc(g);
for (usz i = 0; i < ia; i++) r.a[i] = repeat_replace(ggetU(g,i), q); for (usz i = 0; i < ia; i++) r.a[i] = repeat_replace(ggetU(g,i), q);
return r.b; return r.b;
} else { } else {

View File

@ -35,20 +35,22 @@ B eachd_fn(BBB2B f, B fo, B w, B x) { // consumes w,x; assumes at least one is a
return r.b; return r.b;
} }
HArr_p r = m_harrc(wg? w : x); B bo = wg? w : x;
usz ria = r.c->ia; usz ria = a(bo)->ia;
if (wr==xr) for(usz i = 0; i < ria; i++) r.a[i] = f(fo, wget(w,i), xget(x,i)); usz ri = 0;
else if (wr==0) { B c=wget(w, 0); for(usz i = 0; i < ria; i++) r.a[i] = f(fo, inc(c), xget(x,i)); dec(c); } HArr_p r = m_harrs(ria, &ri);
else if (xr==0) { B c=xget(x, 0); for(usz i = 0; i < ria; i++) r.a[i] = f(fo, wget(w,i), inc(c)); dec(c); } if (wr==xr) for(; ri < ria; ri++) r.a[ri] = f(fo, wget(w,ri), xget(x,ri));
else if (wr==0) { B c=wget(w, 0); for(; ri < ria; ri++) r.a[ri] = f(fo, inc(c) , xget(x,ri)); dec(c); }
else if (xr==0) { B c=xget(x, 0); for(; ri < ria; ri++) r.a[ri] = f(fo, wget(w,ri), inc(c) ); dec(c); }
else if (ria>0) { else if (ria>0) {
usz min = wg? a(x)->ia : a(w)->ia; usz min = wg? a(x)->ia : a(w)->ia;
usz ext = ria / min; usz ext = ria / min;
usz k = 0; if (wg) for (usz i = 0; i < min; i++) { B c=xget(x,i); for (usz j = 0; j < ext; j++,ri++) r.a[ri] = f(fo, wget(w,ri), inc(c)); }
if (wg) for (usz i = 0; i < min; i++) { B c=xget(x,i); for (usz j = 0; j < ext; j++) { r.a[k] = f(fo, wget(w,k), inc(c)); k++; } } else for (usz i = 0; i < min; i++) { B c=wget(w,i); for (usz j = 0; j < ext; j++,ri++) r.a[ri] = f(fo, inc(c), xget(x,ri)); }
else for (usz i = 0; i < min; i++) { B c=wget(w,i); for (usz j = 0; j < ext; j++) { r.a[k] = f(fo, inc(c), xget(x,k)); k++; } }
} }
B rb = harr_fc(r, bo);
dec(w); dec(x); dec(w); dec(x);
return r.b; return rb;
} }
B eachm_fn(BB2B f, B fo, B x) { // consumes x; x must be array B eachm_fn(BB2B f, B fo, B x) { // consumes x; x must be array
usz ia = a(x)->ia; usz ia = a(x)->ia;
@ -66,11 +68,10 @@ B eachm_fn(BB2B f, B fo, B x) { // consumes x; x must be array
for (; i < ia; i++) xp[i] = f(fo, xp[i]); for (; i < ia; i++) xp[i] = f(fo, xp[i]);
return x; return x;
} else { } else {
HArr_p rp = m_harrc(x); rH = m_harrs(ia, &i);
rp.a[i++] = cr; rH.a[i++] = cr;
for (; i < ia; i++) rp.a[i] = f(fo, inc(xp[i])); for (; i < ia; i++) rH.a[i] = f(fo, inc(xp[i]));
dec(x); return harr_fcd(rH, x);
return rp.b;
} }
} else if (v(x)->type==t_i32arr) { } else if (v(x)->type==t_i32arr) {
i32* xp = i32arr_ptr(x); i32* xp = i32arr_ptr(x);
@ -80,7 +81,7 @@ B eachm_fn(BB2B f, B fo, B x) { // consumes x; x must be array
for (; i < ia; i++) { for (; i < ia; i++) {
cr = f(fo, m_i32(xp[i])); cr = f(fo, m_i32(xp[i]));
if (!q_i32(cr)) { if (!q_i32(cr)) {
rH = m_harrc(x); rH = m_harrs(ia, &i);
for (usz j = 0; j < i; j++) rH.a[j] = m_i32(rp[j]); for (usz j = 0; j < i; j++) rH.a[j] = m_i32(rp[j]);
if (!reuse) dec(r); if (!reuse) dec(r);
goto fallback; goto fallback;
@ -98,30 +99,29 @@ B eachm_fn(BB2B f, B fo, B x) { // consumes x; x must be array
for (; i < ia; i++) xp[i] = f(fo, xp[i]); for (; i < ia; i++) xp[i] = f(fo, xp[i]);
return x; return x;
} else { } else {
HArr_p rp = m_harrc(x); HArr_p rp = m_harrs(ia, &i);
rp.a[i++] = cr; rp.a[i++] = cr;
for (; i < ia; i++) rp.a[i] = f(fo, inc(xp[i])); for (; i < ia; i++) rp.a[i] = f(fo, inc(xp[i]));
dec(x); return harr_fcd(rp, x);
return rp.b;
} }
} else } else
rH = m_harrc(x); rH = m_harrs(ia, &i);
} else } else
rH = m_harrc(x); rH = m_harrs(ia, &i);
fallback: fallback:
rH.a[i++] = cr; rH.a[i++] = cr;
for (; i < ia; i++) rH.a[i] = f(fo, xget(x,i)); for (; i < ia; i++) rH.a[i] = f(fo, xget(x,i));
dec(x); return harr_fcd(rH, x);
return rH.b;
} }
B eachm(B f, B x) { // complete F¨ x B eachm(B f, B x) { // complete F¨ x
if (!isArr(x)) return m_hunit(c1(f, x)); if (!isArr(x)) return m_hunit(c1(f, x));
if (isFun(f)) return eachm_fn(c(Fun,f)->c1, f, x); if (isFun(f)) return eachm_fn(c(Fun,f)->c1, f, x);
if (isMd(f)) if (!isArr(x) || a(x)->ia) { decR(x); thrM("Calling a modifier"); } if (isMd(f)) if (!isArr(x) || a(x)->ia) { decR(x); thrM("Calling a modifier"); }
HArr_p r = m_harrc(x); usz ia = a(x)->ia;
for(usz i = 0; i < r.c->ia; i++) r.a[i] = inc(f);
dec(x); dec(x);
HArr_p r = m_harrUv(ia);
for(usz i = 0; i < ia; i++) r.a[i] = inc(f);
return r.b; return r.b;
} }
@ -134,7 +134,7 @@ B eachd(B f, B w, B x) { // complete w F¨ x
} }
if (isMd(f)) if ((isArr(w)&&a(w)->ia) || (isArr(x)&&a(x)->ia)) { decR(x); thrM("Calling a modifier"); } // case where both are scalars has already been taken care of if (isMd(f)) if ((isArr(w)&&a(w)->ia) || (isArr(x)&&a(x)->ia)) { decR(x); thrM("Calling a modifier"); } // case where both are scalars has already been taken care of
HArr_p r = m_harrc(!isArr(w)? x : rnk(w)>rnk(x)? w : x); HArr_p r = m_harrUc(!isArr(w)? x : rnk(w)>rnk(x)? w : x);
for(usz i = 0; i < r.c->ia; i++) r.a[i] = inc(f); for(usz i = 0; i < r.c->ia; i++) r.a[i] = inc(f);
dec(w); dec(x); dec(w); dec(x);
return r.b; return r.b;
@ -194,7 +194,7 @@ B ud_c1(B t, B x) {
for (usz i = 0; i < xu; i++) pr[i] = i; for (usz i = 0; i < xu; i++) pr[i] = i;
return r; return r;
} }
HArr_p r = m_harrv(xu); // TODO f64arr HArr_p r = m_harrUv(xu); // TODO f64arr
for (usz i = 0; i < xu; i++) r.a[i] = m_f64(i); for (usz i = 0; i < xu; i++) r.a[i] = m_f64(i);
return r.b; return r.b;
} }
@ -226,7 +226,7 @@ B fne_c1(B t, B x) {
ur xr = rnk(x); ur xr = rnk(x);
usz* sh = a(x)->sh; usz* sh = a(x)->sh;
for (i32 i = 0; i < xr; i++) if (sh[i]>I32_MAX) { for (i32 i = 0; i < xr; i++) if (sh[i]>I32_MAX) {
HArr_p r = m_harrv(xr); HArr_p r = m_harrUv(xr);
for (i32 j = 0; j < xr; j++) r.a[j] = m_f64(sh[j]); for (i32 j = 0; j < xr; j++) r.a[j] = m_f64(sh[j]);
dec(x); dec(x);
return r.b; return r.b;
@ -297,7 +297,7 @@ B select_c2(B t, B w, B x) {
usz wia = a(w)->ia; usz wia = a(w)->ia;
usz xia = a(x)->ia; usz xia = a(x)->ia;
B xf = getFill(inc(x)); B xf = getFill(inc(x));
HArr_p r = m_harrc(w); HArr_p r = m_harrUc(w);
BS2B wgetU = TI(w).getU; BS2B wgetU = TI(w).getU;
BS2B xget = TI(x).get; BS2B xget = TI(x).get;
for (usz i = 0; i < wia; i++) { for (usz i = 0; i < wia; i++) {
@ -341,13 +341,13 @@ B slash_c1(B t, B x) {
dec(x); dec(x);
return r; return r;
} }
HArr_p r = m_harrv(s); HArr_p r = m_harrs(s, &ri);
for (usz i = 0; i < xia; i++) { for (usz i = 0; i < xia; i++) {
usz c = o2s(xgetU(x, i)); usz c = o2s(xgetU(x, i));
for (usz j = 0; j < c; j++) r.a[ri++] = m_i32(i); for (usz j = 0; j < c; j++) r.a[ri++] = m_i32(i);
} }
dec(x); dec(x);
return withFill(r.b,m_f64(0)); return withFill(harr_fv(r),m_f64(0));
} }
B slash_c2(B t, B w, B x) { B slash_c2(B t, B w, B x) {
if (isArr(w) && isArr(x) && rnk(w)==1 && rnk(x)==1 && depth(w)==1) { if (isArr(w) && isArr(x) && rnk(w)==1 && rnk(x)==1 && depth(w)==1) {
@ -356,10 +356,10 @@ B slash_c2(B t, B w, B x) {
B xf = getFill(inc(x)); B xf = getFill(inc(x));
if (wia!=xia) thrM("/: Lengths of components of 𝕨 must match 𝕩"); if (wia!=xia) thrM("/: Lengths of components of 𝕨 must match 𝕩");
usz ria = isum(w); usz ria = isum(w);
HArr_p r = m_harrv(ria); usz ri = 0;
HArr_p r = m_harrs(ria, &ri);
BS2B wgetU = TI(w).getU; BS2B wgetU = TI(w).getU;
BS2B xgetU = TI(x).getU; BS2B xgetU = TI(x).getU;
usz ri = 0;
for (usz i = 0; i < wia; i++) { for (usz i = 0; i < wia; i++) {
B cw = wgetU(w, i); B cw = wgetU(w, i);
if (isNum(cw)) { if (isNum(cw)) {
@ -373,7 +373,7 @@ B slash_c2(B t, B w, B x) {
} else { dec(cw); goto base; } } else { dec(cw); goto base; }
} }
dec(w); dec(x); dec(w); dec(x);
return withFill(r.b,xf); return withFill(harr_fv(r), xf);
} }
base: base:
return c2(rt_slash, w, x); return c2(rt_slash, w, x);

View File

@ -137,7 +137,7 @@ usz arr_csz(B x) {
B VALIDATE(B x) { B VALIDATE(B x) {
if (!isVal(x)) return x; if (!isVal(x)) return x;
VALIDATEP(v(x)); VALIDATEP(v(x));
if(isArr(x)!=TI(x).isArr && v(x)->type!=t_freed) { if(isArr(x)!=TI(x).isArr && v(x)->type!=t_freed && v(x)->type!=t_harrPartial) {
printf("wat %d %p\n", v(x)->type, (void*)x.u); printf("wat %d %p\n", v(x)->type, (void*)x.u);
print(x); print(x);
err("\nk"); err("\nk");

View File

@ -47,44 +47,44 @@ B fill_c2(B t, B w, B x) { // TODO not set fill for typed arrays
return x; return x;
} }
B grLen_c1(B t, B x) { B grLen_c1(B t, B x) { // assumes valid arguments
i64 ria = -1; i64 ria = -1;
usz ia = a(x)->ia; usz ia = a(x)->ia;
BS2B xgetU = TI(x).getU; BS2B xgetU = TI(x).getU;
for (usz i = 0; i < ia; i++) { for (usz i = 0; i < ia; i++) {
i64 c = o2i64(xgetU(x, i)); i64 c = o2i64u(xgetU(x, i));
if (c>ria) ria = c; if (c>ria) ria = c;
} }
ria++; ria++;
HArr_p r = m_harrv(ria); HArr_p r = m_harrUv(ria);
for (usz i = 0; i < ria; i++) r.a[i] = m_f64(0); for (usz i = 0; i < ria; i++) r.a[i] = m_f64(0);
for (usz i = 0; i < ia; i++) { for (usz i = 0; i < ia; i++) {
i64 n = o2i64(xgetU(x, i)); i64 n = o2i64u(xgetU(x, i));
if (n>=0) r.a[n].f++; if (n>=0) r.a[n].f++;
} }
dec(x); dec(x);
return r.b; return r.b;
} }
B grLen_c2(B t, B w, B x) { B grLen_c2(B t, B w, B x) { // assumes valid arguments
i64 ria = o2i64(w)-1; i64 ria = o2i64u(w)-1;
usz ia = a(x)->ia; usz ia = a(x)->ia;
BS2B xgetU = TI(x).getU; BS2B xgetU = TI(x).getU;
for (usz i = 0; i < ia; i++) { for (usz i = 0; i < ia; i++) {
i64 c = o2i64(xgetU(x, i)); i64 c = o2i64u(xgetU(x, i));
if (c>ria) ria = c; if (c>ria) ria = c;
} }
ria++; ria++;
HArr_p r = m_harrv(ria); HArr_p r = m_harrUv(ria);
for (usz i = 0; i < ria; i++) r.a[i] = m_f64(0); for (usz i = 0; i < ria; i++) r.a[i] = m_f64(0);
for (usz i = 0; i < ia; i++) { for (usz i = 0; i < ia; i++) {
i64 n = o2i64(xgetU(x, i)); i64 n = o2i64u(xgetU(x, i));
if (n>=0) r.a[n].f++; if (n>=0) r.a[n].f++;
} }
dec(x); dec(x);
return r.b; return r.b;
} }
B grOrd_c2(B t, B w, B x) { B grOrd_c2(B t, B w, B x) { // assumes valid arguments
usz wia = a(w)->ia; usz wia = a(w)->ia;
usz xia = a(x)->ia; usz xia = a(x)->ia;
if (wia==0) { dec(w); dec(x); return c1(bi_ud, m_i32(0)); } if (wia==0) { dec(w); dec(x); return c1(bi_ud, m_i32(0)); }
@ -93,9 +93,9 @@ B grOrd_c2(B t, B w, B x) {
BS2B xgetU = TI(x).getU; BS2B xgetU = TI(x).getU;
usz tmp[wia]; usz tmp[wia];
tmp[0] = 0; tmp[0] = 0;
for (int i = 1; i < wia; i++) tmp[i] = tmp[i-1]+o2s(wgetU(w,i-1)); for (int i = 1; i < wia; i++) tmp[i] = tmp[i-1]+o2su(wgetU(w,i-1));
usz ria = tmp[wia-1]+o2s(wgetU(w,wia-1)); usz ria = tmp[wia-1]+o2su(wgetU(w,wia-1));
HArr_p r = m_harrv(ria); HArr_p r = m_harrUv(ria);
for (usz i = 0; i < xia; i++) { for (usz i = 0; i < xia; i++) {
i64 c = o2i64(xgetU(x,i)); i64 c = o2i64(xgetU(x,i));
if (c>=0) r.a[tmp[c]++] = m_usz(i); if (c>=0) r.a[tmp[c]++] = m_usz(i);
@ -144,17 +144,17 @@ static inline void sysfn_init() { bm(type) bm(decp) bm(primInd) bm(glyph) ba(fil
B sys_c1(B t, B x) { B sys_c1(B t, B x) {
assert(isArr(x)); assert(isArr(x));
HArr_p r = m_harrc(x); usz i = 0;
HArr_p r = m_harrs(a(x)->ia, &i);
BS2B xgetU = TI(x).getU; BS2B xgetU = TI(x).getU;
for (usz i = 0; i < a(x)->ia; i++) { for (; i < a(x)->ia; i++) {
B c = xgetU(x,i); B c = xgetU(x,i);
if (eqStr(c, U"internal")) r.a[i] = inc(bi_internal); if (eqStr(c, U"internal")) r.a[i] = inc(bi_internal);
else if (eqStr(c, U"eq")) r.a[i] = inc(bi_feq); else if (eqStr(c, U"eq")) r.a[i] = inc(bi_feq);
else if (eqStr(c, U"decompose")) r.a[i] = inc(bi_decp); else if (eqStr(c, U"decompose")) r.a[i] = inc(bi_decp);
else if (eqStr(c, U"primind")) r.a[i] = inc(bi_primInd); else if (eqStr(c, U"primind")) r.a[i] = inc(bi_primInd);
else if (eqStr(c, U"type")) r.a[i] = inc(bi_type); else if (eqStr(c, U"type")) r.a[i] = inc(bi_type);
else err("Unknown system function"); else thrM("Unknown system function");
} }
dec(x); return harr_fcd(r, x);
return r.b;
} }

View File

@ -239,7 +239,7 @@ B v_get(Scope* sc, B s) { // get value representing s, replacing with bi_optOut;
VT(s, 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_harrUv(ia);
for (u64 i = 0; i < ia; i++) r.a[i] = v_get(sc, sp[i]); for (u64 i = 0; i < ia; i++) r.a[i] = v_get(sc, sp[i]);
return r.b; return r.b;
} }
@ -259,7 +259,7 @@ B* gStack; // points to after end
B* gStackStart; B* gStackStart;
B* gStackEnd; B* gStackEnd;
void allocStack(u64 am) { void gsReserve(u64 am) {
u64 left = gStackEnd-gStack; u64 left = gStackEnd-gStack;
if (am>left) { if (am>left) {
u64 n = gStackEnd-gStackStart + am + 500; u64 n = gStackEnd-gStackStart + am + 500;
@ -269,6 +269,14 @@ void allocStack(u64 am) {
gStackEnd = gStackStart+n; gStackEnd = gStackStart+n;
} }
} }
NOINLINE void gsReserveR(u64 am) { gsReserve(am); }
void gsAdd(B x) {
if (gStack==gStackEnd) gsReserveR(1);
*(gStack++) = x;
}
B gsPop() {
return *--gStack;
}
B evalBC(Body* b, Scope* sc) { // doesn't consume B evalBC(Body* b, Scope* sc) { // doesn't consume
#ifdef DEBUG_VM #ifdef DEBUG_VM
@ -281,7 +289,7 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
B* objs = b->comp->objs->a; B* objs = b->comp->objs->a;
Block** blocks = b->comp->blocks; Block** blocks = b->comp->blocks;
i32* bc = b->bc; i32* bc = b->bc;
allocStack(b->maxStack); gsReserve(b->maxStack);
#define POP (*--gStack) #define POP (*--gStack)
#define P(N) B N=POP; #define P(N) B N=POP;
#define ADD(X) { B tr=X; *(gStack++) = tr; } // if ordering is needed #define ADD(X) { B tr=X; *(gStack++) = tr; } // if ordering is needed
@ -324,7 +332,7 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
} }
case ARRO: case ARRM: { case ARRO: case ARRM: {
i32 sz = *bc++; i32 sz = *bc++;
HArr_p r = m_harrv(sz); HArr_p r = m_harrUv(sz);
for (i32 i = 0; i < sz; i++) r.a[sz-i-1] = POP; for (i32 i = 0; i < sz; i++) r.a[sz-i-1] = POP;
ADD(r.b); ADD(r.b);
break; break;