diff --git a/src/c32arr.c b/src/c32arr.c index 3aa5c08d..403576ff 100644 --- a/src/c32arr.c +++ b/src/c32arr.c @@ -12,7 +12,7 @@ B m_c32arrv(usz ia) { return r; } B m_c32arrc(B x) { assert(isArr(x)); - B r = m_arr(fsizeof(C32Arr,a,B,a(x)->ia), t_c32arr); + B r = m_arr(fsizeof(C32Arr,a,u32,a(x)->ia), t_c32arr); arr_shCopy(r, x); return r; } diff --git a/src/f64arr.c b/src/f64arr.c new file mode 100644 index 00000000..d8c6db6f --- /dev/null +++ b/src/f64arr.c @@ -0,0 +1,66 @@ +#include "h.h" + +typedef struct F64Arr { + struct Arr; + f64 a[]; +} F64Arr; + + +B m_f64arrv(usz ia) { + B r = m_arr(fsizeof(F64Arr,a,f64,ia), t_f64arr); + arr_shVec(r, ia); + return r; +} +B m_f64arrc(B x) { assert(isArr(x)); + B r = m_arr(fsizeof(F64Arr,a,f64,a(x)->ia), t_f64arr); + arr_shCopy(r, x); + return r; +} +B m_f64arrp(usz ia) { // doesn't write shape/rank + B r = m_arr(fsizeof(F64Arr,a,f64,ia), t_f64arr); + a(r)->ia = ia; + return r; +} + + +f64* f64arr_ptr(B x) { VT(x, t_f64arr); return c(F64Arr,x)->a; } + +B m_caf64(usz sz, f64* a) { + B r = m_f64arrv(sz); f64* rp = f64arr_ptr(r); + for (usz i = 0; i < sz; i++) rp[i] = a[i]; + return r; +} + +typedef struct F64Slice { + struct Slice; + f64* a; +} F64Slice; +B m_f64slice(B p, f64* ptr) { + F64Slice* r = mm_allocN(sizeof(F64Slice), t_f64slice); + r->p = p; + r->a = ptr; + return tag(r, ARR_TAG); +} + +B f64arr_slice (B x, usz s) {return m_f64slice(x , c(F64Arr ,x)->a+s); } +B f64slice_slice(B x, usz s) { B r = m_f64slice(inc(c(Slice,x)->p), c(F64Slice,x)->a+s); dec(x); return r; } + + +B f64arr_get (B x, usz n) { VT(x,t_f64arr ); return m_f64(c(F64Arr ,x)->a[n]); } +B f64slice_get(B x, usz n) { VT(x,t_f64slice); return m_f64(c(F64Slice,x)->a[n]); } +f64* f64arr_f64p(B x) { return c(F64Arr ,x)->a; } +f64* f64slice_f64p(B x) { return c(F64Slice,x)->a; } +void f64arr_free(B x) { decSh(x); } +bool f64arr_canStore(B x) { return q_f64(x); } + +static inline void f64arr_init() { + ti[t_f64arr].get = f64arr_get; ti[t_f64slice].get = f64slice_get; + ti[t_f64arr].getU = f64arr_get; ti[t_f64slice].getU = f64slice_get; + ti[t_f64arr].slice = f64arr_slice; ti[t_f64slice].slice = f64slice_slice; + ti[t_f64arr].free = f64arr_free; ti[t_f64slice].free = slice_free; + ti[t_f64arr].visit = do_nothing; ti[t_f64slice].visit = slice_visit; + ti[t_f64arr].print = arr_print; ti[t_f64slice].print = arr_print; + ti[t_f64arr].isArr = true; ti[t_f64slice].isArr = true; + ti[t_f64arr].arrD1 = true; ti[t_f64slice].arrD1 = true; + ti[t_f64arr].canStore = f64arr_canStore; +} diff --git a/src/h.h b/src/h.h index 8169c2e7..513737f1 100644 --- a/src/h.h +++ b/src/h.h @@ -61,13 +61,13 @@ enum Type { /* 8*/ t_fork, t_atop, /*10*/ t_md1D, t_md2D, t_md2H, - /*13*/ t_harr , t_i32arr , t_fillarr , t_c32arr , - /*17*/ t_hslice, t_i32slice, t_fillslice, t_c32slice, + /*13*/ t_harr , t_i32arr , t_fillarr , t_c32arr , t_f64arr , + /*18*/ t_hslice, t_i32slice, t_fillslice, t_c32slice, t_f64slice, - /*21*/ t_comp, t_block, t_body, t_scope, - /*25*/ t_freed, t_harrPartial, + /*22*/ t_comp, t_block, t_body, t_scope, + /*26*/ t_freed, t_harrPartial, #ifdef RT_PERF - /*26*/ t_funPerf, t_md1Perf, t_md2Perf, + /*28*/ t_funPerf, t_md1Perf, t_md2Perf, #endif t_COUNT }; @@ -323,6 +323,7 @@ i32 o2iu (B x) { return isI32(x)? (i32)(u32)x.u : (i32)x.f; } usz o2su (B x) { return (usz)x.f; } i64 o2i64u(B x) { return (i64)x.f; } bool q_i32(B x) { return isI32(x) || isF64(x)&(x.f==(i32)x.f); } +bool q_f64(B x) { return isF64(x) || isI32(x); } typedef struct Slice { diff --git a/src/harr.c b/src/harr.c index ac2fde62..69ceaf15 100644 --- a/src/harr.c +++ b/src/harr.c @@ -91,11 +91,6 @@ B m_caB(usz ia, B* a) { for (usz i = 0; i < ia; i++) r.a[i] = a[i]; return r.b; } -B m_caf64(usz sz, f64* a) { - HArr_p r = m_harrUv(sz); - for (usz i = 0; i < sz; i++) r.a[i] = m_f64(a[i]); - return r.b; -} // consumes all B m_v1(B a ) { HArr_p r = m_harrUv(1); r.a[0] = a; return r.b; } diff --git a/src/i32arr.c b/src/i32arr.c index 74ec277e..31152201 100644 --- a/src/i32arr.c +++ b/src/i32arr.c @@ -12,7 +12,7 @@ B m_i32arrv(usz ia) { return r; } B m_i32arrc(B x) { assert(isArr(x)); - B r = m_arr(fsizeof(I32Arr,a,B,a(x)->ia), t_i32arr); + B r = m_arr(fsizeof(I32Arr,a,i32,a(x)->ia), t_i32arr); arr_shCopy(r, x); return r; } diff --git a/src/main.c b/src/main.c index 6e8690f3..5fc033ea 100644 --- a/src/main.c +++ b/src/main.c @@ -27,6 +27,7 @@ #include "fillarr.c" #include "i32arr.c" #include "c32arr.c" +#include "f64arr.c" #include "utf.c" #include "derv.c" #include "sfns.c" @@ -86,6 +87,7 @@ int main() { fillarr_init(); i32arr_init(); c32arr_init(); + f64arr_init(); arith_init(); sfns_init(); md1_init(); diff --git a/src/sfns.c b/src/sfns.c index ee1c0df5..37afd136 100644 --- a/src/sfns.c +++ b/src/sfns.c @@ -90,6 +90,23 @@ B eachm_fn(BB2B f, B fo, B x) { // consumes x; x must be array } if (!reuse) dec(x); return r; + } else if (v(x)->type==t_f64arr) { + f64* xp = f64arr_ptr(x); + B r = reuse? x : m_f64arrc(x); + f64* rp = f64arr_ptr(r); + rp[i++] = o2iu(cr); + for (; i < ia; i++) { + cr = f(fo, m_f64(xp[i])); + if (!q_f64(cr)) { + rH = m_harrs(ia, &i); + for (usz j = 0; j < i; j++) rH.a[j] = m_f64(rp[j]); + if (!reuse) dec(r); + goto fallback; + } + rp[i] = o2iu(cr); + } + if (!reuse) dec(x); + return r; } else if (v(x)->type==t_fillarr) { B* xp = fillarr_ptr(x); if (reuse) { @@ -189,14 +206,13 @@ B pick_c2(B t, B w, B x) { B ud_c1(B t, B x) { usz xu = o2s(x); if (xush; for (i32 i = 0; i < xr; i++) if (sh[i]>I32_MAX) { - HArr_p r = m_harrUv(xr); - for (i32 j = 0; j < xr; j++) r.a[j] = m_f64(sh[j]); + B r = m_f64arrv(xr); f64* rp = f64arr_ptr(r); + for (i32 j = 0; j < xr; j++) rp[j] = sh[j]; dec(x); - return r.b; + return r; } B r = m_i32arrv(xr); i32* rp = i32arr_ptr(r); for (i32 i = 0; i < xr; i++) rp[i] = sh[i]; diff --git a/src/sysfn.c b/src/sysfn.c index 0bbb0eba..9b3139fd 100644 --- a/src/sysfn.c +++ b/src/sysfn.c @@ -56,14 +56,15 @@ B grLen_c1(B t, B x) { // assumes valid arguments if (c>ria) ria = c; } ria++; - HArr_p r = m_harrUv(ria); - for (usz i = 0; i < ria; i++) r.a[i] = m_f64(0); + B r = m_i32arrv(ria); i32* rp = i32arr_ptr(r); + for (usz i = 0; i < ria; i++) rp[i] = 0; for (usz i = 0; i < ia; i++) { i64 n = o2i64u(xgetU(x, i)); - if (n>=0) r.a[n].f++; + if (n==(usz)n) rp[n]++; + else if (n!=-1) thrM("grLen: Too large"); } dec(x); - return r.b; + return r; } B grLen_c2(B t, B w, B x) { // assumes valid arguments i64 ria = o2i64u(w)-1; @@ -74,14 +75,15 @@ B grLen_c2(B t, B w, B x) { // assumes valid arguments if (c>ria) ria = c; } ria++; - HArr_p r = m_harrUv(ria); - for (usz i = 0; i < ria; i++) r.a[i] = m_f64(0); + B r = m_i32arrv(ria); i32* rp = i32arr_ptr(r); + for (usz i = 0; i < ria; i++) rp[i] = 0; for (usz i = 0; i < ia; i++) { i64 n = o2i64u(xgetU(x, i)); - if (n>=0) r.a[n].f++; + if (n==(usz)n) rp[n]++; + else if (n!=-1) thrM("grLen: Too large"); } dec(x); - return r.b; + return r; } B grOrd_c2(B t, B w, B x) { // assumes valid arguments @@ -95,14 +97,15 @@ B grOrd_c2(B t, B w, B x) { // assumes valid arguments tmp[0] = 0; for (int i = 1; i < wia; i++) tmp[i] = tmp[i-1]+o2su(wgetU(w,i-1)); usz ria = tmp[wia-1]+o2su(wgetU(w,wia-1)); - HArr_p r = m_harrUv(ria); + B r = m_i32arrv(ria); i32* rp = i32arr_ptr(r); + if (xia>=I32_MAX) thrM("grOrd: Too large"); for (usz i = 0; i < xia; i++) { i64 c = o2i64(xgetU(x,i)); - if (c>=0) r.a[tmp[c]++] = m_usz(i); + if (c>=0) rp[tmp[c]++] = i; } dec(w); dec(x); - return r.b; + return r; } B asrt_c1(B t, B x) {