diff --git a/src/builtins/md2.c b/src/builtins/md2.c index b483dd24..9341cb4a 100644 --- a/src/builtins/md2.c +++ b/src/builtins/md2.c @@ -98,10 +98,10 @@ 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_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 before_c1(B d, B x) { return c2(c(Md2D,d)->g, c1i(c(Md2D,d)->f, inc(x)), x); } +B before_c2(B d, B w, B x) { return c2(c(Md2D,d)->g, c1i(c(Md2D,d)->f, w ), x); } +B after_c1(B d, B x) { return c2(c(Md2D,d)->f, x, c1i(c(Md2D,d)->g, inc(x))); } +B after_c2(B d, B w, B x) { return c2(c(Md2D,d)->f, w, c1i(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)); } diff --git a/src/core/derv.c b/src/core/derv.c index d0c770e7..956d5d07 100644 --- a/src/core/derv.c +++ b/src/core/derv.c @@ -24,8 +24,8 @@ 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 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 fork_c1(B t, B x) { B g=c1(c(Fork,t)->h, inc(x)); return c2(c(Fork,t)->g, c1i(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, c2i(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); } B md2H_c2(B d, B w, B x) { Md1D* m=c(Md1D,d); Md2H* t=c(Md2H,m->m1); return md2D_c2(m_md2D(t->m2, m->f, t->g), w, x); } diff --git a/src/h.h b/src/h.h index d3f69b56..b0402b28 100644 --- a/src/h.h +++ b/src/h.h @@ -452,6 +452,19 @@ static B c2(B f, B w, B x) { // BQN-call f dyadically; consumes w,x if (isFun(f)) return VALIDATE(c(Fun,f)->c2(f, w, x)); return c2_rare(f, w, x); } +// like c1/c2, but with less overhead on non-functions +static B c1i(B f, B x) { + if (isFun(f)) return VALIDATE(c(Fun,f)->c1(f, x)); + dec(x); + if (isMd(f)) thrM("Calling a modifier"); + return inc(VALIDATE(f)); +} +static B c2i(B f, B w, B x) { + if (isFun(f)) return VALIDATE(c(Fun,f)->c2(f, w, x)); + dec(w); dec(x); + if (isMd(f)) thrM("Calling a modifier"); + return inc(VALIDATE(f)); +} typedef struct Md1 {