disallow •ReBQN constructing namespaces, ignore RETD in interactive REPL
This commit is contained in:
parent
da5280021c
commit
c03dd349e4
28
src/load.c
28
src/load.c
@ -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);
|
||||
|
||||
20
src/vm.c
20
src/vm.c
@ -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;
|
||||
|
||||
2
src/vm.h
2
src/vm.h
@ -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
|
||||
|
||||
@ -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"⟩ %% ⟨0‿1,0‿1‿2,"Undefined identifier"⟩
|
||||
F←(•ReBQN{repl⇐"loose" })⎊({𝕩↑˜⊑𝕩⊐@+10}•CurrentError) ⋄ ⟨F"a←↕2", F"a←↕3", F"a"⟩ %% ⟨0‿1,0‿1‿2,0‿1‿2⟩
|
||||
F←(•ReBQN{repl⇐"strict"})⎊({𝕩↑˜⊑𝕩⊐@+10}•CurrentError) ⋄ ⟨F"a←↕2", F"a←↕3", F"a"⟩ %% ⟨0‿1,"Redefinition",0‿1⟩
|
||||
|
||||
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)∊3‿4‿5
|
||||
|
||||
Loading…
Reference in New Issue
Block a user