From d08cd90998ff28b71052c0ff6c7ee41fb53f0d59 Mon Sep 17 00:00:00 2001 From: dzaima Date: Wed, 19 May 2021 18:57:12 +0300 Subject: [PATCH] typed arith --- src/arith.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++----- src/main.c | 1 + src/stuff.c | 2 ++ 3 files changed, 71 insertions(+), 6 deletions(-) diff --git a/src/arith.c b/src/arith.c index bd39b233..d35123be 100644 --- a/src/arith.c +++ b/src/arith.c @@ -27,12 +27,74 @@ static inline B arith_recd(BBB2B f, B w, B x) { #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 \ - P2(name) \ - thrM(#name ": invalid arithmetic"); \ -} +#if TYPED_ARITH + static B f64_maybe_i32(B x) { + f64* xp = f64arr_ptr(x); + usz ia = a(x)->ia; + if (ia==0) { dec(x); return inc(bi_emptyIVec); } + if (xp[0] != (i32)xp[0]) return x; + i32* rp; B r = m_i32arrc(&rp, x); + for (usz i = 0; i < ia; i++) { + f64 cf = xp[i]; + i32 c = (i32)cf; + if (cf!=c) { dec(r); return x; } + rp[i] = c; + } + dec(x); + return r; + } + #define ffnx(NAME, EXPR, EXTRA) B NAME##_c2(B t, B w, B x) { \ + if (isF64(w) & isF64(x)) return m_f64(EXPR); \ + EXTRA \ + if (isArr(w)|isArr(x)) { B ow=w; B ox=x; \ + if (isArr(w)&isArr(x) && rnk(w)==rnk(x)) { \ + usz ia = a(x)->ia; \ + u8 we = TI(w).elType; \ + u8 xe = TI(x).elType; \ + if (isNumEl(we)&isNumEl(xe)) { \ + f64* rp; B r = m_f64arrc(&rp, x); \ + if (we==el_i32) { B w,x/*shadow*/; i32* wp = i32any_ptr(ow); \ + if (xe==el_i32) { i32* xp = i32any_ptr(ox); for (usz i = 0; i < ia; i++) {w.f=wp[i];x.f=xp[i];rp[i]=EXPR;} } \ + else { f64* xp = f64any_ptr(ox); for (usz i = 0; i < ia; i++) {w.f=wp[i];x.f=xp[i];rp[i]=EXPR;} } \ + } else { B w,x/*shadow*/; f64* wp = f64any_ptr(ow); \ + if (xe==el_i32) { i32* xp = i32any_ptr(ox); for (usz i = 0; i < ia; i++) {w.f=wp[i];x.f=xp[i];rp[i]=EXPR;} } \ + else { f64* xp = f64any_ptr(ox); for (usz i = 0; i < ia; i++) {w.f=wp[i];x.f=xp[i];rp[i]=EXPR;} } \ + } \ + dec(w); dec(x); return f64_maybe_i32(r); \ + } \ + } else if (isF64(w)&isArr(x)) { usz ia = a(x)->ia; \ + u8 xe = TI(x).elType; f64*rp; \ + if (xe==el_i32) { B r=m_f64arrc(&rp, x); i32*xp=i32any_ptr(x); \ + for (usz i = 0; i < ia; i++) {B x/*shadow*/;x.f=xp[i];rp[i]=EXPR;} \ + dec(x); return f64_maybe_i32(r); \ + } \ + if (xe==el_f64) { B r=m_f64arrc(&rp, x); f64*xp=f64any_ptr(x); \ + for (usz i = 0; i < ia; i++) {B x/*shadow*/;x.f=xp[i];rp[i]=EXPR;} \ + dec(x); return f64_maybe_i32(r); \ + } \ + } else if (isF64(x)&isArr(w)) { usz ia = a(w)->ia; \ + u8 we = TI(w).elType; f64*rp; \ + if (we==el_i32) { B r=m_f64arrc(&rp, w); i32*wp=i32any_ptr(w); \ + for (usz i = 0; i < ia; i++) {B w/*shadow*/;w.f=wp[i];rp[i]=EXPR;} \ + dec(w); return f64_maybe_i32(r); \ + } \ + if (we==el_f64) { B r=m_f64arrc(&rp, w); f64*wp=f64any_ptr(w); \ + for (usz i = 0; i < ia; i++) {B w/*shadow*/;w.f=wp[i];rp[i]=EXPR;} \ + dec(w); return f64_maybe_i32(r); \ + } \ + } \ + P2(NAME) \ + } \ + thrM(#NAME ": invalid arithmetic"); \ + } +#else // !TYPED_ARITH + #define ffnx(name, expr, extra) B name##_c2(B t, B w, B x) { \ + if (isF64(w) & isF64(x)) return m_f64(expr); \ + extra \ + P2(name) \ + thrM(#name ": invalid arithmetic"); \ + } +#endif // TYPED_ARITH #define ffn(name, op, extra) ffnx(name, w.f op x.f, extra) f64 pfmod(f64 a, f64 b) { diff --git a/src/main.c b/src/main.c index 36b14d23..15faff5f 100644 --- a/src/main.c +++ b/src/main.c @@ -14,6 +14,7 @@ // #define ALL_R0 // use all of r0.bqn for runtime_0 // #define ALL_R1 // use all of r1.bqn for runtime // #define RT_SRC // whether ./genRuntimeSrc was used to generate precompiled sources +#define TYPED_ARITH true // whether to use typed arith #define VM_POS true // whether to store detailed execution position information for stacktraces #define CHECK_VALID true // whether to check for valid arguments in places where that would be detrimental to performance (e.g. left argument sortedness of ⍋/⍒, incompatible changes in ⌾, etc) #define EACH_FILLS false // whether to try to squeeze out fills for ¨ and ⌜ diff --git a/src/stuff.c b/src/stuff.c index 8ecde982..ebfcd175 100644 --- a/src/stuff.c +++ b/src/stuff.c @@ -353,6 +353,8 @@ u8 selfElType(B x) { return el_B; } +bool isNumEl(u8 elt) { return elt==el_i32 | elt==el_f64; } + #ifdef DEBUG