diff --git a/src/h.h b/src/h.h index b55189ee..012fade3 100644 --- a/src/h.h +++ b/src/h.h @@ -101,7 +101,7 @@ char* format_type(u8 u) { /*arith.c*/ F(add,"+") F(sub,"-") F(mul,"×") F(div,"÷") F(pow,"⋆") F(floor,"⌊") F(ceil,"⌈") F(stile,"|") F(eq,"=") \ /*arith.c*/ F(ne,"≠") F(le,"≤") F(ge,"≥") F(lt,"<") F(gt,">") F(and,"∧") F(or,"∨") F(not,"¬") F(log,"⋆⁼") \ /*fns.c*/ F(ud,"↕") F(fne,"≢") F(feq,"≡") F(ltack,"⊣") F(rtack,"⊢") F(fmtF,"•FmtF") F(fmtN,"•FmtN") \ - /*sfns.c*/ F(shape,"⥊") F(pick,"⊑") F(pair,"{𝕨‿𝕩}") F(select,"⊏") F(slash,"/") F(join,"∾") F(shiftb,"»") F(shifta,"«") F(take,"↑") F(drop,"↓") \ + /*sfns.c*/ F(shape,"⥊") F(pick,"⊑") F(pair,"{𝕨‿𝕩}") F(select,"⊏") F(slash,"/") F(join,"∾") F(couple,"≍") F(shiftb,"»") F(shifta,"«") F(take,"↑") F(drop,"↓") \ /*derv.c*/ F(fork,"(fork)") F(atop,"(atop)") F(md1d,"(derived 1-modifier)") F(md2d,"(derived 2-modifier)") \ /*sysfn.c*/ F(type,"•Type") F(decp,"•Decompose") F(primInd,"•PrimInd") F(glyph,"•Glyph") F(fill,"•FillFn") \ /*sysfn.c*/ F(grLen,"•GroupLen") F(grOrd,"•groupOrd") F(asrt,"!") F(sys,"•getsys") F(internal,"•Internal") F(show,"•Show") F(out,"•Out") @@ -373,7 +373,7 @@ typedef struct TypeInfo { BS2B getU; // like get, but doesn't increment result (mostly equivalent to `B t=get(…); dec(t); t`) BB2B m1_d; // consume all args; (m, f) BBB2B m2_d; // consume all args; (m, f, g) - BS2B slice; // consumes, but keeps original object alive; create slice from given starting position; add ia, rank, shape yourself; may not actually be a Slice object + BS2B slice; // consumes; create slice from given starting position; add ia, rank, shape yourself; may not actually be a Slice object B2B identity; // return identity element of this function; doesn't consume B2b canStore; // doesn't consume diff --git a/src/main.c b/src/main.c index be624eca..c71b9c87 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 EACH_FILLS false // whether to try to squeeze out fills for ¨ and ⌜ +#define SFNS_FILLS true // whether to insert fills for structural functions (∾, ≍, etc) #define FAKE_RUNTIME false // whether to disable the self-hosted runtime // #define LOG_GC // log GC stats @@ -22,7 +23,7 @@ // #define RT_PERF // time runtime primitives #ifdef CATCH_ERRORS - #define PROPER_FILLS EACH_FILLS + #define PROPER_FILLS (EACH_FILLS&SFNS_FILLS) #else #undef EACH_FILLS #define EACH_FILLS false @@ -91,7 +92,7 @@ int main() { B fruntime[] = { /* +-×÷⋆√⌊⌈|¬ */ bi_add , bi_sub , bi_mul , bi_div , bi_pow , bi_N , bi_floor, bi_ceil, bi_stile , bi_not, /* ∧∨<>≠=≤≥≡≢ */ bi_and , bi_or , bi_lt , bi_gt , bi_ne , bi_eq , bi_le , bi_ge , bi_feq , bi_fne, - /* ⊣⊢⥊∾≍↑↓↕«» */ bi_ltack, bi_rtack , bi_shape, bi_join , bi_N , bi_take , bi_drop , bi_ud , bi_shifta, bi_shiftb, + /* ⊣⊢⥊∾≍↑↓↕«» */ bi_ltack, bi_rtack , bi_shape, bi_join , bi_couple, bi_take , bi_drop , bi_ud , bi_shifta, bi_shiftb, /* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ bi_N , bi_N , bi_slash, bi_N , bi_N , bi_select, bi_pick , bi_N , bi_N , bi_N, /* ⍷⊔!˙˜˘¨⌜⁼´ */ bi_N , bi_N , bi_asrt , bi_const, bi_swap , bi_N , bi_each , bi_tbl , bi_N , bi_fold, /* ˝`∘○⊸⟜⌾⊘◶⎉ */ bi_N , bi_scan , bi_atop , bi_over , bi_before, bi_after , bi_N , bi_val , bi_cond , bi_N, @@ -100,7 +101,7 @@ int main() { bool rtComplete[] = { /* +-×÷⋆√⌊⌈|¬ */ 1,1,1,1,1,0,1,1,1,1, /* ∧∨<>≠=≤≥≡≢ */ 1,1,1,1,1,1,1,1,1,1, - /* ⊣⊢⥊∾≍↑↓↕«» */ 1,1,0,1,0,0,0,0,1,1, + /* ⊣⊢⥊∾≍↑↓↕«» */ 1,1,0,1,1,0,0,0,1,1, /* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ 0,0,1,0,0,1,0,0,0,0, /* ⍷⊔!˙˜˘¨⌜⁼´ */ 0,0,1,1,1,0,1,1,0,1, /* ˝`∘○⊸⟜⌾⊘◶⎉ */ 0,1,1,1,1,1,0,1,0,0, diff --git a/src/sfns.c b/src/sfns.c index 3620354d..ae68d6a7 100644 --- a/src/sfns.c +++ b/src/sfns.c @@ -197,7 +197,7 @@ B select_c1(B t, B x) { ur xr = rnk(x); if (xr==0) thrM("⊏: Argument cannot be rank 0"); if (a(x)->sh[0]==0) thrM("⊏: Argument shape cannot start with 0"); - B r = TI(x).slice(x,0); + B r = TI(x).slice(inc(x),0); usz* sh = arr_shAllocR(r, xr-1); usz ia = 1; for (i32 i = 1; i < xr; i++) { @@ -205,6 +205,7 @@ B select_c1(B t, B x) { ia*= a(x)->sh[i]; } a(r)->ia = ia; + dec(x); return r; } B select_c2(B t, B w, B x) { @@ -217,9 +218,10 @@ B select_c2(B t, B w, B x) { i64 wi = o2i64(w); if (wi<0) wi+= cam; if ((usz)wi >= cam) thrM("⊏: Indexing out-of-bounds"); - B r = TI(x).slice(x, wi*csz); + B r = TI(x).slice(inc(x), wi*csz); usz* sh = arr_shAllocI(r, csz, xr-1); if (sh) memcpy(sh, a(x)->sh+1, (xr-1)*sizeof(usz)); + dec(x); return r; } B xf = getFill(inc(x)); @@ -374,12 +376,12 @@ B drop_c2(B t, B w, B x) { B rt_join; B join_c1(B t, B x) { - if (!isArr(x)) thrM("∾: Argument must be an array"); + if (isAtm(x)) thrM("∾: Argument must be an array"); if (rnk(x)==1) { usz xia = a(x)->ia; if (xia==0) { B xf = getFillE(x); - if (!isArr(xf)) thrM("∾: Empty vector 𝕩 cannot have an atom fill element"); + if (isAtm(xf)) thrM("∾: Empty vector 𝕩 cannot have an atom fill element"); ur ir = rnk(xf); if (ir==0) thrM("∾: Empty vector 𝕩 cannot have a unit fill element"); B xff = getFill(inc(xf)); @@ -395,8 +397,8 @@ B join_c1(B t, B x) { BS2B xgetU = TI(x).getU; B x0 = xgetU(x,0); - B rf = getFill(inc(x0)); - if (!isArr(x0)) thrM("∾: Rank of items must be equal or greater than rank of argument"); + B rf; if(SFNS_FILLS) rf = getFill(inc(x0)); + if (isAtm(x0)) thrM("∾: Rank of items must be equal or greater than rank of argument"); usz ir = rnk(x0); usz* x0sh = a(x0)->sh; if (ir==0) thrM("∾: Rank of items must be equal or greater than rank of argument"); @@ -409,7 +411,7 @@ B join_c1(B t, B x) { usz* csh = a(c)->sh; if (ir>1) for (usz j = 1; j < ir; j++) if (csh[j]!=x0sh[j]) thrM("∾: Item trailing shapes must be equal"); cam+= a(c)->sh[0]; - if (!noFill(rf)) rf = fill_or(rf, getFill(inc(c))); + if (SFNS_FILLS && !noFill(rf)) rf = fill_or(rf, getFill(inc(c))); } MAKE_MUT(r, cam*csz); @@ -428,7 +430,7 @@ B join_c1(B t, B x) { memcpy(sh+1, x0sh+1, sizeof(usz)*(ir-1)); } dec(x); - return qWithFill(rb, rf); + return SFNS_FILLS? qWithFill(rb, rf) : rb; } return c1(rt_join, x); } @@ -463,6 +465,47 @@ B join_c2(B t, B w, B x) { } +B couple_c1(B t, B x) { + if (isArr(x)) { + usz rr = rnk(x); + usz ia = a(x)->ia; + B r = TI(x).slice(inc(x),0); + usz* sh = arr_shAllocI(r, ia, rr+1); + if (sh) { sh[0] = 1; memcpy(sh+1, a(x)->sh, rr*sizeof(usz)); } + dec(x); + return r; + } + if (q_i32(x)) { B r = m_i32arrv(1); i32arr_ptr(r)[0] = o2iu(x); return r; } + if (isF64(x)) { B r = m_f64arrv(1); f64arr_ptr(r)[0] = o2fu(x); return r; } + if (isC32(x)) { B r = m_c32arrv(1); c32arr_ptr(r)[0] = o2cu(x); return r; } + HArr_p r = m_harrUv(1); + r.a[0] = x; + return r.b; +} +B couple_c2(B t, B w, B x) { + if (isAtm(w)&isAtm(x)) { + if (q_i32(x)&q_i32(w)) { B r = m_i32arrv(2); i32* rp=i32arr_ptr(r); rp[0]=o2iu(w); rp[1]=o2iu(x); return r; } + if (isF64(x)&isF64(w)) { B r = m_f64arrv(2); f64* rp=f64arr_ptr(r); rp[0]=o2fu(w); rp[1]=o2fu(x); return r; } + if (isC32(x)&isC32(w)) { B r = m_c32arrv(2); u32* rp=c32arr_ptr(r); rp[0]=o2cu(w); rp[1]=o2cu(x); return r; } + } + if (isAtm(w)) w = m_atomUnit(w); + if (isAtm(x)) x = m_atomUnit(x); + if (!eqShape(w, x)) thrM("≍: 𝕨 and 𝕩 must have equal shapes"); + usz ia = a(w)->ia; + ur wr = rnk(w); + MAKE_MUT(r, ia*2); + mut_copy(r, 0, w, 0, ia); + mut_copy(r, ia, x, 0, ia); + B rb = mut_fp(r); + usz* sh = arr_shAllocR(rb, wr+1); + if (sh) { sh[0]=2; memcpy(sh+1, a(w)->sh, wr*sizeof(usz)); } + if (!SFNS_FILLS) { dec(w); dec(x); return rb; } + B rf = fill_both(w, x); + dec(w); dec(x); + return qWithFill(rb, rf); +} + + static void shift_check(B w, B x) { ur wr = rnk(w); usz* wsh = a(w)->sh; ur xr = rnk(x); usz* xsh = a(x)->sh; @@ -531,8 +574,8 @@ B shifta_c2(B t, B w, B x) { #define bd(N) bi_##N = mm_alloc(sizeof(BFn), t_funBI, ftag(FUN_TAG)); c(Fun,bi_##N)->c2 = N##_c2 ;c(Fun,bi_##N)->c1 = c1_invalid; c(Fun,bi_##N)->extra=pf_##N; c(BFn,bi_##N)->ident=bi_N; gc_add(bi_##N); #define bm(N) bi_##N = mm_alloc(sizeof(BFn), t_funBI, ftag(FUN_TAG)); c(Fun,bi_##N)->c2 = c2_invalid;c(Fun,bi_##N)->c1 = N##_c1 ; c(Fun,bi_##N)->extra=pf_##N; c(BFn,bi_##N)->ident=bi_N; gc_add(bi_##N); -B bi_shape, bi_pick, bi_pair, bi_select, bi_slash, bi_join, bi_shiftb, bi_shifta, bi_take, bi_drop; -static inline void sfns_init() { ba(shape) ba(pick) ba(pair) ba(select) ba(slash) ba(join) ba(shiftb) ba(shifta) bd(take) bd(drop) +B bi_shape, bi_pick, bi_pair, bi_select, bi_slash, bi_join, bi_couple, bi_shiftb, bi_shifta, bi_take, bi_drop; +static inline void sfns_init() { ba(shape) ba(pick) ba(pair) ba(select) ba(slash) ba(join) ba(couple) ba(shiftb) ba(shifta) bd(take) bd(drop) } #undef ba