From 3f62a5130539673accaa8136baf0f7cf1bfe7cd8 Mon Sep 17 00:00:00 2001 From: dzaima Date: Sun, 26 Nov 2023 01:21:11 +0200 Subject: [PATCH] system value inheriting --- src/builtins/sysfn.c | 16 ++++++++------ src/load.c | 50 +++++++++++++++++++++++++++++++++++-------- test/cases/system.bqn | 5 +++++ 3 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index b968b64b..4ca18c71 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -270,13 +270,15 @@ B show_c1(B t, B x) { return x; } -B vfyStr(B x, char* name, char* arg) { - if (isAtm(x) || RNK(x)!=1) thrF("%U: %U must be a string", name, arg); - if (!elChr(TI(x,elType))) { - usz ia = IA(x); - SGetU(x) - for (usz i = 0; i < ia; i++) if (!isC32(GetU(x,i))) thrF("%U: %U must be a string", name, arg); - } +NOINLINE bool isStr(B x) { + if (isAtm(x) || RNK(x)!=1) return false; + if (elChr(TI(x,elType))) return true; + usz ia = IA(x); SGetU(x) + for (usz i = 0; i < ia; i++) if (!isC32(GetU(x,i))) return false; + return true; +} +NOINLINE B vfyStr(B x, char* name, char* arg) { + if (!isStr(x)) thrF("%U: %U must be a string", name, arg); return x; } diff --git a/src/load.c b/src/load.c index 30a6274c..17857bc7 100644 --- a/src/load.c +++ b/src/load.c @@ -239,6 +239,7 @@ B bqn_exec(B str, B path, B args) { // consumes all return res; } +bool isStr(B x); B str_all, str_none; void init_comp(B* new_re, B* prev_re, B prim, B sys) { if (q_N(prim)) { @@ -299,17 +300,48 @@ void init_comp(B* new_re, B* prev_re, B prim, B sys) { new_re[re_sysNames] = new_re[re_sysVals] = emptyHVec(); } else { usz ia = IA(sys); SGetU(sys) - M_HARR(r1, ia); - M_HARR(r2, ia); - for (usz i = 0; i < ia; i++) { + M_HARR(nns, ia); + M_HARR(nvs, ia); + i8* inh; B inhA = m_i8arrv(&inh, ia); + for (usz i = 0; i < ia; i++) { // write defined system values, inherited ones get inserted later B c = GetU(sys,i); - if (!isArr(c) || RNK(c)!=1 || IA(c)!=2) thrM("•ReBQN: 𝕩.system must be either \"all\", \"none\", or a list of pairs"); - SGet(c) - HARR_ADD(r1, i, Get(c,0)); - HARR_ADD(r2, i, Get(c,1)); + B nn, nv; + if (isStr(c)) { + nn = incG(c); + nv = bi_N; + inh[i] = 1; + } else { + if (!isArr(c) || RNK(c)!=1 || IA(c)!=2) thrM("•ReBQN: 𝕩.system must be either \"all\", \"none\", or a list of names or pairs of name & value"); + SGet(c) + nn = Get(c,0); + nv = Get(c,1); + inh[i] = 0; + } + HARR_ADD(nns, i, nn); + HARR_ADD(nvs, i, nv); } - new_re[re_sysNames] = HARR_FV(r1); - new_re[re_sysVals] = HARR_FV(r2); + B nnsA = HARR_FV(nns); + + // system value inheriting + B inhNs = C2(slash, incG(inhA), incG(nnsA)); + usz inhN = IA(inhNs); + if (inhN>0) { + B prevN = prev_re[re_sysNames]; + B prevV = prev_re[re_sysVals]; + B idxs = C2(indexOf, incG(prevN), inhNs); + B inhNIs = C1(slash, incG(inhA)); + SGetU(idxs) SGet(prevV) SGetU(inhNIs) + for (usz i = 0; i < inhN; i++) { + usz oi = o2sG(GetU(inhNIs,i)); + usz idx = o2sG(GetU(idxs,i)); + if (idx == IA(prevN)) thrF("•ReBQN: No system value \"%R\" to inherit", IGet(nnsA, oi)); + HARR_O(nvs).a[oi] = Get(prevV, idx); + } + decG(inhNIs); decG(idxs); + } else decG(inhNs); + + new_re[re_sysNames] = nnsA; + new_re[re_sysVals] = HARR_FV(nvs); } } } diff --git a/test/cases/system.bqn b/test/cases/system.bqn index 8a7f1187..86b7a21c 100644 --- a/test/cases/system.bqn +++ b/test/cases/system.bqn @@ -34,6 +34,11 @@ f←•ReBQN {repl⇐"loose" ⋄ primitives⇐⋈'÷'‿÷} ⋄ ! "Unknown chara ps ← ⟨'÷'‿÷⟩ ⋄ f←•ReBQN {repl⇐"none" ⋄ primitives⇐ps} ⋄ ! ps ≡ F "•primitives" ⋄ ! •primitives ≡ •BQN "•primitives" ⋄ ! ps ≡ F "•primitives" ps ← ⟨'÷'‿÷⟩ ⋄ f←•ReBQN {repl⇐"loose" ⋄ primitives⇐ps} ⋄ ! ps ≡ F "•primitives" ⋄ ! •primitives ≡ •BQN "•primitives" ⋄ ! ps ≡ F "•primitives" +f←•ReBQN{primitives⇐⋈'÷'‿- ⋄ system⇐⟨"foo"‿⋈, "oldbqn"‿•BQN, "bqn"⟩} ⋄ {𝕏 "÷5"}¨ F "⟨•foo, •OldBQN, •BQN⟩" %% ⟨⋈"÷5", 0.2, ¯5⟩ +!"•ReBQN: No system value ""baz"" to inherit" % •ReBQN{system⇐⟨"foo"‿"bar", "bqn", "baz", "rebqn"⟩} +!"•ReBQN: No system value ""bqn"" to inherit" % f←•ReBQN{system⇐⟨"baz"‿1, "rebqn", "foo"‿2⟩} ⋄ g←F"•ReBQN" ⋄ G {system⇐⟨"foo"‿"bar", "baz", "bqn", "rebqn"⟩} +f←•ReBQN{primitives⇐⋈'÷'‿- ⋄ system⇐⟨"foo"‿⋈, "bqn", "listsys"⟩} ⋄ F"•listsys" %% ⟨"foo","bqn","listsys"⟩ + # •primitives !∧´2=•Type¨ ⊑¨•primitives