native namespace creation
This commit is contained in:
parent
ef5864afbc
commit
4f66b6b88a
@ -2,6 +2,7 @@
|
||||
#include "../utils/each.h"
|
||||
#include "../builtins.h"
|
||||
#include "../nfns.h"
|
||||
#include "../ns.h"
|
||||
#include <math.h>
|
||||
|
||||
static inline B arith_recm(BB2B f, B x) {
|
||||
@ -72,12 +73,10 @@ static B mathNS;
|
||||
B getMathNS() {
|
||||
if (mathNS.u == 0) {
|
||||
#define F(X) inc(bi_##X),
|
||||
B fn = bqn_exec(m_str32(U"{⟨Sin, Cos, Tan, Asin, Acos, Atan ⟩⇐𝕩}"), emptyCVec(), emptySVec());
|
||||
B arg = m_caB(6, (B[]){F(sin)F(cos)F(tan)F(asin)F(acos)F(atan)});
|
||||
Body* d = m_nnsDesc("sin","cos","tan","asin","acos","atan");
|
||||
mathNS = m_nns(d, F(sin)F(cos)F(tan)F(asin)F(acos)F(atan));
|
||||
#undef F
|
||||
mathNS = c1(fn,arg);
|
||||
gc_add(mathNS);
|
||||
dec(fn);
|
||||
}
|
||||
return inc(mathNS);
|
||||
}
|
||||
|
||||
@ -343,7 +343,7 @@ i32 str2gid(B s) {
|
||||
|
||||
B gid2str(i32 n) {
|
||||
B r = IGetU(globalNameList, n);
|
||||
// print_fmt("gid2str %i → %R", n, r);
|
||||
// print_fmt("gid2str %i → %R\n", n, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "../core.h"
|
||||
#include "../utils/mut.h"
|
||||
#include "../builtins.h"
|
||||
#include "../ns.h"
|
||||
|
||||
B itype_c1(B t, B x) {
|
||||
B r;
|
||||
@ -271,12 +272,10 @@ B getInternalNS() {
|
||||
listVariations_def = m_str8l("if");
|
||||
gc_addFn(variation_gcRoot);
|
||||
#define F(X) inc(bi_##X),
|
||||
B fn = bqn_exec(m_str32(U"{⟨ Type, ElType, Refc, Squeeze, IsPure, Info, ListVariations, Variation, ClearRefs, Unshare, DeepSqueeze⟩⇐𝕩}"), emptyCVec(), emptySVec());
|
||||
B arg = m_caB(11,(B[]){F(itype)F(elType)F(refc)F(squeeze)F(isPure)F(info)F(listVariations)F(variation)F(clearRefs)F(unshare)F(deepSqueeze)});
|
||||
Body* d = m_nnsDesc("type","eltype","refc","squeeze","ispure","info","listvariations","variation","clearrefs","unshare","deepsqueeze");
|
||||
internalNS = m_nns(d,F(itype)F(elType)F(refc)F(squeeze)F(isPure)F(info)F(listVariations)F(variation)F(clearRefs)F(unshare)F(deepSqueeze));
|
||||
#undef F
|
||||
internalNS = c1(fn,arg);
|
||||
gc_add(internalNS);
|
||||
dec(fn);
|
||||
}
|
||||
return inc(internalNS);
|
||||
}
|
||||
|
||||
@ -297,15 +297,14 @@ B hash_c1(B t, B x) {
|
||||
|
||||
|
||||
|
||||
static B rand_ns;
|
||||
static i32 rand_a, rand_b;
|
||||
static Body* rand_ns;
|
||||
static B rand_rangeName; static NFnDesc* rand_rangeDesc;
|
||||
static B rand_dealName; static NFnDesc* rand_dealDesc;
|
||||
static B rand_subsetName; static NFnDesc* rand_subsetDesc;
|
||||
#define RAND_START Scope* sc = c(NS,nfn_objU(t))->sc; \
|
||||
u64 seed = sc->vars[rand_a].u | sc->vars[rand_b].u<<32;
|
||||
#define RAND_END sc->vars[rand_a].u = seed>>32; \
|
||||
sc->vars[rand_a].u = seed&0xFFFFFFFF;
|
||||
u64 seed = sc->vars[0].u | sc->vars[1].u<<32;
|
||||
#define RAND_END sc->vars[0].u = seed>>32; \
|
||||
sc->vars[1].u = seed&0xFFFFFFFF;
|
||||
B rand_range_c1(B t, B x) {
|
||||
i64 xv = o2i64(x);
|
||||
if (xv<0) thrM("(rand).Range: 𝕩 cannot be negative");
|
||||
@ -493,22 +492,19 @@ B rand_subset_c2(B t, B w, B x) {
|
||||
}
|
||||
|
||||
static NOINLINE void rand_init() {
|
||||
rand_ns = bqn_exec(m_str32(U"{a←𝕨⋄b←𝕩⋄range⇐0⋄deal⇐0⋄subset⇐0}"), emptyCVec(), emptySVec()); gc_add(rand_ns);
|
||||
rand_ns = m_nnsDesc("seed1", "seed2", "range", "deal", "subset");
|
||||
NSDesc* d = rand_ns->nsDesc;
|
||||
d->expGIDs[0] = d->expGIDs[1] = -1;
|
||||
rand_rangeName = m_str8l("range"); gc_add(rand_rangeName); rand_rangeDesc = registerNFn(m_str8l("(rand).Range"), rand_range_c1, rand_range_c2);
|
||||
rand_dealName = m_str8l("deal"); gc_add(rand_dealName); rand_dealDesc = registerNFn(m_str8l("(rand).Deal"), rand_deal_c1, rand_deal_c2);
|
||||
rand_subsetName = m_str8l("subset"); gc_add(rand_subsetName); rand_subsetDesc = registerNFn(m_str8l("(rand).Subset"), c1_bad, rand_subset_c2);
|
||||
B tmp = c2(rand_ns, m_f64(0), m_f64(0));
|
||||
rand_a = ns_pos(tmp, m_str8l("a"));
|
||||
rand_b = ns_pos(tmp, m_str8l("b"));
|
||||
dec(tmp);
|
||||
}
|
||||
B makeRand_c1(B t, B x) {
|
||||
if (!isNum(x)) thrM("•MakeRand: 𝕩 must be a number");
|
||||
if (rand_ns.u==0) rand_init();
|
||||
B r = c2(rand_ns, b(x.u>>32), b(x.u&0xFFFFFFFF));
|
||||
ns_set(r, rand_rangeName, m_nfn(rand_rangeDesc, incG(r)));
|
||||
ns_set(r, rand_dealName, m_nfn(rand_dealDesc, incG(r)));
|
||||
ns_set(r, rand_subsetName, m_nfn(rand_subsetDesc, incG(r)));
|
||||
if (rand_ns==NULL) rand_init();
|
||||
B r = m_nns(rand_ns, b(x.u>>32), b(x.u&0xFFFFFFFF), m_nfn(rand_rangeDesc, bi_N), m_nfn(rand_dealDesc, bi_N), m_nfn(rand_subsetDesc, bi_N));
|
||||
Scope* sc = c(NS,r)->sc;
|
||||
for (i32 i = 2; i < 5; i++) nfn_swapObj(sc->vars[i], inc(r));
|
||||
return r;
|
||||
}
|
||||
static B randNS;
|
||||
@ -812,7 +808,7 @@ B sh_c2(B t, B w, B x) {
|
||||
B getInternalNS(void);
|
||||
B getMathNS(void);
|
||||
|
||||
static B file_nsGen;
|
||||
static Body* file_nsGen;
|
||||
B sys_c1(B t, B x) {
|
||||
assert(isArr(x));
|
||||
usz i = 0;
|
||||
@ -834,9 +830,8 @@ B sys_c1(B t, B x) {
|
||||
if(!fileNS.u) {
|
||||
REQ_PATH;
|
||||
#define F(X) m_nfn(X##Desc, inc(path))
|
||||
B arg = m_caB(6, (B[]){q_N(path)? m_c32(0) : inc(path), F(fileAt), F(list), F(fBytes), F(fChars), F(fLines)});
|
||||
fileNS = m_nns(file_nsGen, q_N(path)? m_c32(0) : inc(path), F(fileAt), F(list), F(fBytes), F(fChars), F(fLines));
|
||||
#undef F
|
||||
fileNS = c1(file_nsGen,arg);
|
||||
}
|
||||
r.a[i] = inc(fileNS);
|
||||
}
|
||||
@ -899,5 +894,5 @@ void sysfn_init() {
|
||||
reBQNDesc = registerNFn(m_str8l("(REPL)"), repl_c1, repl_c2);
|
||||
}
|
||||
void sysfnPost_init() {
|
||||
file_nsGen = bqn_exec(m_str32(U"{⟨path,At,List,Bytes,Chars,Lines⟩⇐𝕩}"), emptyCVec(), emptySVec()); gc_add(file_nsGen);
|
||||
file_nsGen = m_nnsDesc("path","at","list","bytes","chars","lines");
|
||||
}
|
||||
|
||||
@ -21,3 +21,8 @@ static i32 nfn_data(B t) {
|
||||
assert(isVal(t) && v(t)->type == t_nfn);
|
||||
return c(NFn,t)->data;
|
||||
}
|
||||
static B nfn_swapObj(B t, B n) { // consumes n, returns old value
|
||||
B p = c(NFn,t)->obj;
|
||||
c(NFn,t)->obj = n;
|
||||
return p;
|
||||
}
|
||||
78
src/ns.c
78
src/ns.c
@ -1,5 +1,6 @@
|
||||
#include "core.h"
|
||||
#include "ns.h"
|
||||
#include "vm.h"
|
||||
#include "utils/mut.h"
|
||||
|
||||
void m_nsDesc(Body* body, bool imm, u8 ty, i32 actualVam, B nameList, B varIDs, B exported) { // doesn't consume nameList
|
||||
@ -37,15 +38,6 @@ B m_ns(Scope* sc, NSDesc* desc) { // consumes both
|
||||
}
|
||||
|
||||
|
||||
i32 pos2gid(Body* body, i32 pos) {
|
||||
i32 gid = body->varData[pos];
|
||||
if (LIKELY(gid!=-1)) return gid;
|
||||
|
||||
i32 nlIdx = body->varData[pos+body->varAm];
|
||||
if (nlIdx==-1) thrM("Cannot use special variable name as namespace key");
|
||||
return body->varData[pos] = str2gid(IGetU(body->bl->comp->nameList, nlIdx));
|
||||
}
|
||||
|
||||
|
||||
B ns_getU(B ns, i32 gid) { VTY(ns, t_ns);
|
||||
NS* n = c(NS, ns);
|
||||
@ -93,21 +85,81 @@ void ns_set(B ns, B name, B val) { VTY(ns, t_ns);
|
||||
thrM("No key found");
|
||||
}
|
||||
|
||||
i32 ns_pos(B ns, B name) { VTY(ns, t_ns);
|
||||
NS* n = c(NS, ns);
|
||||
Body* body = n->sc->body;
|
||||
|
||||
|
||||
|
||||
static i32* emptyi32ptr;
|
||||
static B emptyi32obj;
|
||||
Body* m_nnsDescF(i32 n, char** names) {
|
||||
if (emptyi32ptr==NULL) gc_add(emptyi32obj = m_i32arrv(&emptyi32ptr, 0));
|
||||
incBy(emptyi32obj, 3);
|
||||
|
||||
usz i = 0;
|
||||
HArr_p nl = m_harrs(n, &i);
|
||||
for (; i < n; i++) nl.a[i] = m_str8l(names[i]);
|
||||
|
||||
Comp* comp = mm_alloc(sizeof(Comp), t_comp);
|
||||
comp->bc = emptyi32obj;
|
||||
comp->indices = bi_N;
|
||||
comp->src = bi_N;
|
||||
comp->path = bi_N;
|
||||
comp->objs = c(HArr, emptyHVec());
|
||||
comp->blockAm = 0;
|
||||
comp->nameList = harr_fv(nl);
|
||||
|
||||
Block* bl = mm_alloc(fsizeof(Block,bodies,Body*,0), t_block);
|
||||
bl->ty = 0; bl->imm = true;
|
||||
bl->comp = comp;
|
||||
bl->bc = bl->map = emptyi32ptr;
|
||||
bl->blocks = NULL;
|
||||
bl->bodyCount = 0;
|
||||
gc_add(tag(bl, OBJ_TAG));
|
||||
|
||||
NSDesc* nd = mm_alloc(fsizeof(NSDesc, expGIDs, i32, n<2?2:n), t_nsDesc);
|
||||
nd->varAm = n;
|
||||
for (i = 0; i < n; i++) nd->expGIDs[i] = str2gid(nl.a[i]);
|
||||
|
||||
Body* body = m_body(n, 0, 0, 0);
|
||||
body->nsDesc = nd;
|
||||
body->bc = (u32*) emptyi32ptr;
|
||||
body->bl = bl;
|
||||
for (i = 0; i < n; i++) {
|
||||
body->varData[i] = nd->expGIDs[i];
|
||||
body->varData[i+n] = i;
|
||||
}
|
||||
gc_add(tag(body, OBJ_TAG));
|
||||
|
||||
bl->dyBody = bl->invMBody = bl->invXBody = bl->invWBody = body;
|
||||
return body;
|
||||
}
|
||||
|
||||
B m_nnsF(Body* desc, i32 n, B* vals) {
|
||||
assert(n == desc->varAm);
|
||||
Scope* sc = m_scope(desc, NULL, n, n, vals);
|
||||
return m_ns(sc, ptr_inc(desc->nsDesc));
|
||||
}
|
||||
|
||||
i32 nns_pos(Body* body, B name) {
|
||||
B nameList = body->bl->comp->nameList; SGetU(nameList);
|
||||
|
||||
i32 ia = body->varAm;
|
||||
for (i32 i = 0; i < ia; i++) {
|
||||
i32 pos = body->varData[i+ia];
|
||||
if (pos>=0 && equal(name, GetU(nameList, pos))) return i;
|
||||
if (pos>=0 && equal(name, GetU(nameList, pos))) { dec(name); return i; }
|
||||
}
|
||||
thrM("No key found");
|
||||
}
|
||||
|
||||
|
||||
|
||||
i32 pos2gid(Body* body, i32 pos) {
|
||||
i32 gid = body->varData[pos];
|
||||
if (LIKELY(gid!=-1)) return gid;
|
||||
|
||||
i32 nlIdx = body->varData[pos+body->varAm];
|
||||
if (nlIdx==-1) thrM("Cannot use special variable name as namespace key");
|
||||
return body->varData[pos] = str2gid(IGetU(body->bl->comp->nameList, nlIdx));
|
||||
}
|
||||
|
||||
DEF_FREE(ns) {
|
||||
NS* c = (NS*)x;
|
||||
|
||||
9
src/ns.h
9
src/ns.h
@ -19,8 +19,15 @@ B ns_getU(B ns, i32 gid); // doesn't consume, doesn't increment result
|
||||
B ns_qgetU(B ns, i32 gid); // ns_getU but return bi_N on fail
|
||||
B ns_getNU(B ns, B name, bool thrEmpty); // doesn't consume anything, doesn't increment result; returns bi_N if doesn't exist and !thrEmpty
|
||||
void ns_set(B ns, B name, B val); // consumes val
|
||||
i32 ns_pos(B ns, B name); // consumes name; returns an index in sc->vars for any variable, exported or local
|
||||
|
||||
i32 pos2gid(Body* body, i32 pos); // converts a variable position to a gid; errors on special name variables
|
||||
i32 str2gid(B s); // doesn't consume
|
||||
B gid2str(i32 n); // returns unowned object
|
||||
|
||||
|
||||
#define m_nnsDesc(...) ({ char* names_[] = {__VA_ARGS__}; m_nnsDescF(sizeof(names_)/sizeof(char*), names_); })
|
||||
#define m_nns(desc, ...) ({ B vals_[] = {__VA_ARGS__}; m_nnsF(desc, sizeof(vals_)/sizeof(char*), vals_); })
|
||||
|
||||
Body* m_nnsDescF(i32 n, char** names); // adds the result as a permanent GC root
|
||||
B m_nnsF(Body* desc, i32 n, B* vals);
|
||||
i32 nns_pos(Body* desc, B name); // consumes name; returns an index in sc->vars for a given variable (exported or local)
|
||||
|
||||
2
src/vm.c
2
src/vm.c
@ -85,7 +85,7 @@ void print_gStack() {
|
||||
}
|
||||
}
|
||||
|
||||
static Body* m_body(i32 vam, i32 pos, u32 maxStack, u16 maxPSC) { // leaves varIDs and nsDesc uninitialized
|
||||
Body* m_body(i32 vam, i32 pos, u32 maxStack, u16 maxPSC) { // leaves varIDs and nsDesc uninitialized
|
||||
Body* body = mm_alloc(fsizeof(Body, varData, i32, vam*2), t_body);
|
||||
|
||||
#if JIT_START != -1
|
||||
|
||||
1
src/vm.h
1
src/vm.h
@ -144,6 +144,7 @@ Block* bqn_comp(B str, B path, B args);
|
||||
Block* bqn_compSc(B str, B path, B args, Scope* sc, bool repl);
|
||||
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);
|
||||
Body* m_body(i32 vam, i32 pos, u32 maxStack, u16 maxPSC); // leaves varIDs and nsDesc uninitialized
|
||||
|
||||
typedef struct Nvm_res { u8* p; B refs; } Nvm_res;
|
||||
Nvm_res m_nvm(Body* b);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user