From 8a1ccc719884485e70114ec88326f746a2be977b Mon Sep 17 00:00:00 2001 From: dzaima Date: Wed, 15 Dec 2021 14:02:46 +0200 Subject: [PATCH] =?UTF-8?q?native=20=E2=8A=91;=20f=E2=8C=BE(v=E2=8A=B8?= =?UTF-8?q?=E2=8A=8F)=20f64arr?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/sfns.c | 95 ++++++++++++++++++++++++++++++++++++++------- src/core/stuff.c | 27 ++++++++----- 2 files changed, 98 insertions(+), 24 deletions(-) diff --git a/src/builtins/sfns.c b/src/builtins/sfns.c index e8c13f87..cf7152bf 100644 --- a/src/builtins/sfns.c +++ b/src/builtins/sfns.c @@ -251,14 +251,70 @@ B pick_c1(B t, B x) { dec(x); return r; } + +static B recPick(B w, B x) { // doesn't consume + assert(isArr(w) && isArr(x)); + usz ia = a(w)->ia; + ur xr = rnk(x); + usz* xsh = a(x)->sh; + switch(TI(w,elType)) { default: UD; + case el_i8: { i8* wp = i8any_ptr (w); if (ia!=xr)goto wrr; usz c=0; for (usz i = 0; i < ia; i++) { c = c*xsh[i] + WRAP(wp[i], xsh[i], goto oob); }; return IGet(x,c); } + case el_i16: { i16* wp = i16any_ptr(w); if (ia!=xr)goto wrr; usz c=0; for (usz i = 0; i < ia; i++) { c = c*xsh[i] + WRAP(wp[i], xsh[i], goto oob); }; return IGet(x,c); } + case el_i32: { i32* wp = i32any_ptr(w); if (ia!=xr)goto wrr; usz c=0; for (usz i = 0; i < ia; i++) { c = c*xsh[i] + WRAP(wp[i], xsh[i], goto oob); }; return IGet(x,c); } + case el_c8: case el_c16: case el_c32: case el_bit: + case el_B: { + if (ia==0) { + if (xr!=0) thrM("โŠ‘: Empty array in ๐•จ must correspond to unit in ๐•ฉ"); + return IGet(x,0); + } + SGetU(w) + if (isNum(GetU(w,0))) { + if (ia!=xr) goto wrr; + usz c=0; + for (usz i = 0; i < ia; i++) { + B cw = GetU(w,i); + if (!isNum(cw)) thrM("โŠ‘: ๐•จ contained list with mixed-type elements"); + c = c*xsh[i] + WRAP(o2i64(cw), xsh[i], goto oob); + } + return IGet(x,c); + } else { + usz i = 0; + HArr_p r = m_harrs(ia, &i); + for(; iia!=0) return c2(rt_pick, w, x); // ugh this is such a lame case that'd need a whole another recursive fn to implement + dec(w); + return x; + } + if (isNum(w)) { + if (rnk(x)!=1) thrF("โŠ‘: ๐•ฉ must be a list when ๐•จ is a number (%H โ‰ก โ‰ข๐•ฉ)", x); usz p = WRAP(o2i64(w), a(x)->ia, thrF("โŠ‘: indexing out-of-bounds (๐•จโ‰ก%R, %sโ‰กโ‰ ๐•ฉ)", w, iaW)); B r = IGet(x, p); dec(x); return r; } - return c2(rt_pick, w, x); + B r = recPick(w, x); + dec(w); dec(x); + return r; } extern B rt_select; @@ -1222,7 +1278,7 @@ B select_ucw(B t, B o, B w, B x) { if (we<=el_i32) { w = toI32Any(w); i32* wp = i32any_ptr(w); - if (rere?xe:re; bool reuse = reusable(x); if (me==el_i32) { @@ -1236,17 +1292,6 @@ B select_ucw(B t, B o, B w, B x) { xp[cw] = cr; } dec(w); dec(rep); FREE_CHECK; return taga(xn); - } else if (me==el_i16) { - I16Arr* xn = reuse? toI16Arr(REUSE(x)) : cpyI16Arr(x); - i16* xp = i16arrv_ptr(xn); - rep = toI16Any(rep); i16* rp = i16any_ptr(rep); - for (usz i = 0; i < wia; i++) { - i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; - i16 cr = rp[i]; - EQ(cr != xp[cw]); - xp[cw] = cr; - } - dec(w); dec(rep); FREE_CHECK; return taga(xn); } else if (me==el_i8) { I8Arr* xn = reuse? toI8Arr(REUSE(x)) : cpyI8Arr(x); i8* xp = i8arrv_ptr(xn); @@ -1258,6 +1303,17 @@ B select_ucw(B t, B o, B w, B x) { xp[cw] = cr; } dec(w); dec(rep); FREE_CHECK; return taga(xn); + } else if (me==el_i16) { + I16Arr* xn = reuse? toI16Arr(REUSE(x)) : cpyI16Arr(x); + i16* xp = i16arrv_ptr(xn); + rep = toI16Any(rep); i16* rp = i16any_ptr(rep); + for (usz i = 0; i < wia; i++) { + i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; + i16 cr = rp[i]; + EQ(cr != xp[cw]); + xp[cw] = cr; + } + dec(w); dec(rep); FREE_CHECK; return taga(xn); } else if (me==el_bit) { BitArr* xn = reuse? toBitArr(REUSE(x)) : cpyBitArr(x); u64* xp = bitarrv_ptr(xn); @@ -1269,6 +1325,17 @@ B select_ucw(B t, B o, B w, B x) { bitp_set(xp,cw,cr); } dec(w); dec(rep); FREE_CHECK; return taga(xn); + } else if (me==el_f64) { + F64Arr* xn = reuse? toF64Arr(REUSE(x)) : cpyF64Arr(x); + f64* xp = f64arrv_ptr(xn); + rep = toF64Any(rep); f64* rp = f64any_ptr(rep); + for (usz i = 0; i < wia; i++) { + i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; + f64 cr = rp[i]; + EQ(cr != xp[cw]); + xp[cw] = cr; + } + dec(w); dec(rep); FREE_CHECK; return taga(xn); } else UD; } if (reusable(x) && xe==re) { diff --git a/src/core/stuff.c b/src/core/stuff.c index c3767590..e6f3d1bd 100644 --- a/src/core/stuff.c +++ b/src/core/stuff.c @@ -199,6 +199,16 @@ i32 num_fmt(char buf[30], f64 x) { } return len; } + +static B appendRaw(B s, B x) { assert(isArr(x) && rnk(x)==1); // consumes x + if (TI(x,elType)==el_c32) AJOIN(x); + else { + B sq = chr_squeezeChk(x); + if (!elChr(TI(sq,elType))) FL_KEEP(sq, ~fl_squoze); + AJOIN(sq); + } + return s; +} NOINLINE B do_fmt(B s, char* p, va_list a) { char buf[30]; char c; @@ -209,16 +219,13 @@ NOINLINE B do_fmt(B s, char* p, va_list a) { switch(c = *p++) { default: printf("Unknown format character '%c'", c); UD; case 'R': { B b = va_arg(a, B); - if (isNum(b)) { - AFMT("%f", o2f(b)); - } else { assert(isArr(b) && rnk(b)==1); - if (TI(b,elType)==el_c32) AJOIN(inc(b)); - else { - B sq = chr_squeezeChk(inc(b)); - if (!elChr(TI(sq,elType))) FL_KEEP(sq, ~fl_squoze); - AJOIN(sq); - } - } + if (isNum(b)) AFMT("%f", o2f(b)); + else s = appendRaw(s, inc(b)); + break; + } + case 'B': { + B b = va_arg(a, B); + s = appendRaw(s, bqn_fmt(inc(b))); break; } case 'H': {