diff --git a/src/h.h b/src/h.h index 5a0f541d..86c6fbf2 100644 --- a/src/h.h +++ b/src/h.h @@ -125,7 +125,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") \ - /*sfns.c*/ F(shape,"⥊") F(pick,"⊑") F(pair,"{𝕨‿𝕩}") F(select,"⊏") F(slash,"/") F(join,"∾") F(couple,"≍") F(shiftb,"»") F(shifta,"«") F(take,"↑") F(drop,"↓") F(group,"⊔") \ + /*sfns.c*/ F(shape,"⥊") F(pick,"⊑") F(pair,"{𝕨‿𝕩}") F(select,"⊏") F(slash,"/") F(join,"∾") F(couple,"≍") F(shiftb,"»") F(shifta,"«") F(take,"↑") F(drop,"↓") F(group,"⊔") F(reverse,"⌽") \ /*derv.c*/ F(fork,"(fork)") F(atop,"(atop)") F(md1d,"(derived 1-modifier)") F(md2d,"(derived 2-modifier)") \ /*sort.c*/ F(gradeUp,"⍋") \ /*sysfn.c*/ F(type,"•Type") F(decp,"•Decompose") F(primInd,"•PrimInd") F(glyph,"•Glyph") F(repr,"•Repr") F(fill,"•FillFn") \ diff --git a/src/load.c b/src/load.c index 896107aa..c0613d84 100644 --- a/src/load.c +++ b/src/load.c @@ -62,19 +62,19 @@ static inline void load_init() { comp_currArgs = bi_N; gc_addFn(load_gcFn); 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_couple, bi_take , bi_drop , bi_ud , bi_shifta, bi_shiftb, - /* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ bi_N , bi_N , bi_slash, bi_gradeUp, bi_N , bi_select, bi_pick , bi_N , bi_N , bi_N, - /* ⍷⊔!˙˜˘¨⌜⁼´ */ bi_N , bi_group , 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_under, bi_val , bi_cond , bi_N, - /* ⚇⍟⎊ */ bi_N , bi_repeat, bi_catch + /* +-×÷⋆√⌊⌈|¬ */ 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_couple, bi_take , bi_drop , bi_ud , bi_shifta, bi_shiftb, + /* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ bi_reverse, bi_N , bi_slash, bi_gradeUp, bi_N , bi_select, bi_pick , bi_N , bi_N , bi_N, + /* ⍷⊔!˙˜˘¨⌜⁼´ */ bi_N , bi_group , 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_under, bi_val , bi_cond , bi_N, + /* ⚇⍟⎊ */ bi_N , bi_repeat, bi_catch }; 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,1,1,1,1,1,1, - /* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ 0,0,1,1,0,1,1,0,0,0, + /* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ 1,0,1,1,0,1,1,0,0,0, /* ⍷⊔!˙˜˘¨⌜⁼´ */ 0,1,1,1,1,0,1,1,0,1, /* ˝`∘○⊸⟜⌾⊘◶⎉ */ 0,1,1,1,1,1,1,1,0,0, /* ⚇⍟⎊ */ 0,1,1 @@ -126,6 +126,7 @@ static inline void load_init() { rt_drop = rtObjGet(rtObjRaw, 26); gc_add(rt_drop); rt_group = rtObjGet(rtObjRaw, 41); gc_add(rt_group); rt_under = rtObjGet(rtObjRaw, 56); gc_add(rt_under); + rt_reverse = rtObjGet(rtObjRaw, 30); gc_add(rt_reverse); for (usz i = 0; i < runtimeLen; i++) { #ifdef ALL_R1 diff --git a/src/mut.c b/src/mut.c index a40c0697..138a3263 100644 --- a/src/mut.c +++ b/src/mut.c @@ -110,6 +110,26 @@ void mut_set(Mut* m, usz ms, B x) { // consumes; sets m[ms] to x } #undef AGAIN } +void mut_setS(Mut* m, usz ms, B x) { // consumes; sets m[ms] to x, assumes the current type can store it + switch(m->type) { default: UD; + case el_i32: { assert(q_i32(x)); + m->ai32[ms] = o2iu(x); + return; + } + case el_c32: { assert(isC32(x)); + m->ac32[ms] = o2cu(x); + return; + } + case el_f64: { assert(isF64(x)); + m->af64[ms] = o2fu(x); + return; + } + case el_B: { + m->aB[ms] = x; + return; + } + } +} void mut_rm(Mut* m, usz ms) { // clears the object at position ms if (m->type == el_B) dec(m->aB[ms]); } diff --git a/src/sfns.c b/src/sfns.c index d29ab0b6..76cd2b5c 100644 --- a/src/sfns.c +++ b/src/sfns.c @@ -740,6 +740,54 @@ B group_c2(B t, B w, B x) { return c2(rt_group, w, x); } +B rt_reverse; +B reverse_c1(B t, B x) { + if (isAtm(x) || rnk(x)==0) thrM("⌽: Argument cannot be a unit"); + B xf = getFillQ(x); + u8 xe = TI(x).elType; + usz xia = a(x)->ia; + if (rnk(x)==1) { + if (xe==el_i32) { + i32* xp = i32any_ptr(x); + i32* rp; B r = m_i32arrv(&rp, xia); + for (usz i = 0; i < xia; i++) rp[i] = xp[xia-i-1]; + dec(x); + return r; + } + } + usz csz = arr_csz(x); + usz cam = a(x)->sh[0]; + usz rp = 0; + usz ip = xia; + MAKE_MUT(r, xia); mut_to(r, xe); + for (usz i = 0; i < cam; i++) { + ip-= csz; + mut_copy(r, rp, x, ip, csz); + rp+= csz; + } + return withFill(mut_fcd(r, x), xf); +} +B reverse_c2(B t, B w, B x) { + if (isArr(w)) return c2(rt_reverse, w, x); + if (isAtm(x) || rnk(x)==0) thrM("⌽: 𝕩 must have rank at least 1 for atom 𝕨"); + usz xia = a(x)->ia; + if (xia==0) return x; + B xf = getFillQ(x); + usz cam = a(x)->sh[0]; + usz csz = arr_csz(x); + i64 am = o2i64(w); + if (am<0 || am>=cam) { am%= cam; if(am<0) am+= cam; } + am*= csz; + MAKE_MUT(r, xia); mut_to(r, TI(x).elType); + mut_copy(r, 0, x, am, xia-am); + mut_copy(r, xia-am, x, 0, am); + return withFill(mut_fcd(r, x), xf); +} + +B reverse_uc1(B t, B o, B x) { + return reverse_c1(t, c1(o, reverse_c1(t, x))); +} + B pick_uc1(B t, B o, B x) { if (isAtm(x) || a(x)->ia==0) return def_fn_uc1(t, o, x); usz ia = a(x)->ia; @@ -858,6 +906,18 @@ B select_ucw(B t, B o, B w, B x) { return x; } } + MAKE_MUT(r, xia); mut_to(r, el_or(TI(x).elType, TI(rep).elType)); + mut_copy(r, 0, x, 0, xia); + BS2B rget = TI(rep).get; + for (usz i = 0; i < wia; i++) { + i64 cw = wp[i]; if (cw<0) cw+= (i64)xia; // oob already checked by original select_c2 call + B cr = rget(rep, i); + EQ(!equal(mut_getU(r, cw), cr)); + mut_rm(r, cw); + mut_setS(r, cw, cr); + } + dec(w); dec(rep); + return mut_fcd(r, x); } MAKE_MUT(r, xia); mut_to(r, el_or(TI(x).elType, TI(rep).elType)); mut_copy(r, 0, x, 0, xia); @@ -875,10 +935,11 @@ B select_ucw(B t, B o, B w, B x) { } -#define F(A,M,D) A(shape) A(pick) A(pair) A(select) A(slash) A(join) A(couple) A(shiftb) A(shifta) A(take) A(drop) A(group) +#define F(A,M,D) A(shape) A(pick) A(pair) A(select) A(slash) A(join) A(couple) A(shiftb) A(shifta) A(take) A(drop) A(group) A(reverse) BI_FNS0(F); static inline void sfns_init() { BI_FNS1(F) c(BFn,bi_pick)->uc1 = pick_uc1; + c(BFn,bi_reverse)->uc1 = reverse_uc1; c(BFn,bi_pick)->ucw = pick_ucw; c(BFn,bi_slash)->ucw = slash_ucw; c(BFn,bi_select)->ucw = select_ucw;