From 9d5caad9a9643f03f900ae33f1345e4ccdf21698 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Sun, 23 Jun 2024 10:51:01 -0400 Subject: [PATCH] Compute Insert identity natively --- src/builtins/fold.c | 27 ++++++++++++++++++++++----- src/load.c | 5 ++--- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/builtins/fold.c b/src/builtins/fold.c index ccf88581..1030c1cd 100644 --- a/src/builtins/fold.c +++ b/src/builtins/fold.c @@ -381,22 +381,39 @@ static B m1c1(B t, B f, B x) { // consumes x decG(fn); return r; } -extern GLOBAL B rt_insert; extern B insert_base(B f, B x, bool has_w, B w); // from cells.c B insert_c1(Md1D* d, B x) { B f = d->f; - if (isAtm(x) || RNK(x)==0) thrM("˝: 𝕩 must have rank at least 1"); + ur xr; + if (isAtm(x) || (xr=RNK(x))==0) thrM("˝: 𝕩 must have rank at least 1"); usz len = *SH(x); - if (len==0) { SLOW2("!𝕎˝𝕩", f, x); return m1c1(rt_insert, f, x); } + if (len==0) { + if (isFun(f)) { + B id = TI(f,identity)(f); + if (!q_N(id)) { + if (isArr(id)) { decG(x); return id; } // arithmetic with table + usz* xsh = SH(x); + Arr* r = reshape_one(shProd(xsh, 1, xr), id); + if (xr == 2) arr_shVec(r); else { + usz* rsh = arr_shAlloc(r, xr-1); + shcpy(rsh, xsh+1, xr-1); + } + decG(x); return taga(r); + } else if (v(f)->flags == n_join+1) { + if (xr <= 1) thrM("˝: Identity does not exist"); + goto join; + } + } + thrM("˝: Identity not found"); + } if (len==1) return C1(select, x); if (RARE(!isFun(f))) { decG(x); if (isMd(f)) thrM("Calling a modifier"); return inc(f); } - ur xr = RNK(x); if (xr==1 && isPervasiveDyExt(f)) return m_unit(fold_c1(d, x)); if (v(f)->flags) { u8 rtid = v(f)->flags-1; if (rtid==n_ltack) return C1(select, x); if (rtid==n_rtack) return C2(select, m_f64(-1), x); - if (rtid==n_join) { + if (rtid==n_join) { join:; if (xr==1) return x; ShArr* rsh; if (xr>2) { diff --git a/src/load.c b/src/load.c index 5df99209..2d8ace52 100644 --- a/src/load.c +++ b/src/load.c @@ -129,7 +129,7 @@ NOINLINE B load_fullpath(B path, B name) { GLOBAL HArr* comps_curr; -GLOBAL B rt_undo, rt_select, rt_slash, rt_insert, rt_depth, +GLOBAL B rt_undo, rt_select, rt_slash, rt_depth, rt_group, rt_under, rt_find; Block* load_buildBlock(B x, B src, B path, B name, Scope* sc, i32 nsResult) { // consumes x,src B fullpath = load_fullpath(path, name); @@ -500,7 +500,6 @@ void load_init() { // very last init function gc_add(rt_under = Get(rtObjRaw, n_under )); gc_add(rt_find = Get(rtObjRaw, n_find )); gc_add(rt_depth = Get(rtObjRaw, n_depth )); - gc_add(rt_insert = Get(rtObjRaw, n_insert)); for (usz i = 0; i < RT_LEN; i++) { #ifdef RT_WRAP @@ -542,7 +541,7 @@ void load_init() { // very last init function load_rt = frtObj; rt_select = rt_slash = rt_group = rt_find = bi_invalidFn; - rt_undo = rt_insert = bi_invalidMd1; + rt_undo = bi_invalidMd1; rt_under = rt_depth = bi_invalidMd2; rt_invFnRegFn = rt_invFnSwapFn = invalidFn_c1;