make •Import follow ReBQN
This commit is contained in:
parent
56a6a08b97
commit
653583eb1d
@ -301,24 +301,6 @@ B find_c2(B t, B w, B x) {
|
||||
decG(x); decG(w); return r;
|
||||
}
|
||||
|
||||
static H_b2i* prevImports;
|
||||
i32 getPrevImport(B path) { // -1 for unset, -2 for unfinished
|
||||
if (prevImports==NULL) prevImports = m_b2i(16);
|
||||
|
||||
bool had; i32 prev = mk_b2i(&prevImports, path, &had);
|
||||
if (had && prevImports->a[prev].val!=-1) return prevImports->a[prev].val;
|
||||
prevImports->a[prev].val = -2;
|
||||
return -1;
|
||||
}
|
||||
void setPrevImport(B path, i32 pos) {
|
||||
bool had; i32 prev = mk_b2i(&prevImports, path, &had);
|
||||
prevImports->a[prev].val = pos;
|
||||
}
|
||||
void clearImportCacheMap(void) {
|
||||
if (prevImports!=NULL) free_b2i(prevImports);
|
||||
prevImports = NULL;
|
||||
}
|
||||
|
||||
static H_b2i* globalNames;
|
||||
B globalNameList;
|
||||
i32 str2gid(B s) {
|
||||
@ -373,7 +355,6 @@ B tack_uc1(B t, B o, B x) {
|
||||
|
||||
|
||||
void fun_gcFn(void) {
|
||||
if (prevImports!=NULL) mm_visitP(prevImports);
|
||||
if (globalNames!=NULL) mm_visitP(globalNames);
|
||||
}
|
||||
static void print_funBI(FILE* f, B x) { fprintf(f, "%s", pfn_repr(c(Fun,x)->extra)); }
|
||||
|
||||
@ -825,54 +825,42 @@ static NFnDesc* importDesc;
|
||||
|
||||
|
||||
B import_c2(B d, B w, B x) {
|
||||
return bqn_execFile(path_rel(nfn_objU(d), x, "•Import"), w);
|
||||
B* o = harr_ptr(nfn_objU(d));
|
||||
B path = path_abs(path_rel(o[0], x, "•Import"));
|
||||
B re = o[1];
|
||||
return bqn_execFileRe(path, w, re);
|
||||
}
|
||||
|
||||
// defined in fns.c
|
||||
i32 getPrevImport(B path);
|
||||
void setPrevImport(B path, i32 pos);
|
||||
void clearImportCacheMap(void);
|
||||
|
||||
static B importKeyList; // exists for GC roots as the hashmap doesn't
|
||||
static B importValList;
|
||||
B import_c1(B d, B x) {
|
||||
if (importKeyList.u==0) {
|
||||
importKeyList = emptyHVec();
|
||||
importValList = emptyHVec();
|
||||
}
|
||||
B path = path_abs(path_rel(nfn_objU(d), x, "•Import"));
|
||||
B* o = harr_ptr(nfn_objU(d));
|
||||
B path = path_abs(path_rel(o[0], x, "•Import"));
|
||||
B re = o[1];
|
||||
B map = IGetU(re, re_map);
|
||||
|
||||
i32 prevIdx = getPrevImport(path);
|
||||
if (prevIdx>=0) {
|
||||
B tag_none = tag(100000000, C32_TAG);
|
||||
B tag_running = tag(100000001, C32_TAG);
|
||||
B prevVal = c2(ns_getC(map, "get"), tag_none, incG(path));
|
||||
if (prevVal.u == tag_running.u) thrF("•Import: cyclic import of \"%R\"", path);
|
||||
if (prevVal.u != tag_none.u) {
|
||||
// print_fmt("cached: %R @ %i/%i\n", path, prevIdx, IA(importKeyList));
|
||||
dec(path);
|
||||
return IGet(importValList, prevIdx);
|
||||
decG(path);
|
||||
return prevVal;
|
||||
}
|
||||
if (prevIdx==-2) thrF("•Import: cyclic import of \"%R\"", path);
|
||||
|
||||
B nsSet = ns_getC(map, "set");
|
||||
decG(c2(nsSet, incG(path), tag_running));
|
||||
if (CATCH) {
|
||||
setPrevImport(path, -1);
|
||||
decG(c1(ns_getC(map, "delete"), incG(path)));
|
||||
rethrow();
|
||||
}
|
||||
|
||||
i32 prevLen = IA(importValList);
|
||||
importKeyList = vec_addN(importKeyList, path);
|
||||
importValList = vec_addN(importValList, bi_N);
|
||||
|
||||
B r = bqn_execFile(incG(path), emptySVec());
|
||||
|
||||
harr_ptr(importValList)[prevLen] = inc(r);
|
||||
setPrevImport(path, prevLen);
|
||||
B r = bqn_execFileRe(incG(path), emptySVec(), re);
|
||||
popCatch();
|
||||
|
||||
decG(c2(nsSet, path, inc(r))); // path finally consumed
|
||||
|
||||
return r;
|
||||
}
|
||||
void clearImportCache(void) {
|
||||
if (importKeyList.u!=0) {
|
||||
dec(importKeyList); importKeyList = m_f64(0);
|
||||
dec(importValList); importValList = m_f64(0);
|
||||
}
|
||||
clearImportCacheMap();
|
||||
}
|
||||
|
||||
|
||||
static NFnDesc* fTypeDesc;
|
||||
@ -1716,7 +1704,7 @@ B invalidMd1_c2(Md1D* d, B w, B x) { thrM("Using an invalid 1-modifier"); }
|
||||
B invalidMd2_c1(Md2D* d, B x) { thrM("Using an invalid 2-modifier"); }
|
||||
B invalidMd2_c2(Md2D* d, B w, B x) { thrM("Using an invalid 2-modifier"); }
|
||||
|
||||
static void initFileNS() {
|
||||
static NOINLINE void initSysDesc() {
|
||||
if (fileInit) return;
|
||||
fileInit = true;
|
||||
file_nsGen = m_nnsDesc("path","at","list","bytes","chars","lines","type","created","accessed","modified","size","exists","name","parent","mapbytes","createdir","realpath","rename","remove");
|
||||
@ -1839,18 +1827,18 @@ B sys_c1(B t, B x) {
|
||||
case 3: cr = getBitNS(); break; // •bit
|
||||
case 4: cr = comps_getPrimitives(); break; // •primitives
|
||||
case 5: cr = getInternalNS(); break; // •internal
|
||||
case 6: initFileNS(); cr = m_nfn(fCharsDesc, inc(REQ_PATH)); break; // •FChars
|
||||
case 7: initFileNS(); cr = m_nfn(fBytesDesc, inc(REQ_PATH)); break; // •FBytes
|
||||
case 8: initFileNS(); cr = m_nfn(fLinesDesc, inc(REQ_PATH)); break; // •FLines
|
||||
case 9: initFileNS(); cr = m_nfn(importDesc, inc(REQ_PATH)); break; // •Import
|
||||
case 10: initFileNS(); cr = m_nfn(ffiloadDesc, inc(REQ_PATH)); break; // •FFI
|
||||
case 6: initSysDesc(); cr = m_nfn(fCharsDesc, inc(REQ_PATH)); break; // •FChars
|
||||
case 7: initSysDesc(); cr = m_nfn(fBytesDesc, inc(REQ_PATH)); break; // •FBytes
|
||||
case 8: initSysDesc(); cr = m_nfn(fLinesDesc, inc(REQ_PATH)); break; // •FLines
|
||||
case 9: initSysDesc(); cr = m_nfn(importDesc, m_hvec2(inc(REQ_PATH), incG(COMPS_CREF(re)))); break; // •Import
|
||||
case 10: initSysDesc(); cr = m_nfn(ffiloadDesc, inc(REQ_PATH)); break; // •FFI
|
||||
case 11: if (q_N(name)) thrM("No name present for •name"); cr = inc(name); break; // •name
|
||||
case 12: if (q_N(path0)) thrM("No path present for •path"); cr = inc(REQ_PATH); break; // •path
|
||||
case 13: { cr = inc(CACHE_OBJ(wdpath, path_abs(inc(cdPath)))); break; } // •wdpath
|
||||
case 14: { // •file
|
||||
#define F(X) m_nfn(X##Desc, inc(path))
|
||||
cr = incG(CACHE_OBJ(fileNS, ({
|
||||
initFileNS();
|
||||
initSysDesc();
|
||||
REQ_PATH;
|
||||
m_nns(file_nsGen, q_N(path)? m_c32(0) : inc(path), F(fileAt), F(fList), F(fBytes), F(fChars), F(fLines), F(fType), F(fCreated), F(fAccessed), F(fModified), F(fSize), F(fExists), inc(bi_fName), inc(bi_fParent), F(fMapBytes), F(createdir), F(realpath), F(rename), F(remove));
|
||||
})));
|
||||
@ -1936,8 +1924,6 @@ void sysfn_init(void) {
|
||||
#endif
|
||||
cdPath = m_c8vec(".", 1); gc_add(cdPath);
|
||||
|
||||
gc_add_ref(&importKeyList);
|
||||
gc_add_ref(&importValList);
|
||||
gc_add_ref(&thrownMsg);
|
||||
|
||||
bqnDesc = registerNFn(m_c32vec_0(U"•BQN"), bqn_c1, bqn_c2);
|
||||
|
||||
22
src/load.c
22
src/load.c
@ -113,6 +113,10 @@ static NOINLINE B m_lvi32_2(i32 a, i32 b ) { i32* rp; B r = m_i32ar
|
||||
static NOINLINE B m_lvi32_3(i32 a, i32 b, i32 c ) { i32* rp; B r = m_i32arrv(&rp,3); rp[0]=a; rp[1]=b; rp[2]=c; return r; }
|
||||
static NOINLINE B m_lvi32_4(i32 a, i32 b, i32 c, i32 d) { i32* rp; B r = m_i32arrv(&rp,4); rp[0]=a; rp[1]=b; rp[2]=c; rp[3]=d; return r; }
|
||||
|
||||
static NOINLINE B m_importMap(void) {
|
||||
return c2(bi_hashMap, emptyHVec(), emptyHVec());
|
||||
}
|
||||
|
||||
static NOINLINE B evalFunBlockConsume(Block* block) {
|
||||
B r = evalFunBlock(block, NULL);
|
||||
ptr_dec(block);
|
||||
@ -288,6 +292,7 @@ void init_comp(B* new_re, B* prev_re, B prim, B sys) {
|
||||
prh.a[np[t]++] = v;
|
||||
}
|
||||
|
||||
new_re[re_map] = m_importMap();
|
||||
new_re[re_rt] = prh.b;
|
||||
new_re[re_glyphs] = inc(rb);
|
||||
new_re[re_comp] = c1(load_compgen, rb);
|
||||
@ -397,6 +402,13 @@ B repl_exec(B str, B state, B re) {
|
||||
}
|
||||
}
|
||||
|
||||
void clearImportCache(void) {
|
||||
B* where = harr_ptr(def_re)+re_map;
|
||||
B prev = *where;
|
||||
*where = m_importMap();
|
||||
decG(prev);
|
||||
}
|
||||
|
||||
B invalidFn_c1(B t, B x);
|
||||
|
||||
void comps_gcFn(void) {
|
||||
@ -572,6 +584,7 @@ void load_init() { // very last init function
|
||||
ps.a[re_comp] = load_comp;
|
||||
ps.a[re_compOpts] = load_compOpts;
|
||||
ps.a[re_rt] = incG(load_rt);
|
||||
ps.a[re_map] = m_importMap();
|
||||
ps.a[re_glyphs] = load_glyphs;
|
||||
ps.a[re_sysNames] = incG(def_sysNames);
|
||||
ps.a[re_sysVals] = incG(def_sysVals);
|
||||
@ -593,8 +606,15 @@ void load_init() { // very last init function
|
||||
}
|
||||
|
||||
NOINLINE B m_state(B path, B name, B args) { return m_lvB_3(path, name, args); }
|
||||
static NOINLINE B fileState(B path, B args) { // consumes args
|
||||
return m_state(path_parent(inc(path)), path_name(inc(path)), args);
|
||||
}
|
||||
B bqn_execFileRe(B path, B args, B re) {
|
||||
B state = fileState(path, args);
|
||||
return evalFunBlockConsume(bqn_compc(path_chars(path), state, re));
|
||||
}
|
||||
B bqn_execFile(B path, B args) { // consumes both
|
||||
B state = m_state(path_parent(inc(path)), path_name(inc(path)), args);
|
||||
B state = fileState(path, args);
|
||||
return bqn_exec(path_chars(path), state);
|
||||
}
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ enum {
|
||||
};
|
||||
enum {
|
||||
re_comp, re_compOpts, re_rt, re_glyphs, re_sysNames, re_sysVals, // compiling info
|
||||
re_map, // •HashMap of cached import results
|
||||
re_mode, re_scope, // only for repl_exec
|
||||
re_max
|
||||
};
|
||||
@ -25,6 +26,7 @@ typedef struct Block Block;
|
||||
typedef struct Scope Scope;
|
||||
B bqn_explain(B str); // consumes str
|
||||
B bqn_execFile(B path, B args); // consumes both
|
||||
B bqn_execFileRe(B path, B args, B re); // consumes path,args
|
||||
Block* bqn_comp (B str, B state); // consumes both
|
||||
Block* bqn_compSc (B str, B state, Scope* sc, bool repl); // consumes str,state
|
||||
Block* bqn_compScc(B str, B state, B re, Scope* sc, bool loose, bool noNS); // consumes str,state
|
||||
|
||||
@ -3,11 +3,18 @@
|
||||
File ← {path0 •file.At 𝕩}
|
||||
CleanPath ← ! {r←•file.RealPath path0 ⋄ ≠i←/r ⍷ 𝕩? (⋈⁼i)(↑∾"..."∾(≠r)⊸+⊸↓)𝕩; 𝕩}∘•CurrentError∘@
|
||||
)
|
||||
|
||||
(
|
||||
%USE file
|
||||
i1 ← •Import File "show.bqn" ⋄ ! "show.bqn"‿⟨⟩ ≡ 1↓i1
|
||||
i2 ← •Import File "show.bqn" ⋄ ! "show.bqn"‿⟨⟩ ≡ 1↓i2
|
||||
! i1 ≡ i2
|
||||
f ← File "show.bqn"
|
||||
r1 ← •Import f ⋄ ! +‿"show.bqn"‿⟨⟩ ≡ 1↓r1
|
||||
r2 ← •Import f ⋄ ! +‿"show.bqn"‿⟨⟩ ≡ 1↓r2
|
||||
! r1 ≡○⊑ r2
|
||||
re ← •ReBQN{primitives⇐⟨'+'‿-⟩}
|
||||
import2 ← RE "•Import"
|
||||
r3 ← Import2 f ⋄ ! -‿"show.bqn"‿⟨⟩ ≡ 1↓r3
|
||||
r4 ← Import2 f ⋄ ! -‿"show.bqn"‿⟨⟩ ≡ 1↓r4
|
||||
! r1‿r3 ≡ ⍷⊑¨r1‿r2‿r3‿r4
|
||||
)
|
||||
|
||||
!"•Import: cyclic import of "".../cyclic.bqn""" % %USE file ⋄ •Import⎊CleanPath File "cyclic.bqn"
|
||||
|
||||
@ -1 +1 @@
|
||||
⟨{⇐}, "show.bqn", •args⟩
|
||||
⟨{⇐}, +, "show.bqn", •args⟩
|
||||
|
||||
Loading…
Reference in New Issue
Block a user