diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index 90a41880..b968b64b 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -295,14 +295,14 @@ static B args_path(B* fullpath, B w, char* name) { // consumes w, returns args, B bqn_c1(B t, B x) { vfyStr(x, "•BQN", "𝕩"); - return bqn_exec(x, bi_N, bi_N); + return rebqn_exec(x, bi_N, bi_N, nfn_objU(t)); } B bqn_c2(B t, B w, B x) { vfyStr(x, "•BQN", "𝕩"); B fullpath; B args = args_path(&fullpath, w, "•BQN"); - return bqn_exec(x, fullpath, args); + return rebqn_exec(x, fullpath, args, nfn_objU(t)); } B cmp_c2(B t, B w, B x) { @@ -691,7 +691,7 @@ B rebqn_c1(B t, B x) { HArr_p d = m_harr0v(re_max); d.a[re_mode] = m_i32(replVal); d.a[re_scope] = scVal; - init_comp(d.a, def_re, prim, sys); + init_comp(d.a, harr_ptr(nfn_objU(t)), prim, sys); decG(x); return m_nfn(rebqnResDesc, d.b); } @@ -699,7 +699,7 @@ B repl_c2(B t, B w, B x) { vfyStr(x, "REPL", "𝕩"); B fullpath; B args = args_path(&fullpath, w, "REPL"); - return rebqn_exec(x, fullpath, args, nfn_objU(t)); + return repl_exec(x, fullpath, args, nfn_objU(t)); } B repl_c1(B t, B x) { return repl_c2(t, emptyHVec(), x); diff --git a/src/load.c b/src/load.c index 102d2293..30a6274c 100644 --- a/src/load.c +++ b/src/load.c @@ -203,10 +203,10 @@ static NOINLINE Block* bqn_compc(B str, B path, B args, B re) { // consumes str, COMPS_POP; popCatch(); return r; } -Block* bqn_comp(B str, B path, B args) { // consumes all +Block* bqn_comp(B str, B path, B args) { return bqn_compc(str, path, args, def_re); } -Block* bqn_compScc(B str, B path, B args, B re, Scope* sc, bool loose, bool noNS) { // consumes str,path,args +Block* bqn_compScc(B str, B path, B args, B re, Scope* sc, bool loose, bool noNS) { str = chr_squeeze(str); COMPS_PUSH(path, args, str, re); B* o = harr_ptr(re); @@ -240,12 +240,12 @@ B bqn_exec(B str, B path, B args) { // consumes all } B str_all, str_none; -void init_comp(B* set, B prev_re, B prim, B sys) { +void init_comp(B* new_re, B* prev_re, B prim, B sys) { if (q_N(prim)) { - set[re_comp] = inc(def_comp); - set[re_compOpts] = inc(def_compOpts); - set[re_rt] = inc(def_rt); - set[re_glyphs] = inc(def_glyphs); + new_re[re_comp] = inc(prev_re[re_comp]); + new_re[re_compOpts] = inc(prev_re[re_compOpts]); + new_re[re_rt] = inc(prev_re[re_rt]); + new_re[re_glyphs] = inc(prev_re[re_glyphs]); } else { if (!isArr(prim) || RNK(prim)!=1) thrM("•ReBQN: 𝕩.primitives must be a list"); usz pia = IA(prim); @@ -281,22 +281,22 @@ void init_comp(B* set, B prev_re, B prim, B sys) { prh.a[np[t]++] = v; } - set[re_rt] = prh.b; - set[re_glyphs] = inc(rb); - set[re_comp] = c1(load_compgen, rb); - set[re_compOpts] = m_hvec2(inc(prh.b), incG(bi_sys)); + new_re[re_rt] = prh.b; + new_re[re_glyphs] = inc(rb); + new_re[re_comp] = c1(load_compgen, rb); + new_re[re_compOpts] = m_hvec2(inc(prh.b), incG(bi_sys)); } if (q_N(sys)) { - all_sys: - set[re_sysNames] = inc(def_sysNames); - set[re_sysVals] = inc(def_sysVals); + inherit_sys: + new_re[re_sysNames] = inc(prev_re[re_sysNames]); + new_re[re_sysVals] = inc(prev_re[re_sysVals]); } else { if (!isArr(sys) || RNK(sys)!=1) thrM("•ReBQN: 𝕩.system must be a list"); if (str_all.u==0) { gc_add(str_all = m_c8vec("all",3)); gc_add(str_none = m_c8vec("none",4)); } - if (equal(sys, str_all)) goto all_sys; + if (equal(sys, str_all)) goto inherit_sys; if (equal(sys, str_none)) { - set[re_sysNames] = set[re_sysVals] = emptyHVec(); + new_re[re_sysNames] = new_re[re_sysVals] = emptyHVec(); } else { usz ia = IA(sys); SGetU(sys) M_HARR(r1, ia); @@ -308,8 +308,8 @@ void init_comp(B* set, B prev_re, B prim, B sys) { HARR_ADD(r1, i, Get(c,0)); HARR_ADD(r2, i, Get(c,1)); } - set[re_sysNames] = HARR_FV(r1); - set[re_sysVals] = HARR_FV(r2); + new_re[re_sysNames] = HARR_FV(r1); + new_re[re_sysVals] = HARR_FV(r2); } } } @@ -338,23 +338,26 @@ void comps_getSysvals(B* res) { } B rebqn_exec(B str, B path, B args, B re) { - B* op = harr_ptr(re); - i32 replMode = o2iG(op[re_mode]); - Scope* sc = c(Scope, op[re_scope]); - B res; - Block* block; - if (replMode>0) { - block = bqn_compScc(str, path, args, re, sc, replMode==2, true); - ptr_dec(sc->body); - sc->body = ptr_inc(block->bodies[0]); - res = execBlockInplace(block, sc); - } else { - block = bqn_compc(str, path, args, re); - res = evalFunBlock(block, 0); - } + Block* block = bqn_compc(str, path, args, re); + B res = evalFunBlock(block, 0); ptr_dec(block); return res; } +B repl_exec(B str, B path, B args, B re) { + B* op = harr_ptr(re); + i32 replMode = o2iG(op[re_mode]); + if (replMode>0) { + Scope* sc = c(Scope, op[re_scope]); + Block* block = bqn_compScc(str, path, args, re, sc, replMode==2, true); + ptr_dec(sc->body); + sc->body = ptr_inc(block->bodies[0]); + B res = execBlockInplace(block, sc); + ptr_dec(block); + return res; + } else { + return rebqn_exec(str, path, args, re); + } +} static NOINLINE B m_lvB_0( ) { return emptyHVec(); } static NOINLINE B m_lvB_1(B a ) { return m_hvec1(a); } diff --git a/src/load.h b/src/load.h index 01d3b978..e6d42fbe 100644 --- a/src/load.h +++ b/src/load.h @@ -10,7 +10,7 @@ enum { }; enum { re_comp, re_compOpts, re_rt, re_glyphs, re_sysNames, re_sysVals, // compiling info - re_mode, re_scope, // only for rebqn_exec + re_mode, re_scope, // only for repl_exec re_max }; #define COMPS_REF(O,N) O->a[comps_##N] @@ -20,6 +20,11 @@ extern B def_sysNames, def_sysVals; B comps_getPrimitives(void); void comps_getSysvals(B* res); -extern B def_re; -B rebqn_exec(B str, B path, B args, B re); // consumes str,path,args -void init_comp(B* set, B prev_re, B prim, B sys); // doesn't consume; writes compiling info re_* into set +typedef struct Block Block; +typedef struct Scope Scope; +Block* bqn_comp(B str, B path, B args); // consumes all +Block* bqn_compSc(B str, B path, B args, Scope* sc, bool repl); // consumes str,path,args +Block* bqn_compScc(B str, B path, B args, B re, Scope* sc, bool loose, bool noNS); // consumes str,path,args +B rebqn_exec(B str, B path, B args, B re); // consumes str,path,args; runs in a new environment +B repl_exec(B str, B path, B args, B re); // consumes str,path,args; uses re_mode and re_scope +void init_comp(B* new_re, B* prev_re, B prim, B sys); // doesn't consume; writes re_* compiling info into new_re diff --git a/src/main.c b/src/main.c index a0a56826..bd8c9e14 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,6 @@ #include "core.h" #include "vm.h" +#include "load.h" #include "ns.h" #include "utils/utf.h" #include "utils/talloc.h" diff --git a/src/vm.h b/src/vm.h index edec389c..e80f0c21 100644 --- a/src/vm.h +++ b/src/vm.h @@ -152,8 +152,6 @@ struct Scope { B vars[]; }; -Block* bqn_comp(B str, B path, B args); // consumes all -Block* bqn_compSc(B str, B path, B args, Scope* sc, bool repl); // consumes str,path,args Block* compileAll(B bcq, B objs, B blocks, B bodies, B indices, B tokenInfo, B src, B path, Scope* sc, i32 nsResult); // nsResult: 0: accept; -1: error; 1: convert to regular RETN Scope* m_scope(Body* body, Scope* psc, u16 varAm, i32 initVarAm, B* initVars); Body* m_body(i32 vam, i32 pos, u32 maxStack, u16 maxPSC); // leaves varData uninitialized diff --git a/test/cases/system.bqn b/test/cases/system.bqn index 7ea1df22..8a7f1187 100644 --- a/test/cases/system.bqn +++ b/test/cases/system.bqn @@ -27,8 +27,8 @@ f ← •ReBQN{repl⇐"none"} ⋄ !6≡•Type F "⇐" !"Cannot construct a namespace for a REPL result" % f ← •ReBQN{repl⇐"strict"} ⋄ F "a⇐1" !"Cannot construct a namespace for a REPL result" % f ← •ReBQN{repl⇐"strict"} ⋄ F "⇐" -# f←•ReBQN {primitives⇐⋈'÷'‿-} ⋄ ! ¯5 ≡ F"•BQN""÷5""" ⋄ b←F"•BQN" ⋄ ! ¯5 ≡ B "÷5" ⋄ ! 0.2 ≡ •BQN "÷5" -# f←•ReBQN {primitives⇐⋈'÷'‿-} ⋄ a1 ← •bqn ⋄ r1 ← F"•BQN" ⋄ a2 ← A1"•BQN" ⋄ r2 ← R1"•BQN" ⋄ a3 ← A1"•ReBQN{⇐}" ⋄ r3 ← R1"•ReBQN{⇐}" ⋄ {𝕏"÷"}¨ ⟨a1,r1,a2,r2,a3,r3⟩ %% ⟨÷,-,÷,-,÷,-⟩ +f←•ReBQN {primitives⇐⋈'÷'‿-} ⋄ ! ¯5 ≡ F"•BQN""÷5""" ⋄ b←F"•BQN" ⋄ ! ¯5 ≡ B "÷5" ⋄ ! 0.2 ≡ •BQN "÷5" +f←•ReBQN {primitives⇐⋈'÷'‿-} ⋄ a1 ← •bqn ⋄ r1 ← F"•BQN" ⋄ a2 ← A1"•BQN" ⋄ r2 ← R1"•BQN" ⋄ a3 ← A1"•ReBQN{⇐}" ⋄ r3 ← R1"•ReBQN{⇐}" ⋄ {𝕏"÷"}¨ ⟨a1,r1,a2,r2,a3,r3⟩ %% ⟨÷,-,÷,-,÷,-⟩ f←•ReBQN {repl⇐"none" ⋄ primitives⇐⋈'÷'‿÷} ⋄ ! "Unknown character: '-'" ≡ F⎊{𝕊: •CurrentError@} "-5" ⋄ ! 0.2 ≡ •BQN "÷5" f←•ReBQN {repl⇐"loose" ⋄ primitives⇐⋈'÷'‿÷} ⋄ ! "Unknown character: '-'" ≡ F⎊{𝕊: •CurrentError@} "-5" ⋄ ! 0.2 ≡ •BQN "÷5" ps ← ⟨'÷'‿÷⟩ ⋄ f←•ReBQN {repl⇐"none" ⋄ primitives⇐ps} ⋄ ! ps ≡ F "•primitives" ⋄ ! •primitives ≡ •BQN "•primitives" ⋄ ! ps ≡ F "•primitives"