inverse modifiers

This commit is contained in:
dzaima 2021-11-25 00:24:16 +02:00
parent b76d30d4bc
commit 0389eda29b
7 changed files with 118 additions and 53 deletions

View File

@ -38,6 +38,8 @@ enum PrimNumbers {
/* ⎉⚇⍟⎊ */ n_cells , n_depth2 , n_repeat, n_catch
};
extern B rt_invFnReg, rt_invFnSwap;
extern BB2B rt_invFnRegFn;
extern BB2B rt_invFnSwapFn;
enum PrimFns { pf_none,
#define F(N,X) pf_##N,

View File

@ -3,26 +3,12 @@
#include "../nfns.h"
static NFnDesc* fun_invRegDesc;
static NFnDesc* fun_invSwapDesc;
B fun_invReg_c1(B t, B x) {
B f = nfn_objU(t);
return TI(f, fn_im)(f, x);
}
B fun_invReg_c2(B t, B w, B x) {
B f = nfn_objU(t);
return TI(f, fn_ix)(f, w, x);
}
B fun_invSwap_c1(B t, B x) {
B f = nfn_objU(t);
return TI(f, fn_is)(f, x);
}
B fun_invSwap_c2(B t, B w, B x) {
B f = nfn_objU(t);
return TI(f, fn_iw)(f, w, x);
}
static NFnDesc* fn_invRegDesc;
static NFnDesc* fn_invSwapDesc;
B fn_invReg_c1 (B t, B x) { B f = nfn_objU(t); return TI(f, fn_im)(f, x); }
B fn_invReg_c2 (B t, B w, B x) { B f = nfn_objU(t); return TI(f, fn_ix)(f, w, x); }
B fn_invSwap_c1(B t, B x) { B f = nfn_objU(t); return TI(f, fn_is)(f, x); }
B fn_invSwap_c2(B t, B w, B x) { B f = nfn_objU(t); return TI(f, fn_iw)(f, w, x); }
extern B rt_undo;
B undo_c1(Md1D* d, B x) { B f = d->f;
@ -40,18 +26,18 @@ B undo_c2(Md1D* d, B w, B x) { B f = d->f;
return r;
}
B setInvReg_c1 (B t, B x) { rt_invFnReg = x; return inc(bi_nativeInvReg); }
B setInvSwap_c1(B t, B x) { rt_invFnSwap = x; return inc(bi_nativeInvSwap); }
B setInvReg_c1 (B t, B x) { rt_invFnReg = x; rt_invFnRegFn = c(Fun,x)->c1; return inc(bi_nativeInvReg); }
B setInvSwap_c1(B t, B x) { rt_invFnSwap = x; rt_invFnSwapFn = c(Fun,x)->c1; return inc(bi_nativeInvSwap); }
B nativeInvReg_c1(B t, B x) {
if (isFun(x)) return m_nfn(fun_invRegDesc, x);
if (isFun(x)) return m_nfn(fn_invRegDesc, x);
return c1(rt_invFnReg, x);
}
B nativeInvSwap_c1(B t, B x) {
if (isFun(x)) return m_nfn(fun_invSwapDesc, x);
if (isFun(x)) return m_nfn(fn_invSwapDesc, x);
return c1(rt_invFnSwap, x);
}
void inverse_init() {
fun_invRegDesc = registerNFn(m_str8l("(fun_invReg)"), fun_invReg_c1, fun_invReg_c2);
fun_invSwapDesc = registerNFn(m_str8l("(fun_invSwap)"), fun_invSwap_c1, fun_invSwap_c2);
fn_invRegDesc = registerNFn(m_str8l("(fn_invReg)"), fn_invReg_c1, fn_invReg_c2);
fn_invSwapDesc = registerNFn(m_str8l("(fn_invSwap)"), fn_invSwap_c1, fn_invSwap_c2);
}

View File

@ -43,6 +43,13 @@ typedef struct BFn {
BB2B im;
B rtInvReg;
} BFn;
typedef struct BMd1 {
struct Md1;
M1C1 im;
M1C2 iw;
M1C2 ix;
} BMd1;
typedef struct BMd2 {
struct Md2;
BBBBB2B uc1;

View File

@ -93,6 +93,14 @@ static B ucwWrap_c1(B t, B x) {
return TI(g,fn_ucw)(g, args[1], args[2], x);
}
// TODO (+ md2D_uc1 and probably more things in the future): remove flags checks when all builtins have at least native wrappers
static B md1D_im(B t, B x) { Md1D* d = c(Md1D,t); return isMd1(d->m1) && !d->flags? TI(d->m1,m1_im)(d, x) : def_fn_im(t, x); }
static B md1D_iw(B t, B w, B x) { Md1D* d = c(Md1D,t); return isMd1(d->m1) && !d->flags? TI(d->m1,m1_iw)(d, w, x) : def_fn_iw(t, w, x); }
static B md1D_ix(B t, B w, B x) { Md1D* d = c(Md1D,t); return isMd1(d->m1) && !d->flags? TI(d->m1,m1_ix)(d, w, x) : def_fn_ix(t, w, x); }
static B md2D_im(B t, B x) { Md2D* d = c(Md2D,t); return isMd2(d->m2) && !d->flags? TI(d->m2,m2_im)(d, x) : def_fn_im(t, x); }
static B md2D_iw(B t, B w, B x) { Md2D* d = c(Md2D,t); return isMd2(d->m2) && !d->flags? TI(d->m2,m2_iw)(d, w, x) : def_fn_iw(t, w, x); }
static B md2D_ix(B t, B w, B x) { Md2D* d = c(Md2D,t); return isMd2(d->m2) && !d->flags? TI(d->m2,m2_ix)(d, w, x) : def_fn_ix(t, w, x); }
void derv_init() {
TIi(t_md1D,freeO) = md1D_freeO; TIi(t_md1D,freeF) = md1D_freeF; TIi(t_md1D,visit) = md1D_visit; TIi(t_md1D,print) = md1D_print; TIi(t_md1D,decompose) = md1D_decompose;
@ -103,8 +111,11 @@ void derv_init() {
TIi(t_md1BI,m1_d) = m_md1D;
TIi(t_md2BI,m2_d) = m_md2D;
TIi(t_md2D,fn_uc1) = md2D_uc1; // not in post so later init can utilize it
TIi(t_md1D,fn_im) = md1D_im; TIi(t_md2D,fn_im) = md2D_im;
TIi(t_md1D,fn_iw) = md1D_iw; TIi(t_md2D,fn_iw) = md2D_iw;
TIi(t_md1D,fn_ix) = md1D_ix; TIi(t_md2D,fn_ix) = md2D_ix;
}
void dervPost_init() {
ucwWrapDesc = registerNFn(m_str8l("(temporary function for ⌾)"), ucwWrap_c1, c2_bad);
TIi(t_fork,fn_uc1) = fork_uc1;
TIi(t_fork,fn_uc1) = fork_uc1; // in post probably to make sure it's not used while not fully initialized or something? idk
}

15
src/h.h
View File

@ -449,10 +449,17 @@ typedef B (*M2C2)(Md2D*, B, B);
F( BBBBB2B, m1_ucw) /* t,o,f, w,x→r; r≡O⌾(w⊸(F _T )) x; consumes w,x */ \
F( BBBBB2B, m2_uc1) /* t,o,f,g, x→r; r≡O⌾( F _T_ G ) x; consumes x */ \
F(BBBBBB2B, m2_ucw) /* t,o,f,g,w,x→r; r≡O⌾(w⊸(F _T_ G)) x; consumes w,x */ \
F( BB2B, fn_im) /* t, x; function monadic inverse; consumes x */ \
F( BB2B, fn_is) /* t, x; function equal-arg inverse; consumes x */ \
F( BBB2B, fn_iw) /* t,w,x; function dyadic 𝕨-inverse; consumes w,x */ \
F( BBB2B, fn_ix) /* t,w,x; function dyadic 𝕩-inverse; consumes w,x */ \
\
F( BB2B, fn_im) /* t, x; function monadic inverse; consumes x */ \
F( BB2B, fn_is) /* t, x; function equal-arg inverse; consumes x */ \
F(BBB2B, fn_iw) /* t,w,x; function dyadic 𝕨-inverse; consumes w,x */ \
F(BBB2B, fn_ix) /* t,w,x; function dyadic 𝕩-inverse; consumes w,x */ \
F( M1C1, m1_im) /* d, x; 1-modifier monadic inverse; consumes x */ \
F( M1C2, m1_iw) /* d,w,x; 1-modifier dyadic 𝕨-inverse; consumes w,x */ \
F( M1C2, m1_ix) /* d,w,x; 1-modifier dyadic 𝕩-inverse; consumes w,x */ \
F( M2C1, m2_im) /* d, x; 2-modifier monadic inverse; consumes x */ \
F( M2C2, m2_iw) /* d,w,x; 2-modifier dyadic 𝕨-inverse; consumes w,x */ \
F( M2C2, m2_ix) /* d,w,x; 2-modifier dyadic 𝕩-inverse; consumes w,x */ \
\
F(B2b, canStore) /* doesn't consume */ \
F(u8, elType) /* guarantees that the corresponding i32any_ptr/f64any_ptr/c32any_ptr/… always succeeds */ \

View File

@ -407,10 +407,18 @@ static B def_m2_d(B m, B f, B g) { thrM("cannot derive this"); }
static Arr* def_slice(B x, usz s, usz ia) { thrM("cannot slice non-array!"); }
B rt_invFnReg, rt_invFnSwap;
B def_fn_im(B t, B x) { B fn = c(Fun,rt_invFnReg )->c1(rt_invFnReg, inc(t)); B r = c1(fn, x); dec(fn); return r; }
B def_fn_is(B t, B x) { B fn = c(Fun,rt_invFnSwap)->c1(rt_invFnSwap, inc(t)); B r = c1(fn, x); dec(fn); return r; }
B def_fn_iw(B t, B w, B x) { B fn = c(Fun,rt_invFnSwap)->c1(rt_invFnSwap, inc(t)); B r = c2(fn, w, x); dec(fn); return r; }
B def_fn_ix(B t, B w, B x) { B fn = c(Fun,rt_invFnReg )->c1(rt_invFnReg, inc(t)); B r = c2(fn, w, x); dec(fn); return r; }
BB2B rt_invFnRegFn;
BB2B rt_invFnSwapFn;
B def_fn_im(B t, B x) { B fn = rt_invFnRegFn(rt_invFnReg, inc(t)); B r = c1(fn, x); dec(fn); return r; }
B def_fn_is(B t, B x) { B fn = rt_invFnSwapFn(rt_invFnSwap, inc(t)); B r = c1(fn, x); dec(fn); return r; }
B def_fn_iw(B t, B w, B x) { B fn = rt_invFnSwapFn(rt_invFnSwap, inc(t)); B r = c2(fn, w, x); dec(fn); return r; }
B def_fn_ix(B t, B w, B x) { B fn = rt_invFnRegFn(rt_invFnReg, inc(t)); B r = c2(fn, w, x); dec(fn); return r; }
B def_m1_im(Md1D* t, B x) { return def_fn_im(tag(t,FUN_TAG), x); }
B def_m1_iw(Md1D* t, B w, B x) { return def_fn_iw(tag(t,FUN_TAG), w, x); }
B def_m1_ix(Md1D* t, B w, B x) { return def_fn_ix(tag(t,FUN_TAG), w, x); }
B def_m2_im(Md2D* t, B x) { return def_fn_im(tag(t,FUN_TAG), x); }
B def_m2_iw(Md2D* t, B w, B x) { return def_fn_iw(tag(t,FUN_TAG), w, x); }
B def_m2_ix(Md2D* t, B w, B x) { return def_fn_ix(tag(t,FUN_TAG), w, x); }
#ifdef DONT_FREE
static B empty_get(Arr* x, usz n) {
@ -439,6 +447,44 @@ static B funBI_imInit(B t, B x) {
return c1(f, x);
}
static NOINLINE B m_bfn(BB2B c1, BBB2B c2, u8 id) {
BFn* f = mm_alloc(sizeof(BFn), t_funBI);
f->c1 = c1;
f->c2 = c2;
f->extra = id;
f->ident = bi_N;
f->uc1 = def_fn_uc1;
f->ucw = def_fn_ucw;
f->im = funBI_imInit;
f->rtInvReg = m_f64(0);
B r = tag(f,FUN_TAG); gc_add(r);
return r;
}
static NOINLINE B m_bm1(M1C1 c1, M1C2 c2, u8 id) {
BMd1* m = mm_alloc(sizeof(BMd1), t_md1BI);
m->c1 = c1;
m->c2 = c2;
m->extra = id;
m->im = def_m1_im;
m->iw = def_m1_iw;
m->ix = def_m1_ix;
B r = tag(m,MD1_TAG); gc_add(r);
return r;
}
static NOINLINE B m_bm2(M2C1 c1, M2C2 c2, u8 id) {
BMd2* m = mm_alloc(sizeof(BMd2), t_md2BI);
m->c1 = c1;
m->c2 = c2;
m->extra = id;
m->uc1 = def_m2_uc1;
m->ucw = def_m2_ucw;
B r = tag(m,MD2_TAG); gc_add(r);
return r;
}
void base_init() { // very first init function
for (u64 i = 0; i < t_COUNT; i++) {
TIi(i,freeO) = def_freeO;
@ -462,10 +508,10 @@ void base_init() { // very first init function
TIi(i,m1_ucw) = def_m1_ucw;
TIi(i,m2_uc1) = def_m2_uc1;
TIi(i,m2_ucw) = def_m2_ucw;
TIi(i,fn_im) = def_fn_im;
TIi(i,fn_im) = def_fn_im; TIi(i,m1_im) = def_m1_im; TIi(i,m2_im) = def_m2_im;
TIi(i,fn_is) = def_fn_is;
TIi(i,fn_iw) = def_fn_iw;
TIi(i,fn_ix) = def_fn_ix;
TIi(i,fn_iw) = def_fn_iw; TIi(i,m1_iw) = def_m1_iw; TIi(i,m2_iw) = def_m2_iw;
TIi(i,fn_ix) = def_fn_ix; TIi(i,m1_ix) = def_m1_ix; TIi(i,m2_ix) = def_m2_ix;
}
TIi(t_empty,freeO) = empty_free; TIi(t_freed,freeO) = def_freeO;
TIi(t_empty,freeF) = empty_free; TIi(t_freed,freeF) = def_freeF;
@ -481,25 +527,25 @@ void base_init() { // very first init function
TIi(t_funBI,visit) = funBI_visit;
assert((MD1_TAG>>1) == (MD2_TAG>>1)); // just to be sure it isn't changed incorrectly, `isMd` depends on this
#define FA(N,X) { BFn* f = mm_alloc(sizeof(BFn), t_funBI); f->c2=N##_c2; f->c1=N##_c1; f->extra=pf_##N; f->ident=bi_N; f->uc1=def_fn_uc1; f->ucw=def_fn_ucw; f->im=funBI_imInit; f->rtInvReg=m_f64(0); gc_add(bi_##N = tag(f,FUN_TAG)); }
#define FM(N,X) { BFn* f = mm_alloc(sizeof(BFn), t_funBI); f->c2=c2_bad; f->c1=N##_c1; f->extra=pf_##N; f->ident=bi_N; f->uc1=def_fn_uc1; f->ucw=def_fn_ucw; f->im=funBI_imInit; f->rtInvReg=m_f64(0); gc_add(bi_##N = tag(f,FUN_TAG)); }
#define FD(N,X) { BFn* f = mm_alloc(sizeof(BFn), t_funBI); f->c2=N##_c2; f->c1=c1_bad; f->extra=pf_##N; f->ident=bi_N; f->uc1=def_fn_uc1; f->ucw=def_fn_ucw; f->im=funBI_imInit; f->rtInvReg=m_f64(0); gc_add(bi_##N = tag(f,FUN_TAG)); }
#define FA(N,X) bi_##N = m_bfn(N##_c1, N##_c2, pf_##N);
#define FM(N,X) bi_##N = m_bfn(N##_c1, c2_bad, pf_##N);
#define FD(N,X) bi_##N = m_bfn(c1_bad, N##_c2, pf_##N);
FOR_PFN(FA,FM,FD)
#undef FA
#undef FM
#undef FD
#define FA(N,X) { Md1* m = mm_alloc(sizeof(Md1), t_md1BI); m->c2 = N##_c2; m->c1 = N##_c1; m->extra=pm1_##N; gc_add(bi_##N = tag(m,MD1_TAG)); }
#define FM(N,X) { Md1* m = mm_alloc(sizeof(Md1), t_md1BI); m->c2 = c2_bad; m->c1 = N##_c1; m->extra=pm1_##N; gc_add(bi_##N = tag(m,MD1_TAG)); }
#define FD(N,X) { Md1* m = mm_alloc(sizeof(Md1), t_md1BI); m->c2 = N##_c2; m->c1 = c1_bad; m->extra=pm1_##N; gc_add(bi_##N = tag(m,MD1_TAG)); }
#define FA(N,X) bi_##N = m_bm1(N##_c1, N##_c2, pm1_##N);
#define FM(N,X) bi_##N = m_bm1(N##_c1, c2_bad, pm1_##N);
#define FD(N,X) bi_##N = m_bm1(c1_bad, N##_c2, pm1_##N);
FOR_PM1(FA,FM,FD)
#undef FA
#undef FM
#undef FD
#define FA(N,X) { BMd2* m = mm_alloc(sizeof(BMd2), t_md2BI); m->c2 = N##_c2 ; m->c1 = N##_c1; m->extra=pm2_##N; m->uc1=def_m2_uc1; m->ucw=def_m2_ucw; gc_add(bi_##N = tag(m,MD2_TAG)); }
#define FM(N,X) { BMd2* m = mm_alloc(sizeof(BMd2), t_md2BI); m->c2 = N##_c2 ; m->c1 = m1c1_bad; m->extra=pm2_##N; m->uc1=def_m2_uc1; m->ucw=def_m2_ucw; gc_add(bi_##N = tag(m,MD2_TAG)); }
#define FD(N,X) { BMd2* m = mm_alloc(sizeof(BMd2), t_md2BI); m->c2 = m1c2_bad; m->c1 = N##_c1; m->extra=pm2_##N; m->uc1=def_m2_uc1; m->ucw=def_m2_ucw; gc_add(bi_##N = tag(m,MD2_TAG)); }
#define FA(N,X) bi_##N = m_bm2(N##_c1, N##_c2, pm2_##N);
#define FM(N,X) bi_##N = m_bm2(m1c1_bad, N##_c2, pm2_##N);
#define FD(N,X) bi_##N = m_bm2(N##_c1, m1c2_bad, pm2_##N);
FOR_PM2(FA,FM,FD)
#undef FA
#undef FM

View File

@ -819,9 +819,15 @@ B md1Bl_c2(Md1D* d, B w, B x) { Md1Block* b=c(Md1Block, d->m1); ptr_inc(d); retu
B md2Bl_c1(Md2D* d, B x) { Md2Block* b=c(Md2Block, d->m2); ptr_inc(d); return execBlock(b->bl, b->bl->bodies[0], b->sc, 6, (B[]){tag(d,FUN_TAG), x, bi_N, inc(d->m2), inc(d->f), inc(d->g)}); }
B md2Bl_c2(Md2D* d, B w, B x) { Md2Block* b=c(Md2Block, d->m2); ptr_inc(d); return execBlock(b->bl, b->bl->dyBody, b->sc, 6, (B[]){tag(d,FUN_TAG), x, w , inc(d->m2), inc(d->f), inc(d->g)}); }
B funBl_im(B t, B x) { FunBlock* b=c(FunBlock, t ); ptr_inc(b); return execBlock(b->bl, b->bl->invMBody, b->sc, 3, (B[]){t, x, bi_N }); }
B funBl_iw(B t, B w, B x) { FunBlock* b=c(FunBlock, t ); ptr_inc(b); return execBlock(b->bl, b->bl->invWBody, b->sc, 3, (B[]){t, x, w }); }
B funBl_ix(B t, B w, B x) { FunBlock* b=c(FunBlock, t ); ptr_inc(b); return execBlock(b->bl, b->bl->invXBody, b->sc, 3, (B[]){t, x, w }); }
B funBl_im(B t, B x) { FunBlock* b=c(FunBlock, t ); ptr_inc(b); return execBlock(b->bl, b->bl->invMBody, b->sc, 3, (B[]){t, x, bi_N}); }
B funBl_iw(B t, B w, B x) { FunBlock* b=c(FunBlock, t ); ptr_inc(b); return execBlock(b->bl, b->bl->invWBody, b->sc, 3, (B[]){t, x, w }); }
B funBl_ix(B t, B w, B x) { FunBlock* b=c(FunBlock, t ); ptr_inc(b); return execBlock(b->bl, b->bl->invXBody, b->sc, 3, (B[]){t, x, w }); }
B md1Bl_im(Md1D* d, B x) { Md1Block* b=c(Md1Block, d->m1); ptr_inc(d); return execBlock(b->bl, b->bl->invMBody, b->sc, 5, (B[]){tag(d,FUN_TAG), x, bi_N, inc(d->m1), inc(d->f)}); }
B md1Bl_iw(Md1D* d, B w, B x) { Md1Block* b=c(Md1Block, d->m1); ptr_inc(d); return execBlock(b->bl, b->bl->invWBody, b->sc, 5, (B[]){tag(d,FUN_TAG), x, w , inc(d->m1), inc(d->f)}); }
B md1Bl_ix(Md1D* d, B w, B x) { Md1Block* b=c(Md1Block, d->m1); ptr_inc(d); return execBlock(b->bl, b->bl->invXBody, b->sc, 5, (B[]){tag(d,FUN_TAG), x, w , inc(d->m1), inc(d->f)}); }
B md2Bl_im(Md2D* d, B x) { Md2Block* b=c(Md2Block, d->m2); ptr_inc(d); return execBlock(b->bl, b->bl->invMBody, b->sc, 6, (B[]){tag(d,FUN_TAG), x, bi_N, inc(d->m2), inc(d->f), inc(d->g)}); }
B md2Bl_iw(Md2D* d, B w, B x) { Md2Block* b=c(Md2Block, d->m2); ptr_inc(d); return execBlock(b->bl, b->bl->invWBody, b->sc, 6, (B[]){tag(d,FUN_TAG), x, w , inc(d->m2), inc(d->f), inc(d->g)}); }
B md2Bl_ix(Md2D* d, B w, B x) { Md2Block* b=c(Md2Block, d->m2); ptr_inc(d); return execBlock(b->bl, b->bl->invXBody, b->sc, 6, (B[]){tag(d,FUN_TAG), x, w , inc(d->m2), inc(d->f), inc(d->g)}); }
B md1Bl_d(B m, B f ) { Md1Block* c = c(Md1Block,m); Block* bl=c(Md1Block, m)->bl; return c->bl->imm? execBlock(bl, bl->bodies[0], c(Md1Block, m)->sc, 2, (B[]){m, f }) : m_md1D(m,f ); }
B md2Bl_d(B m, B f, B g) { Md2Block* c = c(Md2Block,m); Block* bl=c(Md2Block, m)->bl; return c->bl->imm? execBlock(bl, bl->bodies[0], c(Md2Block, m)->sc, 3, (B[]){m, f, g}) : m_md2D(m,f,g); }
@ -968,9 +974,9 @@ void comp_init() {
TIi(t_md1_block,freeO) = md1Bl_freeO; TIi(t_md1_block,freeF) = md1Bl_freeF; TIi(t_md1_block,visit) = md1Bl_visit; TIi(t_md1_block,print) = md1Bl_print; TIi(t_md1_block,decompose) = block_decompose; TIi(t_md1_block,m1_d)=md1Bl_d;
TIi(t_md2_block,freeO) = md2Bl_freeO; TIi(t_md2_block,freeF) = md2Bl_freeF; TIi(t_md2_block,visit) = md2Bl_visit; TIi(t_md2_block,print) = md2Bl_print; TIi(t_md2_block,decompose) = block_decompose; TIi(t_md2_block,m2_d)=md2Bl_d;
TIi(t_fun_block,fn_im) = funBl_im;
TIi(t_fun_block,fn_iw) = funBl_iw;
TIi(t_fun_block,fn_ix) = funBl_ix;
TIi(t_fun_block,fn_im) = funBl_im; TIi(t_md1_block,m1_im) = md1Bl_im; TIi(t_md2_block,m2_im) = md2Bl_im;
TIi(t_fun_block,fn_iw) = funBl_iw; TIi(t_md1_block,m1_iw) = md1Bl_iw; TIi(t_md2_block,m2_iw) = md2Bl_iw;
TIi(t_fun_block,fn_ix) = funBl_ix; TIi(t_md1_block,m1_ix) = md1Bl_ix; TIi(t_md2_block,m2_ix) = md2Bl_ix;
#ifndef GS_REALLOC
allocStack((void**)&gStack, (void**)&gStackStart, (void**)&gStackEnd, sizeof(B), GS_SIZE);