From 1db0527c5ae2d2f8eef1ee1f2c07e36d55dce4d1 Mon Sep 17 00:00:00 2001 From: dzaima Date: Fri, 9 Apr 2021 12:59:54 +0300 Subject: [PATCH] =?UTF-8?q?in-place=20i32arr=20monadic=20=E2=8C=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- primSafe.bqn | 6 +++++- src/c32arr.c | 2 ++ src/fillarr.c | 3 +++ src/h.h | 24 +++++++++++++++++------- src/harr.c | 2 ++ src/i32arr.c | 2 ++ src/main.c | 2 +- src/md1.c | 45 +++++++++++++++++++++++++++++++++++---------- 8 files changed, 67 insertions(+), 19 deletions(-) diff --git a/primSafe.bqn b/primSafe.bqn index 78092c7c..f2277d84 100755 --- a/primSafe.bqn +++ b/primSafe.bqn @@ -1,7 +1,11 @@ #! /usr/bin/env dbqn "usage: ./primSafe.bqn path/to/mlochbaum/BQN | ./BQN (while compiled for REPL mode)"!1≤≠•args path←⊑•args +case←"prim" +{case↩⊑𝕩}⍟(×≠) 1↓•args +case∾↩".bqn" -('%'⊸∊∨ '#'= ·⊑ ∾⟜"#")◶•Out‿@¨•FLines path∾"/test/cases/prim.bqn" + +('%'⊸∊∨ '#'= ·⊑ ∾⟜"#")◶•Out‿@¨•FLines path∾"/test/cases/"∾case •Out """finished""" •Out "" \ No newline at end of file diff --git a/src/c32arr.c b/src/c32arr.c index 54b31d39..eeaec18f 100644 --- a/src/c32arr.c +++ b/src/c32arr.c @@ -53,10 +53,12 @@ B c32slice_slice(B x, usz s) { B r = m_c32slice(inc(c(C32Slice,x)->p), c(C32Slic B c32arr_get (B x, usz n) { VT(x,t_c32arr ); return m_c32(c(C32Arr ,x)->a[n]); } B c32slice_get(B x, usz n) { VT(x,t_c32slice); return m_c32(c(C32Slice,x)->a[n]); } void c32arr_free(B x) { decSh(x); } +bool c32arr_canStore(B x) { return isC32(x); } void c32arr_init() { ti[t_c32arr].get = c32arr_get; ti[t_c32slice].get = c32slice_get; ti[t_c32arr].slice = c32arr_slice; ti[t_c32slice].slice = c32slice_slice; ti[t_c32arr].free = c32arr_free; ti[t_c32slice].free = slice_free; ti[t_c32arr].print = arr_print; ti[t_c32slice].print = arr_print; + ti[t_c32arr].canStore = c32arr_canStore; } diff --git a/src/fillarr.c b/src/fillarr.c index 9057911d..aeeba4d6 100644 --- a/src/fillarr.c +++ b/src/fillarr.c @@ -54,6 +54,7 @@ B m_fillslice(B p, B* ptr) { return tag(r, ARR_TAG); } +B* fillarr_ptr(B x) { VT(x,t_fillarr); return c(FillArr,x)->a; } B fillarr_slice (B x, usz s) {return m_fillslice(x , c(FillArr ,x)->a+s); } B fillslice_slice(B x, usz s) { B r = m_fillslice(inc(c(FillSlice,x)->p), c(FillSlice,x)->a+s); dec(x); return r; } @@ -66,10 +67,12 @@ void fillarr_free(B x) { usz ia = a(x)->ia; for (usz i = 0; i < ia; i++) dec(p[i]); } +bool fillarr_canStore(B x) { return true; } void fillarr_init() { ti[t_fillarr].get = fillarr_get; ti[t_fillslice].get = fillslice_get; ti[t_fillarr].slice = fillarr_slice; ti[t_fillslice].slice = fillslice_slice; ti[t_fillarr].free = fillarr_free; ti[t_fillslice].free = slice_free; ti[t_fillarr].print = arr_print; ti[t_fillslice].print = arr_print; + ti[t_fillarr].canStore = fillarr_canStore; } diff --git a/src/h.h b/src/h.h index 0bd78a74..72703aee 100644 --- a/src/h.h +++ b/src/h.h @@ -24,6 +24,11 @@ #define usz u32 #define ur u8 +#define CTR_FOR(F) +#define CTR_DEF(N) u64 N; +#define CTR_PRINT(N) printf(#N ": %lu\n", N); +CTR_FOR(CTR_DEF) + #ifdef DEBUG #include #define VALIDATE(x) validate(x) // preferred validating level @@ -253,7 +258,8 @@ B m_usz(usz n) { return n==(i32)n? m_i32(n) : m_f64(n); } i32 o2i (B x) { if ((i32)x.f!=x.f) err("o2i"": expected integer"); return (i32)x.f; } usz o2s (B x) { if ((usz)x.f!=x.f) err("o2s"": expected integer"); return (usz)x.f; } i64 o2i64(B x) { if ((i64)x.f!=x.f) err("o2i64: expected integer"); return (i64)x.f; } - +i32 o2iu (B x) { return isI32(x)? (i32)(u32)x.u : (i32)x.f; } +bool q_i32(B x) { return isI32(x) || isF64(x)&(x.f==(i32)x.f); } typedef struct Slice { @@ -265,7 +271,7 @@ void slice_print(B x) { arr_print(x); } -typedef void (*B2V)(B); +typedef void (*B2v)(B); typedef B (* BS2B)(B, usz); typedef B (*BSS2B)(B, usz, usz); typedef B (* B2B)(B); @@ -273,16 +279,19 @@ typedef B (* BB2B)(B, B); typedef B (* BBB2B)(B, B, B); typedef B (* BBBB2B)(B, B, B, B); typedef B (*BBBBB2B)(B, B, B, B, B); +typedef bool (*B2b)(B); typedef struct TypeInfo { - B2V free; // expects refc==0 - B2V visit; // for GC when that comes around - B2V print; // doesn't consume + B2v free; // expects refc==0 BS2B get; // increments result, doesn't consume arg BB2B m1_d; // consume all args; (m, f) BBB2B m2_d; // consume all args; (m, f, g) - B2B decompose; // consumes; must return a HArr BS2B slice; // consumes; create slice from given starting position; add ia, rank, shape yourself + B2b canStore; // doesn't consume + + B2v print; // doesn't consume + B2v visit; // for GC when that comes around + B2B decompose; // consumes; must return a HArr } TypeInfo; TypeInfo ti[Type_MAX]; #define TI(x) (ti[v(x)->type]) @@ -295,7 +304,7 @@ 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); } - +bool def_canStore(B x) { return false; } B bi_nothing, bi_noVar, bi_badHdr, bi_optOut, bi_noFill; void hdr_init() { for (i32 i = 0; i < Type_MAX; ++i) { @@ -306,6 +315,7 @@ void hdr_init() { ti[i].m2_d = def_m2_d; ti[i].decompose = def_decompose; ti[i].slice = def_slice; + ti[i].canStore = def_canStore; } bi_nothing = tag(0, TAG_TAG); bi_noVar = tag(1, TAG_TAG); diff --git a/src/harr.c b/src/harr.c index 4bba4e52..08548c4d 100644 --- a/src/harr.c +++ b/src/harr.c @@ -88,10 +88,12 @@ void harr_free(B x) { usz ia = a(x)->ia; for (usz i = 0; i < ia; i++) dec(p[i]); } +bool harr_canStore(B x) { return true; } void harr_init() { 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; + ti[t_harr].canStore = harr_canStore; } diff --git a/src/i32arr.c b/src/i32arr.c index 8bbdb9bc..9e60bce9 100644 --- a/src/i32arr.c +++ b/src/i32arr.c @@ -61,10 +61,12 @@ B i32slice_slice(B x, usz s) { B r = m_i32slice(inc(c(I32Slice,x)->p), c(I32Slic B i32arr_get (B x, usz n) { VT(x,t_i32arr ); return m_i32(c(I32Arr ,x)->a[n]); } B i32slice_get(B x, usz n) { VT(x,t_i32slice); return m_i32(c(I32Slice,x)->a[n]); } void i32arr_free(B x) { decSh(x); } +bool i32arr_canStore(B x) { return q_i32(x); } void i32arr_init() { 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; + ti[t_i32arr].canStore = i32arr_canStore; } diff --git a/src/main.c b/src/main.c index 0b07f288..9ee080d2 100644 --- a/src/main.c +++ b/src/main.c @@ -172,7 +172,7 @@ int main() { dec(rtRes); dec(comp); - + CTR_FOR(CTR_PRINT) // printf("done\n");fflush(stdout); while(1); #ifdef ALLOC_STAT printf("total ever allocated: %lu\n", talloc); diff --git a/src/md1.c b/src/md1.c index 904e5d6b..4cf2a755 100644 --- a/src/md1.c +++ b/src/md1.c @@ -3,16 +3,42 @@ B tbl_c1(B d, B x) { B f = c(Md1D,d)->f; if (!isArr(x)) return err("⌜: argument was atom"); usz ia = a(x)->ia; - if (v(x)->type==t_harr && reusable(x)) { - B* p = harr_ptr(x); - for (usz i = 0; i < ia; i++) p[i] = c1(f, p[i]); - return x; - } - HArr_p r = m_harrc(x); + if (ia==0) return x; BS2B xget = TI(x).get; - for (usz i = 0; i < ia; i++) r.a[i] = c1(f, xget(x,i)); + usz i = 0; + B cr = c1(f, xget(x,0)); + HArr_p rH; + if (reusable(x) && TI(x).canStore(cr)) { + if (v(x)->type==t_harr) { + B* p = harr_ptr(x); + p[i++] = cr; + for (; i < ia; i++) p[i] = c1(f, p[i]); + return x; + } else if (v(x)->type==t_i32arr) { + i32* p = i32arr_ptr(x); + p[i++] = o2iu(cr); + for (; i < ia; i++) { + cr = c1(f, m_i32(p[i])); + if (!q_i32(cr)) { + rH = m_harrc(x); + for (usz j = 0; j < i; j++) rH.a[j] = m_i32(p[j]); + goto fallback; + } + p[i] = o2iu(cr); + } + return x; + } else if (v(x)->type==t_fillarr) { + B* p = fillarr_ptr(x); + p[i++] = cr; + for (; i < ia; i++) p[i] = c1(f, p[i]); + return x; + } else rH = m_harrc(x); + } else rH = m_harrc(x); + fallback: + rH.a[i++] = cr; + for (; i < ia; i++) rH.a[i] = c1(f, xget(x,i)); dec(x); - return r.b; + return rH.b; } B tbl_c2(B d, B w, B x) { B f = c(Md1D,d)->f; if (isArr(w) & isArr(x)) { @@ -64,9 +90,8 @@ B scan_c1(B d, 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)) return err("`: 𝕩 cannot be a scalar"); - ur xr = rnk(x); usz* xsh = a(x)->sh; BS2B xget = TI(x).get; + ur xr = rnk(x); usz* xsh = a(x)->sh; BS2B xget = TI(x).get; usz ia = a(x)->ia; HArr_p r = (v(x)->type==t_harr && reusable(x))? harr_parts(inc(x)) : m_harrc(x); - usz ia = r.c->ia; if (isArr(w)) { ur wr = rnk(w); usz* wsh = a(w)->sh; BS2B wget = TI(w).get; if (xr==0) return err("`: 𝕩 cannot be a scalar");