system value redefining with •ReBQN

This commit is contained in:
dzaima 2022-10-19 22:53:40 +03:00
parent 4d9a63f68b
commit f2b6b5d446
4 changed files with 56 additions and 27 deletions

View File

@ -5,7 +5,7 @@ See [the BQN specification](https://mlochbaum.github.io/BQN/spec/system.html) fo
| function | notes | | function | notes |
|---------------|-------| |---------------|-------|
| `•BQN` | | | `•BQN` | |
| `•ReBQN` | Supported options: `repl`, `primitives` | | `•ReBQN` | Supported options: `repl`; `primitives`; `system` that's not `"safe"` |
| `•primitives` | | | `•primitives` | |
| `•Import` | | | `•Import` | |
| `•FFI` | see [FFI](#ffi) | | `•FFI` | see [FFI](#ffi) |

View File

@ -563,6 +563,7 @@ B reBQN_c1(B t, B x) {
if (!isNsp(x)) thrM("•ReBQN: Argument must be a namespace"); if (!isNsp(x)) thrM("•ReBQN: Argument must be a namespace");
B repl = ns_getC(x, "repl"); B repl = ns_getC(x, "repl");
B prim = ns_getC(x, "primitives"); B prim = ns_getC(x, "primitives");
B sys = ns_getC(x, "system");
i32 replVal = q_N(repl) || eqStr(repl,U"none")? 0 : eqStr(repl,U"strict")? 1 : eqStr(repl,U"loose")? 2 : 3; 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"); if (replVal==3) thrM("•ReBQN: Invalid repl value");
Block* initBlock = bqn_comp(m_c8vec_0("\"(REPL initializer)\""), inc(cdPath), m_f64(0)); Block* initBlock = bqn_comp(m_c8vec_0("\"(REPL initializer)\""), inc(cdPath), m_f64(0));
@ -574,9 +575,9 @@ B reBQN_c1(B t, B x) {
scVal = tag(sc,OBJ_TAG); scVal = tag(sc,OBJ_TAG);
} }
ptr_dec(initBlock); ptr_dec(initBlock);
HArr_p d = m_harrUv(5); d.a[0] = m_f64(replVal); d.a[1] = scVal; HArr_p d = m_harrUv(7); d.a[0] = m_f64(replVal); d.a[1] = scVal;
d.a[2]=d.a[3]=d.a[4]=bi_N; for (usz i=2; i<7; i++) d.a[i] = bi_N;
init_comp(d.a+2, prim); init_comp(d.a+2, prim, sys);
decG(x); decG(x);
return m_nfn(reBQNDesc, d.b); return m_nfn(reBQNDesc, d.b);
} }
@ -1371,6 +1372,7 @@ B getBitNS() {
B getInternalNS(void); B getInternalNS(void);
B getMathNS(void); B getMathNS(void);
B getPrimitives(void); B getPrimitives(void);
void getSysvals(B* res);
static Body* file_nsGen; static Body* file_nsGen;
@ -1451,14 +1453,12 @@ static void initFileNS() {
ffiloadDesc = registerNFn(m_c32vec_0(U"•FFI"), c1_bad, ffiload_c2); ffiloadDesc = registerNFn(m_c32vec_0(U"•FFI"), c1_bad, ffiload_c2);
} }
B dsv_obj;
B sys_c1(B t, B x) { B sys_c1(B t, B x) {
assert(isArr(x)); assert(isArr(x));
B sysvals = dsv_obj; B tmp[2]; getSysvals(tmp);
SGetU(sysvals) B curr_ns = tmp[0];
B curr_ns = GetU(sysvals,0); B curr_vs = tmp[1]; SGetU(curr_vs)
B curr_vs = GetU(sysvals,1); SGetU(curr_vs)
B idxs = indexOf_c2(m_f64(0), incG(curr_ns), incG(x)); SGetU(idxs) B idxs = indexOf_c2(m_f64(0), incG(curr_ns), incG(x)); SGetU(idxs)
B fileNS = m_f64(0); B fileNS = m_f64(0);
@ -1537,17 +1537,16 @@ static char* dsv_strs[] = {
#undef F #undef F
}; };
B dsv_ns, dsv_vs;
void sysfn_init() { void sysfn_init() {
usz dsv_num = sizeof(dsv_strs)/sizeof(char*); usz dsv_num = sizeof(dsv_strs)/sizeof(char*);
usz i = 0; usz i = 0;
HArr_p dsv_vs = m_harrUv(dsv_num); HArr_p dsv_ns0 = m_harrUv(dsv_num); dsv_ns=dsv_ns0.b; gc_add(dsv_ns);
#define F(L,N,B) dsv_vs.a[i] = inc(B); i++; for (usz i = 0; i < dsv_num; i++) dsv_ns0.a[i] = m_c8vec_0(dsv_strs[i]);
HArr_p dsv_vs0 = m_harrUv(dsv_num); dsv_vs=dsv_vs0.b; gc_add(dsv_vs);
#define F(L,N,B) dsv_vs0.a[i] = inc(B); i++;
FOR_DEFAULT_SYSVALS(F) FOR_DEFAULT_SYSVALS(F)
#undef F #undef F
HArr_p dsv_ns = m_harrUv(dsv_num);
for (usz i = 0; i < dsv_num; i++) dsv_ns.a[i] = m_c8vec_0(dsv_strs[i]);
dsv_obj = m_hVec2(dsv_ns.b, dsv_vs.b);
gc_add(dsv_obj);
#if CATCH_ERRORS #if CATCH_ERRORS
lastErrMsg = bi_N; lastErrMsg = bi_N;

View File

@ -101,7 +101,7 @@ i64 comp_currEnvPos;
B comp_currPath; B comp_currPath;
B comp_currArgs; B comp_currArgs;
B comp_currSrc; B comp_currSrc;
B comp_currRe; B comp_currRe; // ⟨REPL mode ⋄ scope ⋄ compiler ⋄ runtime ⋄ glyphs ⋄ sysval names ⋄ sysval values⟩
B rt_undo, rt_select, rt_slash, rt_pick, rt_take, rt_drop, rt_insert, rt_depth, B rt_undo, rt_select, rt_slash, rt_pick, rt_take, rt_drop, rt_insert, rt_depth,
rt_group, rt_under, rt_reverse, rt_indexOf, rt_count, rt_memberOf, rt_find, rt_transp; rt_group, rt_under, rt_reverse, rt_indexOf, rt_count, rt_memberOf, rt_find, rt_transp;
@ -212,7 +212,9 @@ B bqn_exec(B str, B path, B args) { // consumes all
return res; return res;
} }
void init_comp(B* set, B prim) { extern B dsv_ns, dsv_vs;
B str_all, str_none;
void init_comp(B* set, B prim, B sys) {
if (q_N(prim)) { if (q_N(prim)) {
set[0] = inc(load_comp); set[0] = inc(load_comp);
set[1] = inc(load_rtObj); set[1] = inc(load_rtObj);
@ -256,14 +258,36 @@ void init_comp(B* set, B prim) {
set[2] = inc(rb); set[2] = inc(rb);
set[0] = c1(load_compgen, rb); set[0] = c1(load_compgen, rb);
} }
if (q_N(sys)) {
all_sys:
set[3] = inc(dsv_ns);
set[4] = inc(dsv_vs);
} 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_none)) {
set[3] = set[4] = emptyHVec();
} else {
usz ia = IA(sys); SGetU(sys)
M_HARR(r1, ia);
M_HARR(r2, ia);
for (usz i = 0; i < ia; i++) {
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));
}
set[3] = HARR_FV(r1);
set[4] = HARR_FV(r2);
}
}
} }
B getPrimitives() { B getPrimitives() {
B g, r; B g, r;
if (q_N(comp_currRe)) { if (q_N(comp_currRe)) { g=load_glyphs; r=load_rtObj; }
g = load_glyphs; r = load_rtObj; else { B* o = harr_ptr(comp_currRe); g=o[4]; r=o[3]; }
} else {
B* o = harr_ptr(comp_currRe); g = o[4]; r = o[3];
}
B* pr = harr_ptr(r); B* pr = harr_ptr(r);
B* gg = harr_ptr(g); B* gg = harr_ptr(g);
M_HARR(ph, IA(r)); M_HARR(ph, IA(r));
@ -278,6 +302,12 @@ B getPrimitives() {
return HARR_FV(ph); return HARR_FV(ph);
} }
extern B dsv_ns, dsv_vs;
void getSysvals(B* res) {
if (q_N(comp_currRe)) { res[0]=dsv_ns; res[1]=dsv_vs; }
else { B* o=harr_ptr(comp_currRe); res[0]=o[5]; res[1]=o[6]; }
}
B rebqn_exec(B str, B path, B args, B o) { B rebqn_exec(B str, B path, B args, B o) {
B prevRe = comp_currRe; B prevRe = comp_currRe;
if (CATCH) { comp_currRe = prevRe; rethrow(); } if (CATCH) { comp_currRe = prevRe; rethrow(); }
@ -287,21 +317,21 @@ B rebqn_exec(B str, B path, B args, B o) {
i32 replMode = o2iG(op[0]); i32 replMode = o2iG(op[0]);
Scope* sc = c(Scope, op[1]); Scope* sc = c(Scope, op[1]);
B res; B res;
Block* block;
if (replMode>0) { if (replMode>0) {
Block* block = bqn_compScc(str, path, args, sc, op[2], op[3], replMode==2); block = bqn_compScc(str, path, args, sc, op[2], op[3], replMode==2);
comp_currRe = prevRe; comp_currRe = prevRe;
ptr_dec(sc->body); ptr_dec(sc->body);
sc->body = ptr_inc(block->bodies[0]); sc->body = ptr_inc(block->bodies[0]);
res = execBlockInline(block, sc); res = execBlockInline(block, sc);
ptr_dec(block);
} else { } else {
B rtsys = m_hVec2(inc(op[3]), incG(bi_sys)); B rtsys = m_hVec2(inc(op[3]), incG(bi_sys));
Block* block = bqn_compc(str, path, args, op[2], rtsys); block = bqn_compc(str, path, args, op[2], rtsys);
decG(rtsys); decG(rtsys);
comp_currRe = prevRe; comp_currRe = prevRe;
res = evalFunBlock(block, 0); res = evalFunBlock(block, 0);
ptr_dec(block);
} }
ptr_dec(block);
decG(o); decG(o);
popCatch(); popCatch();

View File

@ -156,7 +156,7 @@ Block* bqn_compSc(B str, B path, B args, Scope* sc, bool repl); // consumes str,
Block* compile(B bcq, B objs, B blocks, B bodies, B indices, B tokenInfo, B src, B path, Scope* sc); 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); 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 Body* m_body(i32 vam, i32 pos, u32 maxStack, u16 maxPSC); // leaves varData uninitialized
void init_comp(B* set, B prim); // doesn't consume; writes into first 3 elements of set void init_comp(B* set, B prim, B sys); // doesn't consume; writes into first 3 elements of set
B rebqn_exec(B str, B path, B args, B o); // consumes str,path,args B rebqn_exec(B str, B path, B args, B o); // consumes str,path,args
B listVars(Scope* sc); // doesn't consume; returns bi_N if not accessable B listVars(Scope* sc); // doesn't consume; returns bi_N if not accessable