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,
|
B rt_undo, rt_select, rt_slash, rt_insert, rt_depth,
|
||||||
rt_group, rt_under, rt_find;
|
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)
|
SGet(x)
|
||||||
usz xia = IA(x);
|
usz xia = IA(x);
|
||||||
if (xia!=6 & xia!=4) thrM("load_compObj: bad item count");
|
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)
|
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);
|
: compileAll(Get(x,0),Get(x,1),Get(x,2),Get(x,3),bi_N, bi_N, src, inc(path), sc, nsResult);
|
||||||
decG(x);
|
decG(x);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -121,11 +121,11 @@ Block* load_compObj(B x, B src, B path, Scope* sc) { // consumes x,src
|
|||||||
|
|
||||||
#if RT_SRC
|
#if RT_SRC
|
||||||
Block* load_compImport(char* name, B bc, B objs, B blocks, B bodies, B inds, B src) { // consumes all
|
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
|
#else
|
||||||
Block* load_compImport(char* name, B bc, B objs, B blocks, B bodies) { // consumes all
|
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
|
#endif
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ void switchComp(void) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
B compObj_c1(B t, B x) {
|
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);
|
B res = evalFunBlock(block, 0);
|
||||||
ptr_dec(block);
|
ptr_dec(block);
|
||||||
return res;
|
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
|
static NOINLINE Block* bqn_compc(B str, B path, B args, B comp, B compArg) { // consumes str,path,args
|
||||||
str = chr_squeeze(str);
|
str = chr_squeeze(str);
|
||||||
PUSH_COMP;
|
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);
|
dec(path); dec(args);
|
||||||
POP_COMP; popCatch();
|
POP_COMP; popCatch();
|
||||||
return r;
|
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
|
Block* bqn_comp(B str, B path, B args) { // consumes all
|
||||||
return bqn_compc(str, path, args, load_comp, load_compArg);
|
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);
|
str = chr_squeeze(str);
|
||||||
PUSH_COMP;
|
PUSH_COMP;
|
||||||
B vName = emptyHVec();
|
B vName = emptyHVec();
|
||||||
B vDepth = emptyIVec();
|
B vDepth = emptyIVec();
|
||||||
if (repl && (!sc || sc->psc)) thrM("VM compiler: REPL mode must be used at top level scope");
|
if (loose && (!sc || sc->psc)) thrM("VM compiler: REPL mode must be used at top level scope");
|
||||||
i32 depth = repl? -1 : 0;
|
i32 depth = loose? -1 : 0;
|
||||||
Scope* csc = sc;
|
Scope* csc = sc;
|
||||||
while (csc) {
|
while (csc) {
|
||||||
B vars = listVars(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;
|
csc = csc->psc;
|
||||||
depth++;
|
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);
|
dec(path); dec(args);
|
||||||
POP_COMP; popCatch();
|
POP_COMP; popCatch();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
NOINLINE Block* bqn_compSc(B str, B path, B args, Scope* sc, bool repl) { // consumes str,path,args
|
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
|
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;
|
B res;
|
||||||
Block* block;
|
Block* block;
|
||||||
if (replMode>0) {
|
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;
|
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]);
|
||||||
@ -512,7 +512,7 @@ void load_init() { // very last init function
|
|||||||
#ifdef PRECOMP
|
#ifdef PRECOMP
|
||||||
Block* c = compileAll(
|
Block* c = compileAll(
|
||||||
#include "../build/interp"
|
#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);
|
B interp = evalFunBlock(c, 0); ptr_dec(c);
|
||||||
printI(interp);
|
printI(interp);
|
||||||
|
|||||||
20
src/vm.c
20
src/vm.c
@ -141,7 +141,8 @@ typedef struct NextRequest {
|
|||||||
|
|
||||||
static B emptyARMM;
|
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);
|
usz blIA = IA(block);
|
||||||
if (blIA!=3) thrM("VM compiler: Bad block info size");
|
if (blIA!=3) thrM("VM compiler: Bad block info size");
|
||||||
SGetU(block)
|
SGetU(block)
|
||||||
@ -314,8 +315,15 @@ Block* compileBlock(B block, Comp* comp, bool* bDone, u32* bc, usz bcIA, B allBl
|
|||||||
ret = true;
|
ret = true;
|
||||||
break;
|
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");
|
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);
|
if (nsResult!=0 && depth==0) {
|
||||||
TSADD(newBC, RETD);
|
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;
|
ret = true;
|
||||||
break;
|
break;
|
||||||
case DFND: {
|
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 ((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");
|
if (bDone[id]) thrM("VM compiler: DFND of the same block in multiple places");
|
||||||
bDone[id] = true;
|
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);
|
TSADD(newBC, bl->ty==0? DFND0 : bl->ty==1? DFND1 : DFND2);
|
||||||
A64(ptr2u64(bl));
|
A64(ptr2u64(bl));
|
||||||
TSADD(usedBlocks, 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)
|
// 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
|
// 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);
|
usz bIA = IA(allBlocks);
|
||||||
I32Arr* bca = toI32Arr(bcq);
|
I32Arr* bca = toI32Arr(bcq);
|
||||||
u32* bc = (u32*)bca->a;
|
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);
|
TALLOC(bool,bDone,bIA);
|
||||||
for (usz i = 0; i < bIA; i++) bDone[i] = false;
|
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);
|
TFREE(bDone);
|
||||||
ptr_dec(comp); decG(allBlocks); decG(allBodies); dec(tokenInfo);
|
ptr_dec(comp); decG(allBlocks); decG(allBodies); dec(tokenInfo);
|
||||||
return ret;
|
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_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* 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);
|
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, B sys); // 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
|
||||||
|
|||||||
@ -13,8 +13,20 @@
|
|||||||
f←•ReBQN {system⇐"all"} ⋄ F "•internal.Type ↕10" %% "i8arr"
|
f←•ReBQN {system⇐"all"} ⋄ F "•internal.Type ↕10" %% "i8arr"
|
||||||
!"Unknown system function •internal" % f←•ReBQN {system⇐"none"} ⋄ F "•internal.Type ↕10"
|
!"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 {system⇐⟨"range"‿↕ ⋄ "add"‿+ ⋄ "reverse"‿⌽⟩} ⋄ F "•Reverse ¯5 •Add •Range 10" %% 4-↕10
|
||||||
|
|
||||||
f←•ReBQN{⇐} ⋄ F "Ah"•internal.Variation"1↑""""" %% " "
|
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
|
# •primitives
|
||||||
!∧´2=•Type¨ ⊑¨•primitives
|
!∧´2=•Type¨ ⊑¨•primitives
|
||||||
!¨ (•Type¨1⊑¨•primitives)∊3‿4‿5
|
!¨ (•Type¨1⊑¨•primitives)∊3‿4‿5
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user