diff --git a/.gitignore b/.gitignore index 2ab2f8e7..59df3a8b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ main.s BQN src/runtime +src/runtime1 src/compiler src/interp src/formatter diff --git a/genRuntime b/genRuntime index 2edf4049..0417e032 100755 --- a/genRuntime +++ b/genRuntime @@ -3,6 +3,6 @@ if [[ $# -ne 1 ]]; then echo "Usage: ./genRuntime path/to/mlochbaum/BQN" exit fi -./cc.bqn $1 r > src/runtime +./cc.bqn $1 r1 > src/runtime1 ./cc.bqn $1 c > src/compiler ./cc.bqn $1 f > src/formatter diff --git a/src/derv.c b/src/derv.c index 19989f0b..4a92fccb 100644 --- a/src/derv.c +++ b/src/derv.c @@ -46,8 +46,8 @@ B md1D_c1(B t, B x) { return c(Md1,c(Md1D, t)->m1)->c1(t, x); } B md1D_c2(B t, B w, B x) { return c(Md1,c(Md1D, t)->m1)->c2(t, w, x); } B md2D_c1(B t, B x) { return c(Md2,c(Md2D, t)->m2)->c1(t, x); } B md2D_c2(B t, B w, B x) { return c(Md2,c(Md2D, t)->m2)->c2(t, w, x); } -B atop_c1(B t, B x) { return c1(c(Atop,t)->g, c1(c(Atop,t)->h, x)); } -B atop_c2(B t, B w, B x) { return c1(c(Atop,t)->g, c2(c(Atop,t)->h, w, x)); } +B tr2D_c1(B t, B x) { return c1(c(Atop,t)->g, c1(c(Atop,t)->h, x)); } +B tr2D_c2(B t, B w, B x) { return c1(c(Atop,t)->g, c2(c(Atop,t)->h, w, x)); } B fork_c1(B t, B x) { B g=c1(c(Fork,t)->h, inc(x)); return c2(c(Fork,t)->g, c1(c(Fork,t)->f, x), g); } B fork_c2(B t, B w, B x) { B g=c2(c(Fork,t)->h, inc(w), inc(x)); return c2(c(Fork,t)->g, c2(c(Fork,t)->f, w, x), g); } B md2H_c1(B d, B x) { Md1D* m=c(Md1D,d); Md2H* t=c(Md2H,m->m1); return md2D_c1(m_md2D(t->m2, m->f, t->g), x); } @@ -64,7 +64,7 @@ B m_md1D(B m, B f ) { B r = mm_alloc(sizeof(Md1D), t_md1D, ftag(FUN_TAG)); c B m_md2D(B m, B f, B g) { B r = mm_alloc(sizeof(Md2D), t_md2D, ftag(FUN_TAG)); c(Md2D,r)->f = f; c(Md2D,r)->m2 = m; c(Md2D,r)->g = g; c(Md2D,r)->c1=md2D_c1; c(Md2D,r)->c2=md2D_c2; c(Md2D,r)->extra=pf_md2d; return r; } B m_md2H(B m, B g) { B r = mm_alloc(sizeof(Md2H), t_md2H, ftag(MD1_TAG)); c(Md2H,r)->m2 = m; c(Md2H,r)->g = g; c(Md2H,r)->c1=md2H_c1; c(Md2H,r)->c2=md2H_c2; return r; } B m_fork(B f, B g, B h) { B r = mm_alloc(sizeof(Fork), t_fork, ftag(FUN_TAG)); c(Fork,r)->f = f; c(Fork,r)->g = g; c(Fork,r)->h = h; c(Fork,r)->c1=fork_c1; c(Fork,r)->c2=fork_c2; c(Fork,r)->extra=pf_fork; return r; } -B m_atop( B g, B h) { B r = mm_alloc(sizeof(Atop), t_atop, ftag(FUN_TAG)); c(Atop,r)->g = g; c(Atop,r)->h = h; c(Atop,r)->c1=atop_c1; c(Atop,r)->c2=atop_c2; c(Atop,r)->extra=pf_atop; return r; } +B m_atop( B g, B h) { B r = mm_alloc(sizeof(Atop), t_atop, ftag(FUN_TAG)); c(Atop,r)->g = g; c(Atop,r)->h = h; c(Atop,r)->c1=tr2D_c1; c(Atop,r)->c2=tr2D_c2; c(Atop,r)->extra=pf_atop; return r; } // consume all args B m1_d(B m, B f ) { if(isMd1(m)) return TI(m).m1_d(m, f ); thrM("Interpreting non-1-modifier as 1-modifier"); } diff --git a/src/h.h b/src/h.h index 17dc53e0..86676ade 100644 --- a/src/h.h +++ b/src/h.h @@ -26,6 +26,7 @@ #define usz u32 #define ur u8 +#define UR_MAX 255 #define CTR_FOR(F) #define CTR_DEF(N) u64 N; @@ -87,10 +88,12 @@ char* format_type(u8 u) { } #define FOR_PF(F) F(none, "(unknown fn)") \ - F(add,"+") F(sub,"-") F(mul,"×") F(div,"÷") F(pow,"⋆") F(floor,"⌊") F(ceil,"⌈") F(stile,"|") F(eq,"=") F(ne,"≠") F(le,"≤") F(ge,"≥") F(lt,"<") F(gt,">") F(and,"∧") F(or,"∨") F(not,"¬") F(log,"⋆⁼") /*arith.c*/ \ - F(shape,"⥊") F(pick,"⊑") F(ud,"↕") F(pair,"{𝕨‿𝕩}") F(fne,"≢") F(feq,"≡") F(select,"⊏") F(slash,"/") F(ltack,"⊣") F(rtack,"⊢") F(fmtF,"⍕") F(fmtN,"⍕") /*sfns.c*/ \ - F(fork,"(fork)") F(atop,"(atop)") F(md1d,"(derived 1-modifier)") F(md2d,"(derived 2-modifier)") /*derv.c*/ \ - F(type,"•Type") F(decp,"•Decompose") F(primInd,"•PrimInd") F(glyph,"•Glyph") F(fill,"•FillFn") /*sysfn.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,"⋆⁼") /*arith.c*/ \ + F(shape,"⥊") F(pick,"⊑") F(ud,"↕") F(pair,"{𝕨‿𝕩}") F(fne,"≢") F(feq,"≡") F(select,"⊏") /*sfns.c*/ \ + F(slash,"/") F(ltack,"⊣") F(rtack,"⊢") F(fmtF,"⍕") F(fmtN,"⍕") F(join,"∾") F(take,"↑") F(drop,"↓") /*sfns.c*/ \ + F(fork,"(fork)") F(atop,"(atop)") F(md1d,"(derived 1-modifier)") F(md2d,"(derived 2-modifier)") /*derv.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") /*sysfn.c*/ enum PrimFns { @@ -107,22 +110,23 @@ char* format_pf(u8 u) { } enum PrimMd1 { pm1_none, - pm1_tbl, pm1_each, pm1_fold, pm1_scan, // md1.c + pm1_tbl, pm1_each, pm1_fold, pm1_scan, pm1_const, pm1_swap, // md1.c }; char* format_pm1(u8 u) { switch(u) { default: case pf_none: return"(unknown 1-modifier)"; - case pm1_tbl: return"⌜"; case pm1_each: return"¨"; case pm1_fold: return"´"; case pm1_scan: return"`"; + case pm1_tbl:return"⌜"; case pm1_each:return"¨"; case pm1_fold:return"´"; case pm1_scan:return"`"; case pm1_const:return"˙"; case pm1_swap:return"˜"; } } enum PrimMd2 { pm2_none, - pm2_val, pm2_before, pm2_repeat, pm2_fillBy, pm2_catch, // md2.c + pm2_val, pm2_atop, pm2_over, pm2_before, pm2_after, pm2_cond, pm2_repeat, pm2_fillBy, pm2_catch, // md2.c }; char* format_pm2(u8 u) { switch(u) { default: case pf_none: return"(unknown 1-modifier)"; - case pm2_val: return"⊘"; case pm2_before: return"⊸"; case pm2_repeat: return"⍟"; case pm2_fillBy: return"•_fillBy_"; case pm2_catch: return"⎊"; + case pm2_val:return"⊘"; case pm2_repeat:return"⍟"; case pm2_fillBy:return"•_fillBy_"; case pm2_catch:return"⎊"; + case pm2_atop:return"∘"; case pm2_over:return"○"; case pm2_before:return"⊸"; case pm2_after:return"⟜"; case pm2_cond:return"◶"; } } diff --git a/src/main.c b/src/main.c index 030c3eaa..885cc3f8 100644 --- a/src/main.c +++ b/src/main.c @@ -99,21 +99,21 @@ int main() { // fake runtime 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_N , bi_N , bi_N , bi_N , bi_ud , bi_N , bi_N, - /* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ 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_N , bi_N , bi_N , bi_each , bi_tbl , bi_N , bi_fold, - /* ˝`∘○⊸⟜⌾⊘◶⎉ */ bi_N , bi_scan , bi_N , bi_N , bi_before, bi_N , bi_N , bi_val , bi_N , bi_N, + /* +-×÷⋆√⌊⌈|¬ */ 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_N , bi_N, + /* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ 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, /* ⚇⍟⎊ */ 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,0,0,0,0,0,0,0, - /* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ 0,0,1,0,0,1,0,0,0,0, - /* ⍷⊔!˙˜˘¨⌜⁼´ */ 0,0,1,0,0,0,1,1,0,1, - /* ˝`∘○⊸⟜⌾⊘◶⎉ */ 0,1,0,0,1,0,0,1,0,0, + /* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ 0,0,1,0,0,0,0,0,0,0, + /* ⍷⊔!˙˜˘¨⌜⁼´ */ 0,0,1,1,1,0,1,1,0,1, + /* ˝`∘○⊸⟜⌾⊘◶⎉ */ 0,1,1,1,1,1,0,1,0,0, /* ⚇⍟⎊ */ 0,1,1 }; assert(sizeof(fruntime)/sizeof(B) == rtLen); @@ -121,9 +121,10 @@ int main() { B frtObj = m_caB(rtLen, fruntime); B provide[] = {bi_type,bi_fill,bi_log,bi_grLen,bi_grOrd,bi_asrt,bi_add,bi_sub,bi_mul,bi_div,bi_pow,bi_floor,bi_eq,bi_le,bi_fne,bi_shape,bi_pick,bi_ud,bi_tbl,bi_scan,bi_fillBy,bi_val,bi_catch}; + B runtime_0[] = {bi_floor, bi_ceil, bi_stile, bi_lt, bi_gt, bi_ne, bi_ge, bi_rtack, bi_ltack, bi_join, bi_take, bi_drop, bi_select, bi_const, bi_swap, bi_fold, bi_atop, bi_over, bi_before, bi_after, bi_cond, bi_repeat}; Block* runtime_b = compile( - #include "runtime" + #include "runtime1" ); B rtRes = m_funBlock(runtime_b, 0); ptr_dec(runtime_b); B rtObjRaw = TI(rtRes).get(rtRes,0); diff --git a/src/md1.c b/src/md1.c index 5c5c7ea6..d0edf020 100644 --- a/src/md1.c +++ b/src/md1.c @@ -114,6 +114,12 @@ B fold_c2(B d, B w, B x) { B f = c(Md1D,d)->f; return c; } +B const_c1(B d , B x) { dec(x); return inc(c(Md1D,d)->f); } +B const_c2(B d, B w, B x) { dec(w); dec(x); return inc(c(Md1D,d)->f); } + +B swap_c1(B d , B x) { return c2(c(Md1D,d)->f, inc(x), x); } +B swap_c2(B d, B w, B x) { return c2(c(Md1D,d)->f, x , w); } + #define ba(NAME) bi_##NAME = mm_alloc(sizeof(Md1), t_md1BI, ftag(MD1_TAG)); c(Md1,bi_##NAME)->c2 = NAME##_c2; c(Md1,bi_##NAME)->c1 = NAME##_c1 ; c(Md1,bi_##NAME)->extra=pm1_##NAME; gc_add(bi_##NAME); #define bd(NAME) bi_##NAME = mm_alloc(sizeof(Md1), t_md1BI, ftag(MD1_TAG)); c(Md1,bi_##NAME)->c2 = NAME##_c2; c(Md1,bi_##NAME)->c1 = c1_invalid; c(Md1,bi_##NAME)->extra=pm1_##NAME; gc_add(bi_##NAME); @@ -121,8 +127,8 @@ B fold_c2(B d, B w, B x) { B f = c(Md1D,d)->f; void print_md1_def(B x) { printf("%s", format_pm1(c(Md1,x)->extra)); } -B bi_tbl, bi_each, bi_fold, bi_scan; -static inline void md1_init() { ba(tbl) ba(each) ba(fold) ba(scan) +B bi_tbl, bi_each, bi_fold, bi_scan, bi_const, bi_swap; +static inline void md1_init() { ba(tbl) ba(each) ba(fold) ba(scan) ba(const) ba(swap) ti[t_md1BI].print = print_md1_def; } diff --git a/src/md2.c b/src/md2.c index 7da14daa..9f8ad5ab 100644 --- a/src/md2.c +++ b/src/md2.c @@ -94,11 +94,28 @@ B repeat_c1(B d, B x) { REPEAT_T(c1,{} ); } B repeat_c2(B d, B w, B x) { REPEAT_T(c2,dec(w), inc(w), ); } #undef REPEAT_T -B before_c1(B d, B x) { - return c2(c(Md2D,d)->g, c1(c(Md2D,d)->f, inc(x)), x); +B before_c1(B d, B x) { return c2(c(Md2D,d)->g, c1(c(Md2D,d)->f, inc(x)), x); } +B before_c2(B d, B w, B x) { return c2(c(Md2D,d)->g, c1(c(Md2D,d)->f, w ), x); } +B after_c1(B d, B x) { return c2(c(Md2D,d)->f, x, c1(c(Md2D,d)->g, inc(x))); } +B after_c2(B d, B w, B x) { return c2(c(Md2D,d)->f, w, c1(c(Md2D,d)->g, x )); } +B atop_c1(B d, B x) { return c1(c(Md2D,d)->f, c1(c(Md2D,d)->g, x)); } +B atop_c2(B d, B w, B x) { return c1(c(Md2D,d)->f, c2(c(Md2D,d)->g, w, x)); } +B over_c1(B d, B x) { return c1(c(Md2D,d)->f, c1(c(Md2D,d)->g, x)); } +B over_c2(B d, B w, B x) { B xr=c1(c(Md2D,d)->g, x); return c2(c(Md2D,d)->f, c1(c(Md2D,d)->g, w), xr); } + +B cond_c1(B d, B x) { B g=c(Md2D,d)->g; + if (!isArr(g)||rnk(g)!=1) thrM("◶: 𝕘 must have rank 1"); + i64 fr = o2i64(c1(c(Md2D,d)->f, inc(x))); + if (fr<0) fr+= a(g)->ia; + if ((u64)fr >= a(g)->ia) thrM("◶: 𝔽 out of bounds of 𝕘"); + return c1(TI(g).getU(g, fr), x); } -B before_c2(B d, B w, B x) { - return c2(c(Md2D,d)->g, c1(c(Md2D,d)->f, w), x); +B cond_c2(B d, B w, B x) { B g=c(Md2D,d)->g; + if (!isArr(g)||rnk(g)!=1) thrM("◶: 𝕘 must have rank 1"); + i64 fr = o2i64(c2(c(Md2D,d)->f, inc(w), inc(x))); + if (fr<0) fr+= a(g)->ia; + if ((u64)fr >= a(g)->ia) thrM("◶: 𝔽 out of bounds of 𝕘"); + return c2(TI(g).getU(g, fr), w, x); } #define ba(NAME) bi_##NAME = mm_alloc(sizeof(Md2), t_md2BI, ftag(MD2_TAG)); c(Md2,bi_##NAME)->c2 = NAME##_c2; c(Md2,bi_##NAME)->c1 = NAME##_c1; c(Md2,bi_##NAME)->extra=pm2_##NAME; gc_add(bi_##NAME); @@ -107,8 +124,8 @@ B before_c2(B d, B w, B x) { void print_md2_def(B x) { printf("%s", format_pm2(c(Md1,x)->extra)); } -B bi_val, bi_repeat, bi_before, bi_fillBy, bi_catch; -static inline void md2_init() { ba(val) ba(repeat) ba(before) ba(fillBy) ba(catch) +B bi_val, bi_repeat, bi_atop, bi_over, bi_before, bi_after, bi_cond, bi_fillBy, bi_catch; +static inline void md2_init() { ba(val) ba(repeat) ba(atop) ba(over) ba(before) ba(after) ba(cond) ba(fillBy) ba(catch) ti[t_md2BI].print = print_md2_def; } diff --git a/src/sfns.c b/src/sfns.c index 84419845..a5a8be29 100644 --- a/src/sfns.c +++ b/src/sfns.c @@ -150,7 +150,7 @@ B eachd(B f, B w, B x) { // complete w F¨ x ur mr = rnk(w); if(rnk(w)sh, a(x)->sh, mr)) { decR(x); thrM("Mapping: Expected equal shape prefix"); } } - if (isMd(f)) if ((isArr(w)&&a(w)->ia) || (isArr(x)&&a(x)->ia)) { decR(x); thrM("Calling a modifier"); } // case where both are scalars has already been taken care of + if (isMd(f)) if ((isArr(w)&&a(w)->ia) || (isArr(x)&&a(x)->ia)) { decR(x); thrM("Calling a modifier"); } // case where both are units has already been taken care of HArr_p r = m_harrUc(!isArr(w)? x : rnk(w)>rnk(x)? w : x); for(usz i = 0; i < r.c->ia; i++) r.a[i] = inc(f); @@ -310,23 +310,50 @@ B select_c1(B t, B x) { return r; } B select_c2(B t, B w, B x) { - if (isArr(w) && isArr(x) && rnk(w)==1 && rnk(x)==1) { - usz wia = a(w)->ia; - usz xia = a(x)->ia; + if (isArr(w) && isArr(x)) { B xf = getFill(inc(x)); - HArr_p r = m_harrUc(w); BS2B wgetU = TI(w).getU; BS2B xget = TI(x).get; - for (usz i = 0; i < wia; i++) { - B cw = wgetU(w, i); - if (!isNum(cw)) { harr_pfree(r.b, i); goto base; } - f64 c = o2f(cw); - if (c<0) c+= xia; - if (c!=(usz)c | c>=xia) { harr_pfree(r.b, i); goto base; } - r.a[i] = xget(x, c); + if (rnk(x)==1) { + usz wia = a(w)->ia; + usz xia = a(x)->ia; + HArr_p r = m_harrUc(w); + for (usz i = 0; i < wia; i++) { + B cw = wgetU(w, i); + if (!isNum(cw)) { harr_pfree(r.b, i); goto base; } + f64 c = o2f(cw); + if (c<0) c+= xia; + if ((usz)c >= xia) thrM("⊏: Indexing out-of-bounds"); + r.a[i] = xget(x, c); + } + dec(w); dec(x); + return withFill(r.b,xf); + } else { + ur wr = rnk(w); usz wia = a(w)->ia; + ur xr = rnk(x); + u32 rr = wr+xr-1; + if (xr==0) thrM("⊏: 𝕩 cannot be a unit"); + if (rr>UR_MAX) thrM("⊏: Result rank too large"); + usz csz = arr_csz(x); + usz cam = a(x)->sh[0]; + usz ria = wia*csz; + HArr_p r = m_harrUp(ria); + usz* rsh = arr_shAllocR(r.b, rr); + if (rsh) { + memcpy(rsh , a(w)->sh , wr *sizeof(usz)); + memcpy(rsh+wr, a(x)->sh+1, (xr-1)*sizeof(usz)); + } + for (usz i = 0; i < wia; i++) { + B cw = wgetU(w, i); + if (!isNum(cw)) { harr_pfree(r.b, i); goto base; } + f64 c = o2f(cw); + if (c<0) c+= cam; + if ((usz)c >= cam) thrM("⊏: Indexing out-of-bounds"); + for (usz j = 0; j < csz; j++) r.a[i*csz+j] = xget(x, c*csz+j); + } + dec(w); dec(x); + return withFill(r.b,xf); } - dec(w); dec(x); - return withFill(r.b,xf); } base: return c2(rt_select, w, x); @@ -396,14 +423,41 @@ B slash_c2(B t, B w, B x) { return c2(rt_slash, w, x); } +B slicev(B x, usz s, usz ia) { + usz xia = a(x)->ia; if (s+ia>xia) thrM("↑/↓: NYI fills"); + B r = TI(x).slice(x, s); + arr_shVec(r, ia); + return r; +} +B take_c2(B t, B w, B x) { + if (!isArr(x) || rnk(x)!=1) thrM("↑: NYI 1≠=𝕩"); + i64 v = o2i64(w); usz ia = a(x)->ia; + return v<0? slicev(x, ia+v, -v) : slicev(x, 0, v); +} +B drop_c2(B t, B w, B x) { + if (!isArr(x) || rnk(x)!=1) thrM("↓: NYI 1≠=𝕩"); + i64 v = o2i64(w); usz ia = a(x)->ia; + return v<0? slicev(x, 0, v+ia) : slicev(x, v, ia-v); +} +B join_c2(B t, B w, B x) { + if (!isArr(w)|!isArr(x) || rnk(w)!=1 | rnk(x)!=1) thrM("∾: NYI non-vector args"); + usz wia = a(w)->ia; BS2B wget = TI(w).get; + usz xia = a(x)->ia; BS2B xget = TI(x).get; + HArr_p r = m_harrUv(wia+xia); + for (i64 i = 0; i < wia; i++) r.a[i ] = wget(w, i); + for (i64 i = 0; i < xia; i++) r.a[i+wia] = xget(x, i); + dec(x); dec(w); + return r.b; +} + #define ba(N) bi_##N = mm_alloc(sizeof(BFn), t_funBI, ftag(FUN_TAG)); c(Fun,bi_##N)->c2 = N##_c2 ;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); #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); void print_fun_def(B x) { printf("%s", format_pf(c(Fun,x)->extra)); } -B bi_shape, bi_pick, bi_ud, bi_pair, bi_fne, bi_feq, bi_select, bi_slash, bi_ltack, bi_rtack, bi_fmtF, bi_fmtN; -static inline void sfns_init() { ba(shape) ba(pick) bm(ud) ba(pair) ba(fne) ba(feq) ba(select) ba(slash) ba(ltack) ba(rtack) bm(fmtF) bm(fmtN) +B bi_shape, bi_pick, bi_ud, bi_pair, bi_fne, bi_feq, bi_select, bi_slash, bi_ltack, bi_rtack, bi_join, bi_take, bi_drop, bi_fmtF, bi_fmtN; +static inline void sfns_init() { ba(shape) ba(pick) bm(ud) ba(pair) ba(fne) ba(feq) ba(select) ba(slash) ba(ltack) ba(rtack) bd(join) bd(take) bd(drop) bm(fmtF) bm(fmtN) ti[t_funBI].print = print_fun_def; ti[t_funBI].identity = funBI_identity; }