native namespace creation

This commit is contained in:
dzaima 2021-11-29 16:44:20 +02:00
parent ef5864afbc
commit 4f66b6b88a
9 changed files with 101 additions and 43 deletions

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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");
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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);