disallow •ReBQN constructing namespaces, ignore RETD in interactive REPL

This commit is contained in:
dzaima 2023-05-27 16:34:44 +03:00
parent da5280021c
commit c03dd349e4
4 changed files with 41 additions and 21 deletions

View File

@ -105,12 +105,12 @@ B comp_currRe; // ⟨REPL mode ⋄ scope ⋄ compiler ⋄ runtime ⋄ glyphs ⋄
B rt_undo, rt_select, rt_slash, rt_insert, rt_depth,
rt_group, rt_under, rt_find;
Block* load_compObj(B x, B src, B path, Scope* sc) { // consumes x,src
Block* load_compObj(B x, B src, B path, Scope* sc, i32 nsResult) { // consumes x,src
SGet(x)
usz xia = IA(x);
if (xia!=6 & xia!=4) thrM("load_compObj: bad item count");
Block* r = xia==6? compileAll(Get(x,0),Get(x,1),Get(x,2),Get(x,3),Get(x,4),Get(x,5), src, inc(path), sc)
: compileAll(Get(x,0),Get(x,1),Get(x,2),Get(x,3),bi_N, bi_N, src, inc(path), sc);
Block* r = xia==6? compileAll(Get(x,0),Get(x,1),Get(x,2),Get(x,3),Get(x,4),Get(x,5), src, inc(path), sc, nsResult)
: compileAll(Get(x,0),Get(x,1),Get(x,2),Get(x,3),bi_N, bi_N, src, inc(path), sc, nsResult);
decG(x);
return r;
}
@ -121,11 +121,11 @@ Block* load_compObj(B x, B src, B path, Scope* sc) { // consumes x,src
#if RT_SRC
Block* load_compImport(char* name, B bc, B objs, B blocks, B bodies, B inds, B src) { // consumes all
return compileAll(bc, objs, blocks, bodies, inds, bi_N, src, m_c8vec_0(name), NULL);
return compileAll(bc, objs, blocks, bodies, inds, bi_N, src, m_c8vec_0(name), NULL, 0);
}
#else
Block* load_compImport(char* name, B bc, B objs, B blocks, B bodies) { // consumes all
return compileAll(bc, objs, blocks, bodies, bi_N, bi_N, bi_N, m_c8vec_0(name), NULL);
return compileAll(bc, objs, blocks, bodies, bi_N, bi_N, bi_N, m_c8vec_0(name), NULL, 0);
}
#endif
@ -145,7 +145,7 @@ void switchComp(void) {
}
#endif
B compObj_c1(B t, B x) {
Block* block = load_compObj(x, bi_N, bi_N, NULL);
Block* block = load_compObj(x, bi_N, bi_N, NULL, 0);
B res = evalFunBlock(block, 0);
ptr_dec(block);
return res;
@ -188,7 +188,7 @@ B bqn_repr(B x) {
static NOINLINE Block* bqn_compc(B str, B path, B args, B comp, B compArg) { // consumes str,path,args
str = chr_squeeze(str);
PUSH_COMP;
Block* r = load_compObj(c2G(comp, incG(compArg), inc(str)), str, path, NULL);
Block* r = load_compObj(c2G(comp, incG(compArg), inc(str)), str, path, NULL, 0);
dec(path); dec(args);
POP_COMP; popCatch();
return r;
@ -196,13 +196,13 @@ static NOINLINE Block* bqn_compc(B str, B path, B args, B comp, B compArg) { //
Block* bqn_comp(B str, B path, B args) { // consumes all
return bqn_compc(str, path, args, load_comp, load_compArg);
}
Block* bqn_compScc(B str, B path, B args, Scope* sc, B comp, B rt, bool repl) { // consumes str,path,args
Block* bqn_compScc(B str, B path, B args, Scope* sc, B comp, B rt, bool loose, bool noNS) { // consumes str,path,args
str = chr_squeeze(str);
PUSH_COMP;
B vName = emptyHVec();
B vDepth = emptyIVec();
if (repl && (!sc || sc->psc)) thrM("VM compiler: REPL mode must be used at top level scope");
i32 depth = repl? -1 : 0;
if (loose && (!sc || sc->psc)) thrM("VM compiler: REPL mode must be used at top level scope");
i32 depth = loose? -1 : 0;
Scope* csc = sc;
while (csc) {
B vars = listVars(csc);
@ -212,13 +212,13 @@ Block* bqn_compScc(B str, B path, B args, Scope* sc, B comp, B rt, bool repl) {
csc = csc->psc;
depth++;
}
Block* r = load_compObj(c2G(comp, m_hvec4(incG(rt), incG(bi_sys), vName, vDepth), inc(str)), str, path, sc);
Block* r = load_compObj(c2G(comp, m_hvec4(incG(rt), incG(bi_sys), vName, vDepth), inc(str)), str, path, sc, sc!=NULL? (noNS? -1 : 1) : 0);
dec(path); dec(args);
POP_COMP; popCatch();
return r;
}
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);
return bqn_compScc(str, path, args, sc, load_comp, load_rtObj, repl, false);
}
B bqn_exec(B str, B path, B args) { // consumes all
@ -335,7 +335,7 @@ B rebqn_exec(B str, B path, B args, B o) {
B res;
Block* block;
if (replMode>0) {
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, true);
comp_currRe = prevRe;
ptr_dec(sc->body);
sc->body = ptr_inc(block->bodies[0]);
@ -512,7 +512,7 @@ void load_init() { // very last init function
#ifdef PRECOMP
Block* c = compileAll(
#include "../build/interp"
, bi_N, bi_N, bi_N, bi_N, NULL
, bi_N, bi_N, bi_N, bi_N, NULL, 0
);
B interp = evalFunBlock(c, 0); ptr_dec(c);
printI(interp);

View File

@ -141,7 +141,8 @@ typedef struct NextRequest {
static B emptyARMM;
Block* compileBlock(B block, Comp* comp, bool* bDone, u32* bc, usz bcIA, B allBlocks, B allBodies, B nameList, Scope* sc, i32 depth, i32 myPos) {
Block* compileBlock(B block, Comp* comp, bool* bDone, u32* bc, usz bcIA, B allBlocks, B allBodies, B nameList, Scope* sc, i32 depth, i32 myPos, i32 nsResult) {
assert(sc!=NULL || nsResult==0);
usz blIA = IA(block);
if (blIA!=3) thrM("VM compiler: Bad block info size");
SGetU(block)
@ -314,8 +315,15 @@ Block* compileBlock(B block, Comp* comp, bool* bDone, u32* bc, usz bcIA, B allBl
ret = true;
break;
case RETD: if(h!=1&h!=0) thrM("VM compiler: RETD expected to be called with no more than 1 item on the stack");
if (h==1) TSADD(newBC, POPS);
TSADD(newBC, RETD);
if (nsResult!=0 && depth==0) {
if (nsResult==-1) thrM("Cannot construct a namespace for a REPL result");
assert(nsResult==1);
if (h==0) thrM("No value for REPL expression to return");
TSADD(newBC, RETN);
} else {
if (h==1) TSADD(newBC, POPS);
TSADD(newBC, RETD);
}
ret = true;
break;
case DFND: {
@ -323,7 +331,7 @@ Block* compileBlock(B block, Comp* comp, bool* bDone, u32* bc, usz bcIA, B allBl
if ((u32)id >= IA(allBlocks)) thrM("VM compiler: DFND index out-of-bounds");
if (bDone[id]) thrM("VM compiler: DFND of the same block in multiple places");
bDone[id] = true;
Block* bl = compileBlock(IGetU(allBlocks,id), comp, bDone, bc, bcIA, allBlocks, allBodies, nameList, sc, depth+1, c-bc);
Block* bl = compileBlock(IGetU(allBlocks,id), comp, bDone, bc, bcIA, allBlocks, allBodies, nameList, sc, depth+1, c-bc, 0);
TSADD(newBC, bl->ty==0? DFND0 : bl->ty==1? DFND1 : DFND2);
A64(ptr2u64(bl));
TSADD(usedBlocks, bl);
@ -444,7 +452,7 @@ Block* compileBlock(B block, Comp* comp, bool* bDone, u32* bc, usz bcIA, B allBl
// consumes all; assumes arguments are valid (verifies some stuff, but definitely not everything)
// if sc isn't NULL, this block must only be evaluated directly in that scope precisely once
NOINLINE Block* compileAll(B bcq, B objs, B allBlocks, B allBodies, B indices, B tokenInfo, B src, B path, Scope* sc) {
NOINLINE Block* compileAll(B bcq, B objs, B allBlocks, B allBodies, B indices, B tokenInfo, B src, B path, Scope* sc, i32 nsResult) {
usz bIA = IA(allBlocks);
I32Arr* bca = toI32Arr(bcq);
u32* bc = (u32*)bca->a;
@ -481,7 +489,7 @@ NOINLINE Block* compileAll(B bcq, B objs, B allBlocks, B allBodies, B indices, B
}
TALLOC(bool,bDone,bIA);
for (usz i = 0; i < bIA; i++) bDone[i] = false;
Block* ret = compileBlock(IGetU(allBlocks, 0), comp, bDone, bc, bcIA, allBlocks, allBodies, nameList, sc, 0, 0);
Block* ret = compileBlock(IGetU(allBlocks, 0), comp, bDone, bc, bcIA, allBlocks, allBodies, nameList, sc, 0, 0, nsResult);
TFREE(bDone);
ptr_dec(comp); decG(allBlocks); decG(allBodies); dec(tokenInfo);
return ret;

View File

@ -154,7 +154,7 @@ struct 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* compileAll(B bcq, B objs, B blocks, B bodies, B indices, B tokenInfo, B src, B path, Scope* sc);
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
void init_comp(B* set, B prim, B sys); // doesn't consume; writes into first 3 elements of set

View File

@ -13,8 +13,20 @@
f•ReBQN {system"all"} F "•internal.Type ↕10" %% "i8arr"
!"Unknown system function •internal" % f•ReBQN {system"none"} F "•internal.Type ↕10"
f•ReBQN {system"range" "add"+ "reverse"} F "•Reverse ¯5 •Add •Range 10" %% 4-10
f•ReBQN{} F "Ah"•internal.Variation"1↑""""" %% " "
F(•ReBQN{repl"none" })({𝕩˜𝕩@+10}•CurrentError) F"a←↕2", F"a←↕3", F"a" %% 01,012,"Undefined identifier"
F(•ReBQN{repl"loose" })({𝕩˜𝕩@+10}•CurrentError) F"a←↕2", F"a←↕3", F"a" %% 01,012,012
F(•ReBQN{repl"strict"})({𝕩˜𝕩@+10}•CurrentError) F"a←↕2", F"a←↕3", F"a" %% 01,"Redefinition",01
f •ReBQN{repl"none"} !6•Type F "a⇐1"
f •ReBQN{repl"none"} !6•Type F "⇐"
!"Cannot construct a namespace for a REPL result" % f •ReBQN{repl"loose"} F "a⇐1"
!"Cannot construct a namespace for a REPL result" % f •ReBQN{repl"loose"} 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 "⇐"
# •primitives
!´2=•Type¨ ¨•primitives
!¨ (•Type¨1¨•primitives)345