diff --git a/src/arith.c b/src/arith.c index 7b24f7dc..062ba6fe 100644 --- a/src/arith.c +++ b/src/arith.c @@ -1,8 +1,32 @@ #include "h.h" #include -#define P1(N) { if( isArr(x)) return eachm_fn(N##_c1, bi_N, x); } -#define P2(N) { if(isArr(w)|isArr(x)) return eachd_fn(N##_c2, bi_N, w, x); } +static inline B arith_recm(BB2B f, B x) { + B fx = getFill(inc(x)); + B r = eachm_fn(f, bi_N, x); + return withFill(r, fx); +} +#ifdef CATCH_ERRORS +static inline B arith_recd(BBB2B f, B w, B x) { + B fx = getFill(inc(x)); + if (noFill(fx)) return eachd_fn(f, bi_N, w, x); + B fw = getFill(inc(w)); + B r = eachd_fn(f, bi_N, w, x); + if (noFill(fw)) return r; + if (CATCH) { dec(catchMessage); return r; } + B fr = f(bi_N, fw, fx); + popCatch(); + return withFill(r, asFill(fr)); +} +#else +static inline B arith_recd(BBB2B f, B w, B x) { + return eachd_fn(f, bi_N, w, x); +} +#endif + + +#define P1(N) { if( isArr(x)) return arith_recm(N##_c1, x); } +#define P2(N) { if(isArr(w)|isArr(x)) return arith_recd(N##_c2, w, x); } #define ffnx(name, expr, extra) B name##_c2(B t, B w, B x) { \ if (isF64(w) & isF64(x)) return m_f64(expr); \ extra \ diff --git a/src/fillarr.c b/src/fillarr.c index b2014d84..24ce91cc 100644 --- a/src/fillarr.c +++ b/src/fillarr.c @@ -85,8 +85,37 @@ static inline void fillarr_init() { ti[t_fillarr].canStore = fillarr_canStore; } +B m_unit(B x) { + B xf = asFill(inc(x)); + if (noFill(xf)) { + HArr_p r = m_harrp(1); + arr_shAlloc(r.b, 1, 0); + r.a[0] = x; + return r.b; + } + B r = m_arr(fsizeof(FillArr,a,B,1), t_fillarr); + arr_shAlloc(r, 1, 0); + c(FillArr,r)->fill = xf; + c(FillArr,r)->a[0] = x; + return r; +} + +void validateFill(B x) { + if (isArr(x)) { + BS2B xgetU = TI(x).getU; + usz ia = a(x)->ia; + for (usz i = 0; i < ia; i++) validateFill(xgetU(x,i)); + } else if (isF64(x)) { + assert(x.f==0); + } else if (isC32(x)) { + assert(' '==(u32)x.u); + } +} B withFill(B x, B fill) { // consumes both assert(isArr(x)); + #ifdef DEBUG + validateFill(fill); + #endif if (noFill(fill) && v(x)->type!=t_fillarr && v(x)->type!=t_fillslice) return x; switch(v(x)->type) { case t_i32arr : case t_i32slice : if(fill.u == m_i32(0 ).u) return x; break; diff --git a/src/harr.c b/src/harr.c index 915b8481..1ebd82e7 100644 --- a/src/harr.c +++ b/src/harr.c @@ -64,7 +64,6 @@ B m_v1(B a ) { HArr_p r = m_harrv(1); r.a[0] = a; 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_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_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_unit(B x) { HArr_p r = m_harrp(1); arr_shAlloc(r.b, 1, 0); r.a[0] = x; return r.b; } typedef struct HSlice {