From a6251ff3e74e5c9907e94245fe98b9f24e72c43c Mon Sep 17 00:00:00 2001 From: dzaima Date: Thu, 9 Sep 2021 16:08:13 +0300 Subject: [PATCH] squeeze int arrs on withFill --- src/builtins/internal.c | 30 ++++++------- src/core.h | 9 ++++ src/core/c32arr.h | 22 +++++++++- src/core/fillarr.c | 93 ++++++++++++++--------------------------- src/core/i32arr.h | 30 +++++++++++++ src/utils/mut.c | 8 +++- 6 files changed, 112 insertions(+), 80 deletions(-) diff --git a/src/builtins/internal.c b/src/builtins/internal.c index f70c53e9..58cdf042 100644 --- a/src/builtins/internal.c +++ b/src/builtins/internal.c @@ -135,8 +135,8 @@ B listVariations_c2(B t, B w, B x) { B listVariations_c1(B t, B x) { return listVariations_c2(t, inc(listVariations_def), x); } -static bool u32_get(u32** cv, u32* cE, u32* x) { - u32* c = *cv; +static bool u8_get(u8** cv, u8* cE, const char* x) { + u8* c = *cv; while (true) { if (!*x) { *cv = c; @@ -163,9 +163,9 @@ B variation_c2(B t, B w, B x) { u8 xe = TI(x,elType); BS2B xget = TI(x,get); BS2B xgetU = TI(x,getU); - C32Arr* wc = toC32Arr(w); - u32* wp = wc->a; - u32* wpE = wp+wc->ia; + C8Arr* wc = toC8Arr(w); + u8* wp = wc->a; + u8* wpE = wp+wc->ia; if (wc->ia==0) thrM("•internal.Variation: Zero-length 𝕨"); B res; if (*wp == 'A' || *wp == 'S') { @@ -173,24 +173,24 @@ B variation_c2(B t, B w, B x) { wp++; #define CPT(I) do { I; for (usz i = 0; i < xia; i++) tp[i] = xp[i]; } while(0) #define CPF(F) for (usz i = 0; i < xia; i++) tp[i] = F(xgetU(x,i)) - if (u32_get(&wp, wpE, U"i8" )) { i8* tp; res = m_i8arrc (&tp, x); if (xe==el_i8 ) CPT(i8* xp=i8any_ptr (x)); else CPF(o2i); } - else if (u32_get(&wp, wpE, U"i16")) { i16* tp; res = m_i16arrc(&tp, x); if (xe==el_i16) CPT(i16* xp=i16any_ptr(x)); else CPF(o2i); } - else if (u32_get(&wp, wpE, U"i32")) { i32* tp; res = m_i32arrc(&tp, x); if (xe==el_i32) CPT(i32* xp=i32any_ptr(x)); else CPF(o2i); } - else if (u32_get(&wp, wpE, U"c8" )) { u8* tp; res = m_c8arrc (&tp, x); if (xe==el_c8 ) CPT(u8* xp=c8any_ptr (x)); else CPF(o2c); } - else if (u32_get(&wp, wpE, U"c16")) { u16* tp; res = m_c16arrc(&tp, x); if (xe==el_c16) CPT(u16* xp=c16any_ptr(x)); else CPF(o2c); } - else if (u32_get(&wp, wpE, U"c32")) { u32* tp; res = m_c32arrc(&tp, x); if (xe==el_c32) CPT(u32* xp=c32any_ptr(x)); else CPF(o2c); } - else if (u32_get(&wp, wpE, U"f64")) { + if (u8_get(&wp, wpE, "i8" )) { i8* tp; res = m_i8arrc (&tp, x); if (xe==el_i8 ) CPT(i8* xp=i8any_ptr (x)); else CPF(o2i); } + else if (u8_get(&wp, wpE, "i16")) { i16* tp; res = m_i16arrc(&tp, x); if (xe==el_i16) CPT(i16* xp=i16any_ptr(x)); else CPF(o2i); } + else if (u8_get(&wp, wpE, "i32")) { i32* tp; res = m_i32arrc(&tp, x); if (xe==el_i32) CPT(i32* xp=i32any_ptr(x)); else CPF(o2i); } + else if (u8_get(&wp, wpE, "c8" )) { u8* tp; res = m_c8arrc (&tp, x); if (xe==el_c8 ) CPT(u8* xp=c8any_ptr (x)); else CPF(o2c); } + else if (u8_get(&wp, wpE, "c16")) { u16* tp; res = m_c16arrc(&tp, x); if (xe==el_c16) CPT(u16* xp=c16any_ptr(x)); else CPF(o2c); } + else if (u8_get(&wp, wpE, "c32")) { u32* tp; res = m_c32arrc(&tp, x); if (xe==el_c32) CPT(u32* xp=c32any_ptr(x)); else CPF(o2c); } + else if (u8_get(&wp, wpE, "f64")) { f64* tp; res = m_f64arrc(&tp, x); if (xe==el_i32) CPT(i32* xp=i32any_ptr(x)); else if (xe==el_f64) CPT(f64* xp=f64any_ptr(x)); else for (usz i = 0; i < xia; i++) tp[i] = o2f(xgetU(x,i)); - } else if (u32_get(&wp, wpE, U"h")) { + } else if (u8_get(&wp, wpE, "h")) { HArr_p t = m_harrUc(x); if (xe==el_i32) { i32* xp=i32any_ptr(x); for (usz i = 0; i < xia; i++) t.a[i] = m_f64(xp[i]); } else if (xe==el_f64) { f64* xp=f64any_ptr(x); for (usz i = 0; i < xia; i++) t.a[i] = m_f64(xp[i]); } else for (usz i = 0; i < xia; i++) t.a[i] = xget(x,i); res = t.b; - } else if (u32_get(&wp, wpE, U"f")) { + } else if (u8_get(&wp, wpE, "f")) { Arr* t = m_fillarrp(xia); res = taga(t); fillarr_setFill(t, getFillQ(x)); @@ -205,7 +205,7 @@ B variation_c2(B t, B w, B x) { arr_shCopy(slice, res); res = taga(slice); } - if (u32_get(&wp, wpE, U"Inc")) { + if (u8_get(&wp, wpE, "Inc")) { if (!variation_refs.u) { variation_refs = emptyHVec(); } diff --git a/src/core.h b/src/core.h index 63081333..cf8ad4a9 100644 --- a/src/core.h +++ b/src/core.h @@ -59,6 +59,15 @@ extern B r1Objs[rtLen]; #endif +static B* arr_bptr(B x) { assert(isArr(x)); + if (v(x)->type==t_harr) return harr_ptr(x); + if (v(x)->type==t_hslice) return c(HSlice,x)->a; + if (v(x)->type==t_fillarr) return fillarr_ptr(a(x)); + if (v(x)->type==t_fillslice) return c(FillSlice,x)->a; + return NULL; +} + + typedef struct BFn { struct Fun; B ident; diff --git a/src/core/c32arr.h b/src/core/c32arr.h index f8d61fda..e63391e4 100644 --- a/src/core/c32arr.h +++ b/src/core/c32arr.h @@ -2,15 +2,35 @@ B m_str8(usz sz, char* s); B m_str8l(char* s); B m_str32(u32* s); +static C8Arr* toC8Arr(B x) { + if (v(x)->type==t_c8arr) return c(C8Arr,x); + u8* rp; B r = m_c8arrc(&rp, x); + usz ia = a(r)->ia; + BS2B xgetU = TI(x,getU); + for (usz i = 0; i < ia; i++) rp[i] = o2cu(xgetU(x,i)); + dec(x); + return c(C8Arr,r); +} +static C16Arr* toC16Arr(B x) { + if (v(x)->type==t_c16arr) return c(C16Arr,x); + u16* rp; B r = m_c16arrc(&rp, x); + usz ia = a(r)->ia; + BS2B xgetU = TI(x,getU); + for (usz i = 0; i < ia; i++) rp[i] = o2cu(xgetU(x,i)); + dec(x); + return c(C16Arr,r); +} static C32Arr* toC32Arr(B x) { if (v(x)->type==t_c32arr) return c(C32Arr,x); u32* rp; B r = m_c32arrc(&rp, x); usz ia = a(r)->ia; BS2B xgetU = TI(x,getU); - for (usz i = 0; i < ia; i++) rp[i] = o2c(xgetU(x,i)); + for (usz i = 0; i < ia; i++) rp[i] = o2cu(xgetU(x,i)); dec(x); return c(C32Arr,r); } + + static bool eqStr(B w, u32* x) { if (isAtm(w) || rnk(w)!=1) return false; BS2B wgetU = TI(w,getU); diff --git a/src/core/fillarr.c b/src/core/fillarr.c index cd27e7c9..3ce14a5d 100644 --- a/src/core/fillarr.c +++ b/src/core/fillarr.c @@ -116,6 +116,8 @@ B withFill(B x, B fill) { // consumes both case t_i8arr: case t_i8slice: if(fill.u == m_i32(0 ).u) return x; break; case t_i16arr: case t_i16slice: if(fill.u == m_i32(0 ).u) return x; break; case t_i32arr: case t_i32slice: if(fill.u == m_i32(0 ).u) return x; break; + case t_c8arr: case t_c8slice: if(fill.u == m_c32(' ').u) return x; break; + case t_c16arr: case t_c16slice: if(fill.u == m_c32(' ').u) return x; break; case t_c32arr: case t_c32slice: if(fill.u == m_c32(' ').u) return x; break; case t_fillslice: if (fillEqual(((FillArr*)c(Slice,x)->p)->fill, fill)) { dec(fill); return x; } break; case t_fillarr: if (fillEqual(c(FillArr,x)->fill, fill)) { dec(fill); return x; } @@ -128,69 +130,36 @@ B withFill(B x, B fill) { // consumes both } usz ia = a(x)->ia; if (isNum(fill)) { - if (xt==t_harr) { - B* xp = harr_ptr(x); - { - i32* rp; B r = m_i32arrc(&rp, x); - for (usz i = 0; i < ia; i++) { - B c = xp[i]; - if (!q_i32(c)) { dec(r); goto h_f64; } - rp[i] = o2iu(c); - } - dec(x); - return r; - } - h_f64: { - f64* rp; B r = m_f64arrc(&rp, x); - for (usz i = 0; i < ia; i++) { - B c = xp[i]; - if (!q_f64(c)) { dec(r); goto base; } - rp[i] = o2fu(c); - } - dec(x); - return r; - } - } else { - BS2B xgetU = TI(x,getU); - { - i32* rp; B r = m_i32arrc(&rp, x); - for (usz i = 0; i < ia; i++) { - B c = xgetU(x, i); - if (!q_i32(c)) { dec(r); goto g_f64; } - rp[i] = o2iu(c); - } - dec(x); - return r; - } - g_f64: { - f64* rp; B r = m_f64arrc(&rp, x); - for (usz i = 0; i < ia; i++) { - B c = xgetU(x, i); - if (!q_f64(c)) { dec(r); goto base; } - rp[i] = o2fu(c); - } - dec(x); - return r; - } - - // bool ints = true; - // for (usz i = 0; i < ia; i++) { - // B c = xgetU(x, i); - // if (!isNum(c)) goto base; - // if (!q_i32(c)) ints = false; - // } - // if (ints) { - // B r = m_i32arrc(x); i32* rp = i32arr_ptr(r); - // for (usz i = 0; i < ia; i++) rp[i] = o2iu(xgetU(x, i)); - // dec(x); - // return r; - // } else { - // B r = m_f64arrc(x); f64* rp = f64arr_ptr(r); - // for (usz i = 0; i < ia; i++) rp[i] = o2fu(xgetU(x, i)); - // dec(x); - // return r; - // } + B* xp = arr_bptr(x); + if (xp==NULL) goto base; + usz i = 0; + i32 or = 0; + for (; i < ia; i++) { + if (!q_i32(xp[i])) goto n_i32; + i32 c = o2iu(xp[i]); + or|= c<0?-c:c; // using or as a heuristical max } + if (or<=I8_MAX) { + i8* rp; B r = m_i8arrc(&rp, x); + for (usz i = 0; i < ia; i++) rp[i] = o2iu(xp[i]); + dec(x); return r; + } else if (or<=I16_MAX) { + i16* rp; B r = m_i16arrc(&rp, x); + for (usz i = 0; i < ia; i++) rp[i] = o2iu(xp[i]); + dec(x); return r; + } else { + i32* rp; B r = m_i32arrc(&rp, x); + for (usz i = 0; i < ia; i++) rp[i] = o2iu(xp[i]); + dec(x); return r; + } + + n_i32:; + while (i < ia) if (!isF64(xp[i++])) goto base; + + f64* rp; B r = m_f64arrc(&rp, x); + for (usz i = 0; i < ia; i++) rp[i] = o2f(xp[i]); + dec(x); return r; + } else if (isC32(fill)) { u32* rp; B r = m_c32arrc(&rp, x); BS2B xgetU = TI(x,getU); diff --git a/src/core/i32arr.h b/src/core/i32arr.h index 3fac3245..5f5b866a 100644 --- a/src/core/i32arr.h +++ b/src/core/i32arr.h @@ -1,5 +1,35 @@ B m_cai32(usz ia, i32* a); +static I8Arr* toI8Arr(B x) { // assumes it's possible + if (v(x)->type==t_i8arr) return c(I8Arr,x); + i8* rp; B r = m_i8arrc(&rp, x); + usz ia = a(r)->ia; + if (TI(x,elType)==el_i32) { + i32* fp = i32any_ptr(x); + for (usz i = 0; i < ia; i++) rp[i] = (i8)fp[i]; + } else { + BS2B xgetU = TI(x,getU); + for (usz i = 0; i < ia; i++) rp[i] = o2iu(xgetU(x,i)); + } + dec(x); + return c(I8Arr,r); +} + +static I16Arr* toI16Arr(B x) { // assumes it's possible + if (v(x)->type==t_i16arr) return c(I16Arr,x); + i16* rp; B r = m_i16arrc(&rp, x); + usz ia = a(r)->ia; + if (TI(x,elType)==el_f64) { + f64* fp = f64any_ptr(x); + for (usz i = 0; i < ia; i++) rp[i] = (i16)fp[i]; + } else { + BS2B xgetU = TI(x,getU); + for (usz i = 0; i < ia; i++) rp[i] = o2iu(xgetU(x,i)); + } + dec(x); + return c(I16Arr,r); +} + static I32Arr* toI32Arr(B x) { // assumes it's possible if (v(x)->type==t_i32arr) return c(I32Arr,x); i32* rp; B r = m_i32arrc(&rp, x); diff --git a/src/utils/mut.c b/src/utils/mut.c index 546a1673..84c646f7 100644 --- a/src/utils/mut.c +++ b/src/utils/mut.c @@ -21,9 +21,13 @@ NOINLINE void mut_to(Mut* m, u8 n) { } #endif switch(n) { default: UD; + case el_i8: { I8Arr* t=toI8Arr (taga(m->val)); m->val=(Arr*)t; m->ai8 =t->a; return; } + case el_i16: { I16Arr* t=toI16Arr(taga(m->val)); m->val=(Arr*)t; m->ai16=t->a; return; } case el_i32: { I32Arr* t=toI32Arr(taga(m->val)); m->val=(Arr*)t; m->ai32=t->a; return; } - case el_f64: { F64Arr* t=toF64Arr(taga(m->val)); m->val=(Arr*)t; m->af64=t->a; return; } + case el_c8: { C8Arr* t=toC8Arr (taga(m->val)); m->val=(Arr*)t; m->ac8 =t->a; return; } + case el_c16: { C16Arr* t=toC16Arr(taga(m->val)); m->val=(Arr*)t; m->ac16=t->a; return; } case el_c32: { C32Arr* t=toC32Arr(taga(m->val)); m->val=(Arr*)t; m->ac32=t->a; return; } + case el_f64: { F64Arr* t=toF64Arr(taga(m->val)); m->val=(Arr*)t; m->af64=t->a; return; } case el_B : { HArr* t=toHArr (taga(m->val)); m->val=(Arr*)t; m->aB =t->a; return; } } } @@ -43,7 +47,7 @@ NOINLINE void mut_pfree(Mut* m, usz n) { // free the first n elements else mm_free((Value*) m->val); } -u8 el_orArr[el_MAX*16 + el_MAX]; +u8 el_orArr[el_MAX*16 + el_MAX+1]; void mutF_init() { for (u8 i = 0; i <= el_MAX; i++) { for (u8 j = 0; j <= el_MAX; j++) {