diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index d3faf5cf..488b1774 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -538,33 +538,17 @@ B reBQN_c1(B t, B x) { scVal = tag(sc,OBJ_TAG); } ptr_dec(initBlock); - B dat = m_hVec4(m_f64(replVal), scVal, bi_N, bi_N); - init_comp(harr_ptr(dat)+2, prim); + HArr_p d = m_harrUv(5); d.a[0] = m_f64(replVal); d.a[1] = scVal; + d.a[2]=d.a[3]=d.a[4]=bi_N; + init_comp(d.a+2, prim); dec(x); - return m_nfn(reBQNDesc, dat); + return m_nfn(reBQNDesc, d.b); } B repl_c2(B t, B w, B x) { vfyStr(x, "REPL", "𝕩"); - B o = nfn_objU(t); - B* op = harr_ptr(o); - i32 replMode = o2iu(op[0]); - Scope* sc = c(Scope, op[1]); - B fullpath; B args = args_path(&fullpath, w, "REPL"); - - B res; - if (replMode>0) { - Block* block = bqn_compScc(x, fullpath, args, sc, op[2], op[3], replMode==2); - ptr_dec(sc->body); - sc->body = ptr_inc(block->bodies[0]); - res = execBlockInline(block, sc); - ptr_dec(block); - } else { - res = rebqn_exec(x, fullpath, args, op[2], op[3]); - } - - return res; + return rebqn_exec(x, fullpath, args, nfn_objU(t)); } B repl_c1(B t, B x) { return repl_c2(t, emptyHVec(), x); @@ -812,6 +796,7 @@ B sh_c2(B t, B w, B x) { B getInternalNS(void); B getMathNS(void); +B getPrimitives(void); static Body* file_nsGen; B sys_c1(B t, B x) { @@ -864,6 +849,7 @@ B sys_c1(B t, B x) { else if (eqStr(c, U"makerand")) r.a[i] = incG(bi_makeRand); else if (eqStr(c, U"rand")) r.a[i] = getRandNS(); else if (eqStr(c, U"rebqn")) r.a[i] = incG(bi_reBQN); + else if (eqStr(c, U"primitives")) r.a[i] = getPrimitives(); else if (eqStr(c, U"fromutf8")) r.a[i] = incG(bi_fromUtf8); else if (eqStr(c, U"path")) r.a[i] = inc(REQ_PATH); else if (eqStr(c, U"name")) r.a[i] = inc(REQ_NAME); diff --git a/src/load.c b/src/load.c index 0bc31e19..f88b23a3 100644 --- a/src/load.c +++ b/src/load.c @@ -100,6 +100,7 @@ i64 comp_currEnvPos; B comp_currPath; B comp_currArgs; B comp_currSrc; +B comp_currRe; B rt_merge, rt_undo, rt_select, rt_slash, rt_join, rt_ud, rt_pick,rt_take, rt_drop, rt_group, rt_under, rt_reverse, rt_indexOf, rt_count, rt_memberOf, rt_find, rt_cell; @@ -127,6 +128,7 @@ B load_comp; B load_compgen; B load_rtObj; B load_compArg; +B load_glyphs; #if FORMATTER B load_fmt, load_repr; @@ -149,6 +151,7 @@ void load_gcFn() { mm_visit(comp_currPath); mm_visit(comp_currArgs); mm_visit(comp_currSrc); + mm_visit(comp_currRe); mm_visit(rt_invFnReg); mm_visit(rt_invFnSwap); } @@ -206,10 +209,23 @@ Block* bqn_compScc(B str, B path, B args, Scope* sc, B comp, B rt, bool repl) { NOINLINE Block* bqn_compSc(B str, B path, B args, Scope* sc, bool repl) { // consumes str,path,args return bqn_compScc(str, path, args, sc, load_comp, load_rtObj, repl); } + +B bqn_exec(B str, B path, B args) { // consumes all + Block* block = bqn_comp(str, path, args); + B res = m_funBlock(block, 0); + ptr_dec(block); + return res; +} +void bqn_setComp(B comp) { // consumes; doesn't unload old comp, but whatever + load_comp = comp; + gc_add(load_comp); +} + void init_comp(B* set, B prim) { // doesn't consume if (q_N(prim)) { set[0] = inc(load_comp); set[1] = inc(load_rtObj); + set[2] = inc(load_glyphs); } else { if (!isArr(prim)||rnk(prim)!=1) thrM("β€’ReBQN: 𝕩.primitives must be a list"); usz pia = a(prim)->ia; @@ -243,29 +259,55 @@ void init_comp(B* set, B prim) { // doesn't consume rt[np[t]++] = v; } set[1] = prh.b; + set[2] = inc(r.b); set[0] = c1(load_compgen, r.b); } } - -B bqn_exec(B str, B path, B args) { // consumes all - Block* block = bqn_comp(str, path, args); - B res = m_funBlock(block, 0); - ptr_dec(block); - return res; -} -B rebqn_exec(B str, B path, B args, B comp, B rt) { // consumes str,path,args - B rtsys = m_hVec2(inc(rt), incG(bi_sys)); - Block* block = bqn_compc(str, path, args, comp, rtsys); - dec(rtsys); - B res = m_funBlock(block, 0); - ptr_dec(block); - return res; -} -void bqn_setComp(B comp) { // consumes; doesn't unload old comp, but whatever - load_comp = comp; - gc_add(load_comp); +B getPrimitives(void) { + B g, r; + if (q_N(comp_currRe)) { + g = load_glyphs; r = load_rtObj; + } else { + B* o = harr_ptr(comp_currRe); g = o[4]; r = o[3]; + } + B* pr = harr_ptr(r); + B* gg = harr_ptr(g); + HArr_p ph = m_harrUv(a(r)->ia); B* p = ph.a; + for (usz gi = 0; gi < 3; gi++) { + usz l = a(gg[gi])->ia; + u32 *gp = c32arr_ptr(gg[gi]); + for (usz i = 0; i < l; i++) { + p[i] = m_hVec2(m_c32(gp[i]), inc(pr[i])); + } + p += l; pr += l; + } + return ph.b; } +B rebqn_exec(B str, B path, B args, B o) { + B prevRe = comp_currRe; comp_currRe = inc(o); + B* op = harr_ptr(o); + i32 replMode = o2iu(op[0]); + Scope* sc = c(Scope, op[1]); + B res; + if (replMode>0) { + Block* block = bqn_compScc(str, path, args, sc, op[2], op[3], replMode==2); + comp_currRe = prevRe; + ptr_dec(sc->body); + sc->body = ptr_inc(block->bodies[0]); + res = execBlockInline(block, sc); + ptr_dec(block); + } else { + B rtsys = m_hVec2(inc(op[3]), incG(bi_sys)); + Block* block = bqn_compc(str, path, args, op[2], rtsys); + dec(rtsys); + comp_currRe = prevRe; + res = m_funBlock(block, 0); + ptr_dec(block); + } + dec(o); + return res; +} static NOINLINE B m_lvB_0( ) { return emptyHVec(); } static NOINLINE B m_lvB_1(B a ) { return m_hVec1(a); } @@ -282,6 +324,7 @@ void load_init() { // very last init function comp_currPath = bi_N; comp_currArgs = bi_N; comp_currSrc = bi_N; + comp_currRe = bi_N; gc_addFn(load_gcFn); B fruntime[] = { /* +-Γ—Γ·β‹†βˆšβŒŠβŒˆ|Β¬ */ bi_add , bi_sub , bi_mul , bi_div , bi_pow , bi_root , bi_floor , bi_ceil , bi_stile , bi_not, @@ -414,10 +457,10 @@ void load_init() { // very last init function #include "gen/compiles" ); runtime[n_asrt] = prevAsrt; - B glyphs = m_hVec3(m_str32(U"+-Γ—Γ·β‹†βˆšβŒŠβŒˆ|¬∧∨<>β‰ =≀β‰₯β‰‘β‰’βŠ£βŠ’β₯ŠβˆΎβ‰β‹ˆβ†‘β†“β†•Β«Β»βŒ½β‰/β‹β’βŠβŠ‘βŠβŠ’βˆŠβ·βŠ”!"), m_str32(U"Λ™ΛœΛ˜Β¨βŒœβΌΒ΄Λ`"), m_str32(U"βˆ˜β—‹βŠΈβŸœβŒΎβŠ˜β—ΆβŽ‰βš‡βŸβŽŠ")); + load_glyphs = m_hVec3(m_str32(U"+-Γ—Γ·β‹†βˆšβŒŠβŒˆ|¬∧∨<>β‰ =≀β‰₯β‰‘β‰’βŠ£βŠ’β₯ŠβˆΎβ‰β‹ˆβ†‘β†“β†•Β«Β»βŒ½β‰/β‹β’βŠβŠ‘βŠβŠ’βˆŠβ·βŠ”!"), m_str32(U"Λ™ΛœΛ˜Β¨βŒœβΌΒ΄Λ`"), m_str32(U"βˆ˜β—‹βŠΈβŸœβŒΎβŠ˜β—ΆβŽ‰βš‡βŸβŽŠ")); load_compgen = m_funBlock(comp_b, 0); ptr_dec(comp_b); - load_comp = c1(load_compgen, glyphs); - gc_add(load_compgen); gc_add(load_comp); + load_comp = c1(load_compgen, inc(load_glyphs)); + gc_add(load_compgen); gc_add(load_comp); gc_add(load_glyphs); #if FORMATTER diff --git a/src/vm.h b/src/vm.h index c6579edc..921f7637 100644 --- a/src/vm.h +++ b/src/vm.h @@ -142,13 +142,12 @@ struct Scope { }; Block* bqn_comp(B str, B path, B args); -Block* bqn_compSc (B str, B path, B args, Scope* sc, bool repl); -Block* bqn_compScc(B str, B path, B args, Scope* sc, B comp, B rt, bool repl); +Block* bqn_compSc(B str, B path, B args, Scope* sc, bool repl); Block* compile(B bcq, B objs, B blocks, B bodies, B indices, B tokenInfo, B src, B path, Scope* sc); 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 varIDs and nsDesc uninitialized void init_comp(B* set, B prim); -B rebqn_exec(B str, B path, B args, B comp, B rt); +B rebqn_exec(B str, B path, B args, B o); typedef struct Nvm_res { u8* p; B refs; } Nvm_res; Nvm_res m_nvm(Body* b);