From 1d13a1ef071d4ba919b4f3f998842029e2070f3e Mon Sep 17 00:00:00 2001 From: dzaima Date: Sat, 28 Aug 2021 23:55:48 +0300 Subject: [PATCH] =?UTF-8?q?=E2=80=A2ReBQN=20with=20only=20the=20repl=20set?= =?UTF-8?q?ting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/sysfn.c | 63 ++++++++++++++++++++++++++------------------ src/ns.c | 5 ++-- src/ns.h | 2 +- src/utils/builtins.h | 2 +- src/vm.c | 2 +- 5 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index 96115963..d5f140b8 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -427,28 +427,31 @@ B makeRand_c1(B t, B x) { return r; } extern B replPath; // defined in main.c -static NFnDesc* makeREPLDesc; -B makeREPL_c1(B t, B x) { +static NFnDesc* reBQNDesc; +B reBQN_c1(B t, B x) { + if (!isNsp(x)) thrM("•ReBQN: Argument must be a namespace"); + B replStr = m_str32(U"repl"); + B repl = ns_getNU(x, replStr, false); dec(replStr); + i32 replVal = q_N(repl) || eqStr(repl,U"none")? 0 : eqStr(repl,U"strict")? 1 : eqStr(repl,U"loose")? 2 : 3; + if (replVal==3) thrM("•ReBQN: Invalid repl value"); dec(x); Block* initBlock = bqn_comp(m_str32(U"\"(REPL initializer)\""), inc(replPath), m_f64(0)); - Scope* sc = m_scope(initBlock->bodies[0], NULL, 0, 0, NULL); + B scVal; + if (replVal==0) { + scVal = bi_N; + } else { + Scope* sc = m_scope(initBlock->bodies[0], NULL, 0, 0, NULL); + scVal = tag(sc, OBJ_TAG); + } ptr_dec(initBlock); - return m_nfn(makeREPLDesc, tag(sc, OBJ_TAG)); -} -B repl_c1(B t, B x) { - Scope* sc = c(Scope,nfn_objU(t)); - - Block* block = bqn_compSc(x, inc(replPath), emptySVec(), sc, true); - - ptr_dec(sc->body); ptr_inc(block->bodies[0]); - sc->body = block->bodies[0]; - B res = execBlockInline(block, sc); - - ptr_dec(block); - return res; + return m_nfn(reBQNDesc, m_v2(m_f64(replVal), scVal)); } B repl_c2(B t, B w, B x) { - Scope* sc = c(Scope,nfn_objU(t)); + B o = nfn_objU(t); + B* op = harr_ptr(o); + i32 replMode = o2iu(op[0]); + Scope* sc = c(Scope, op[1]); + if (!isArr(w) || rnk(w)!=1 || a(w)->ia>3) thrM("REPL: 𝕨 must be a vector with at most 3 items"); usz ia = a(w)->ia; BS2B wget = TI(w,get); @@ -456,16 +459,24 @@ B repl_c2(B t, B w, B x) { B file = ia>1? wget(w,1) : emptyCVec(); B args = ia>2? wget(w,2) : emptySVec(); B fullpath = vec_join(vec_add(path, m_c32('/')), file); - Block* block = bqn_compSc(x, fullpath, args, sc, true); - - ptr_dec(sc->body); ptr_inc(block->bodies[0]); - sc->body = block->bodies[0]; - B res = execBlockInline(block, sc); - dec(w); - ptr_dec(block); + + B res; + if (replMode>0) { + Block* block = bqn_compSc(x, fullpath, args, sc, replMode==2); + ptr_dec(sc->body); ptr_inc(block->bodies[0]); + sc->body = block->bodies[0]; + res = execBlockInline(block, sc); + ptr_dec(block); + } else { + res = bqn_exec(x, fullpath, args); + } + return res; } +B repl_c1(B t, B x) { + return repl_c2(t, emptyHVec(), x); +} static NFnDesc* fileAtDesc; B fileAt_c1(B d, B x) { @@ -675,7 +686,7 @@ B sys_c1(B t, B x) { else if (eqStr(c, U"fmt")) r.a[i] = inc(bi_fmt); else if (eqStr(c, U"glyph")) r.a[i] = inc(bi_glyph); else if (eqStr(c, U"makerand")) r.a[i] = inc(bi_makeRand); - else if (eqStr(c, U"makerepl")) r.a[i] = inc(bi_makeREPL); + else if (eqStr(c, U"rebqn")) r.a[i] = inc(bi_reBQN); else if (eqStr(c, U"fromutf8")) r.a[i] = inc(bi_fromUtf8); else if (eqStr(c, U"path")) r.a[i] = inc(REQ_PATH); else if (eqStr(c, U"fchars")) r.a[i] = m_nfn(fCharsDesc, inc(REQ_PATH)); @@ -699,7 +710,7 @@ void sysfn_init() { fLinesDesc = registerNFn(m_str32(U"(file).Lines"), flines_c1, flines_c2); fBytesDesc = registerNFn(m_str32(U"(file).Bytes"), fbytes_c1, fbytes_c2); importDesc = registerNFn(m_str32(U"•Import"), import_c1, import_c2); - makeREPLDesc = registerNFn(m_str32(U"(REPL)"), repl_c1, repl_c2); + reBQNDesc = registerNFn(m_str32(U"(REPL)"), repl_c1, repl_c2); listDesc = registerNFn(m_str32(U"•file.List"), list_c1, c2_invalid); } void sysfnPost_init() { diff --git a/src/ns.c b/src/ns.c index b3885d66..0603a5bb 100644 --- a/src/ns.c +++ b/src/ns.c @@ -78,7 +78,7 @@ B ns_qgetU(B ns, B cNL, i32 nameID) { VTY(ns, t_ns); // TODO somehow merge impl } return bi_N; } -B ns_getNU(B ns, B name) { VTY(ns, t_ns); +B ns_getNU(B ns, B name, bool thrEmpty) { VTY(ns, t_ns); NS* n = c(NS, ns); NSDesc* d = n->desc; i32 dVarAm = d->varAm; @@ -88,7 +88,8 @@ B ns_getNU(B ns, B name) { VTY(ns, t_ns); i32 dID = d->expIDs[i]; if (dID>=0 && equal(dNLgetU(dNL, dID), name)) return n->sc->vars[i]; } - thrM("No key found"); + if (thrEmpty) thrM("No key found"); + return bi_N; } void ns_set(B ns, B name, B val) { VTY(ns, t_ns); NS* n = c(NS, ns); diff --git a/src/ns.h b/src/ns.h index 1c258d5e..b31023e2 100644 --- a/src/ns.h +++ b/src/ns.h @@ -18,6 +18,6 @@ void m_nsDesc(Body* body, bool imm, u8 ty, B nameList, B varIDs, B exported); // B m_ns(Scope* sc, NSDesc* desc); // consumes both B ns_getU(B ns, B nameList, i32 nameID); // doesn't consume anything, doesn't increment result B ns_qgetU(B ns, B nameList, i32 nameID); // ns_getU but return bi_N on fail -B ns_getNU(B ns, B name); // doesn't consume anything, doesn't increment result +B ns_getNU(B ns, B name, bool thrEmpty); // doesn't consume anything, doesn't increment result; returns bi_N if doesn't exist and !thrEmpty void ns_set(B ns, B name, B val); // consumes val i32 ns_pos(B ns, B name); // consumes name; returns an index in sc->vars for any variable, exported or local diff --git a/src/utils/builtins.h b/src/utils/builtins.h index def23c31..0e2c5c7e 100644 --- a/src/utils/builtins.h +++ b/src/utils/builtins.h @@ -9,7 +9,7 @@ /* everything before the definition of •Type is defined to be pure, and everything after is not */ \ /* sysfn.c*/M(type,"•Type") M(decp,"•Decompose") M(primInd,"•PrimInd") M(glyph,"•Glyph") A(fill,"•FillFn") M(sys,"•getsys") A(grLen,"•GroupLen") D(grOrd,"•groupOrd") \ /* sysfn.c*/M(repr,"•Repr") M(fmt,"•Fmt") A(asrt,"!") A(casrt,"!") M(out,"•Out") M(show,"•Show") M(bqn,"•BQN") M(sh,"•SH") M(fromUtf8,"•FromUTF8") \ -/* sysfn.c*/D(cmp,"•Cmp") A(hash,"•Hash") M(delay,"•Delay") M(makeRand,"•MakeRand") M(makeREPL,"•MakeREPL") M(exit,"•Exit") M(getLine,"•GetLine") \ +/* sysfn.c*/D(cmp,"•Cmp") A(hash,"•Hash") M(delay,"•Delay") M(makeRand,"•MakeRand") M(reBQN,"•ReBQN") M(exit,"•Exit") M(getLine,"•GetLine") \ /*internal.c*/M(itype,"•internal.Type") M(refc,"•internal.Refc") M(squeeze,"•internal.Squeeze") M(isPure,"•internal.IsPure") A(info,"•internal.Info") \ /*internal.c*/D(variation,"•internal.Variation") A(listVariations,"•internal.ListVariations") M(clearRefs,"•internal.ClearRefs") M(unshare,"•internal.Unshare") diff --git a/src/vm.c b/src/vm.c index 08273b1b..458c11ee 100644 --- a/src/vm.c +++ b/src/vm.c @@ -455,7 +455,7 @@ NOINLINE void v_setR(Scope* pscs[], B s, B x, bool upd) { v_set(pscs, c, ns_getU(x, sc->body->nsDesc->nameList, nameID), upd); } else if (isExt(c)) { ScopeExt* ext = pscs[(u16)(c.u>>32)]->ext; - v_set(pscs, c, ns_getNU(x, ext->vars[(u32)c.u + ext->varAm]), upd); + v_set(pscs, c, ns_getNU(x, ext->vars[(u32)c.u + ext->varAm], true), upd); } else if (isObj(c)) { assert(v(c)->type == t_fldAlias); Scope* sc = pscs[0];