aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2021-08-30 14:23:07 -0400
committerMarshall Lochbaum <mwlochbaum@gmail.com>2021-08-30 14:24:04 -0400
commit3761d5a57ab3c9ee6db96a4e1381048f1060a71c (patch)
tree544fdcba547fa169b0862dbd1f9b4d2d6ead9cb6
parent13318ddb9ec7b51baa7d9d693f2392d1de270acc (diff)
Expose REPL functionality more cleanly, fixing •path in Node REPL
-rwxr-xr-xbqn.js10
-rw-r--r--docs/bqn.js74
2 files changed, 43 insertions, 41 deletions
diff --git a/bqn.js b/bqn.js
index 04fe0b96..a0d8be07 100755
--- a/bqn.js
+++ b/bqn.js
@@ -6,10 +6,10 @@ let fs = require('fs');
let bqn = require("./docs/bqn.js");
module.exports = bqn;
-let {fmt,fmtErr,sysvals,sysargs,makebqn}=bqn;
+let {fmt,fmtErr,sysvals,sysargs,makebqn,makerepl}=bqn;
let {has,list,str,unstr,dynsys,req1str,makens}=bqn.util;
-let bqn_state=makebqn((u,s,x,w)=>(u(s,w),x));
-let bqn_nostate=makebqn((u,s,x,w)=>x);
+let bqn_state=makebqn((x,w,u,s)=>(u(s,w),x));
+let bqn_nostate=makebqn(x=>x);
let show = x => console.log(fmt(x));
sysvals.show = (x,w) => { show(x); return x; };
@@ -152,8 +152,8 @@ if (!module.parent) {
}
if (!has(arg0) || arg0==='-r') {
let stdin = process.stdin;
- let repl = sysvals.rebqn(cl_state())(makens(["repl"],[str("loose")]));
- let e = exec(s=>show(repl(str(s))));
+ let repl = makerepl(cl_state(), 1);
+ let e = exec(s=>show(repl(s)));
stdin.on('end', () => { process.exit(); });
stdin.on('readable', () => {
let inp; while ((inp=stdin.read())!==null) {
diff --git a/docs/bqn.js b/docs/bqn.js
index 0436c5f4..6b2e7c2d 100644
--- a/docs/bqn.js
+++ b/docs/bqn.js
@@ -490,10 +490,10 @@ let dojs = (x,w) => {
let update_state = (st,w)=>w; // Modified by Node version to handle •state
let makebqn = (proc,fn) => st => (x,w) => {
- let src = proc(update_state,st,x,w);
+ let src = proc(x,w,update_state,st);
return fn(st.comps(st)(src));
}
-let makebqnfn = (e,fn) => makebqn((u,s,x,w)=>req1str(e,x,u(s,w)), fn);
+let makebqnfn = (e,fn) => makebqn((x,w,u,s)=>req1str(e,x,u(s,w)), fn);
let copy_state = st_old => { let st={...st_old}; st.addrt=[]; return st; }
let dynsys_copy = fn => dynsys(st => fn(copy_state(st)));
@@ -505,43 +505,44 @@ let rebqn = dynsys_copy(state => (x,w) => {
let [repl,primitives] = ["repl","primitives"]
.map(s=>(i=>has(i)?x[x.ns[i]]:i)(rev[s]));
- if (has(primitives)) {
- let p = primitives;
- req(p.sh && p.sh.length===1, "𝕩.primitives must be a list");
- req(p.every(e=>e.sh&&e.sh.length===1&&e.sh[0]===2), "𝕩.primitives must contain glyph-primitive pairs");
- let pr=glyphs.map(_=>[]), l=0, rt=pr.map(_=>[]);
- p.forEach(([gl,val])=>{
- req(typeof gl==="string", "Primitive glyphs must be characters");
- req(isfunc(val), "Primitives must be operations");
- let k=val.m||0;
- pr[k].push(gl); rt[k].push(val);
- });
- state.glyphs = pr.map(str);
- state.runtime = list([].concat(...rt));
- compgen(state);
- }
+ if (has(primitives)) { addprimitives(state, primitives); }
let cmp = makebqnfn("•ReBQN evaluation", r=>r)(state);
- if (!has(repl) || (repl=unstr(repl))==="none") {
- return (x,w) => run(...cmp(x,w));
- } else {
- let rd = repl==="strict" ? 0 : -1;
- req(rd==0||repl==="loose", "invalid value for 𝕩.repl")
- let vars = [], names = [], redef = [];
- state.addrt = [names,redef];
- return (x,w) => {
- names.sh=redef.sh=[names.length];
- let c = cmp(x,w);
- let pnames = c[5][2][0];
- let newv = c[3][0][2].slice(vars.length);
- names.push(...newv.map(i=>pnames[i]));
- redef.push(...newv.map(i=>rd));
- vars .push(...newv.map(i=>null));
- c.push(vars);
- return run(...c);
- }
- }
+ repl = has(repl) ? ["none","loose","strict"].indexOf(unstr(repl)) : 0;
+ req(repl>=0, "invalid value for 𝕩.repl");
+ return repl ? rerepl(repl,cmp,state) : ((x,w) => run(...cmp(x,w)));
});
+let addprimitives = (state, p) => {
+ let req = (r,s) => { if (!r) throw Error("•ReBQN 𝕩.primitives: "+s) };
+ req(p.sh && p.sh.length===1, "Must be a list");
+ req(p.every(e=>e.sh&&e.sh.length===1&&e.sh[0]===2), "Must consist of glyph-primitive pairs");
+ let pr=glyphs.map(_=>[]), l=0, rt=pr.map(_=>[]);
+ p.forEach(([gl,val])=>{
+ req(typeof gl==="string", "Glyphs must be characters");
+ req(isfunc(val), "Primitives must be operations");
+ let k=val.m||0;
+ pr[k].push(gl); rt[k].push(val);
+ });
+ state.glyphs = pr.map(str);
+ state.runtime = list([].concat(...rt));
+ compgen(state);
+}
+let rerepl = (repl, cmp, state) => {
+ let rd = repl>1 ? 0 : -1;
+ let vars = [], names = [], redef = [];
+ state.addrt = [names,redef];
+ return (x,w) => {
+ names.sh=redef.sh=[names.length];
+ let c = cmp(x,w);
+ let pnames = c[5][2][0];
+ let newv = c[3][0][2].slice(vars.length);
+ names.push(...newv.map(i=>pnames[i]));
+ redef.push(...newv.map(i=>rd));
+ vars .push(...newv.map(i=>null));
+ c.push(vars);
+ return run(...c);
+ }
+}
let primitives = dynsys(state => {
let gl=[].concat(...state.glyphs), rt=state.runtime;
return list(gl.map((g,i) => list([g,rt[i]])));
@@ -580,6 +581,7 @@ if (typeof module!=='undefined') { // Node.js
bqn.fmt=fmt; bqn.fmtErr=fmtErr; bqn.compile=compile; bqn.run=run;
bqn.sysargs=sysargs; bqn.sysvals=sysvals;
bqn.makebqn=fn=>makebqn(fn,r=>run(...r));
+ bqn.makerepl=(st,repl)=>rerepl(repl, makebqn(x=>x,r=>r)(st), st);
bqn.util={has,list,str,unstr,dynsys,req1str,makens};
bqn.setexec = f => { update_state=f; }
module.exports=bqn;