namespaces
This commit is contained in:
parent
8ed4019edf
commit
0dede67d2a
6
src/h.h
6
src/h.h
@ -69,9 +69,10 @@ enum Type {
|
|||||||
/*18*/ t_hslice, t_i32slice, t_fillslice, t_c32slice, t_f64slice,
|
/*18*/ t_hslice, t_i32slice, t_fillslice, t_c32slice, t_f64slice,
|
||||||
|
|
||||||
/*22*/ t_comp, t_block, t_body, t_scope,
|
/*22*/ t_comp, t_block, t_body, t_scope,
|
||||||
/*26*/ t_freed, t_harrPartial,
|
/*26*/ t_ns, t_nsDesc,
|
||||||
|
/*27*/ t_freed, t_harrPartial,
|
||||||
#ifdef RT_PERF
|
#ifdef RT_PERF
|
||||||
/*28*/ t_funPerf, t_md1Perf, t_md2Perf,
|
/*29*/ t_funPerf, t_md1Perf, t_md2Perf,
|
||||||
#endif
|
#endif
|
||||||
t_COUNT
|
t_COUNT
|
||||||
};
|
};
|
||||||
@ -346,6 +347,7 @@ i32 o2cu (B x) { return (u32)x.u; }
|
|||||||
usz o2su (B x) { return (usz)x.f; }
|
usz o2su (B x) { return (usz)x.f; }
|
||||||
f64 o2fu (B x) { return x.f; }
|
f64 o2fu (B x) { return x.f; }
|
||||||
i64 o2i64u(B x) { return (i64)x.f; }
|
i64 o2i64u(B x) { return (i64)x.f; }
|
||||||
|
bool o2b (B x) { usz t=o2s(x); if(t!=0&t!=1)thrM("Expected boolean"); return t; }
|
||||||
bool q_i32(B x) { return isI32(x) | (isF64(x) && x.f==(f64)(i32)x.f); }
|
bool q_i32(B x) { return isI32(x) | (isF64(x) && x.f==(f64)(i32)x.f); }
|
||||||
bool q_f64(B x) { return isF64(x) || isI32(x); }
|
bool q_f64(B x) { return isF64(x) || isI32(x); }
|
||||||
|
|
||||||
|
|||||||
24
src/main.c
24
src/main.c
@ -50,6 +50,7 @@
|
|||||||
#include "md1.c"
|
#include "md1.c"
|
||||||
#include "md2.c"
|
#include "md2.c"
|
||||||
#include "vm.c"
|
#include "vm.c"
|
||||||
|
#include "ns.c"
|
||||||
#include "rtPerf.c"
|
#include "rtPerf.c"
|
||||||
|
|
||||||
void pr(char* a, B b) {
|
void pr(char* a, B b) {
|
||||||
@ -60,12 +61,15 @@ void pr(char* a, B b) {
|
|||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
Block* ca3(B x) {
|
Block* compB(B x) {
|
||||||
B* xp = harr_ptr(x);
|
BS2B xget = TI(x).get;
|
||||||
Block* r = compile(inc(xp[0]),inc(xp[1]),inc(xp[2]));
|
Block* r = compile(xget(x,0),xget(x,1),xget(x,2),xget(x,3),xget(x,4));
|
||||||
dec(x);
|
dec(x);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
Block* compile3(B bc, B objs, B blocks) {
|
||||||
|
return compile(bc, objs, blocks, bi_N, bi_N);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
@ -99,14 +103,14 @@ int main() {
|
|||||||
#ifndef ALL_R0
|
#ifndef ALL_R0
|
||||||
B runtime_0[] = {bi_floor,bi_ceil,bi_stile,bi_lt,bi_gt,bi_ne,bi_ge,bi_rtack,bi_ltack,bi_join,bi_take,bi_drop,bi_select,bi_const,bi_swap,bi_each,bi_fold,bi_atop,bi_over,bi_before,bi_after,bi_cond,bi_repeat};
|
B runtime_0[] = {bi_floor,bi_ceil,bi_stile,bi_lt,bi_gt,bi_ne,bi_ge,bi_rtack,bi_ltack,bi_join,bi_take,bi_drop,bi_select,bi_const,bi_swap,bi_each,bi_fold,bi_atop,bi_over,bi_before,bi_after,bi_cond,bi_repeat};
|
||||||
#else
|
#else
|
||||||
Block* runtime0_b = compile(
|
Block* runtime0_b = compile3(
|
||||||
#include "runtime0"
|
#include "runtime0"
|
||||||
);
|
);
|
||||||
B r0r = m_funBlock(runtime0_b, 0); ptr_dec(runtime0_b);
|
B r0r = m_funBlock(runtime0_b, 0); ptr_dec(runtime0_b);
|
||||||
B* runtime_0 = toHArr(r0r)->a;
|
B* runtime_0 = toHArr(r0r)->a;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Block* runtime_b = compile(
|
Block* runtime_b = compile3(
|
||||||
#include "runtime1"
|
#include "runtime1"
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -153,14 +157,14 @@ int main() {
|
|||||||
|
|
||||||
|
|
||||||
// uncomment to use src/interp; needed for test.bqn
|
// uncomment to use src/interp; needed for test.bqn
|
||||||
// Block* c = ca3(
|
// Block* c = compB(
|
||||||
// #include "interp"
|
// #include "interp"
|
||||||
// );
|
// );
|
||||||
// B interp = m_funBlock(c, 0); ptr_dec(c);
|
// B interp = m_funBlock(c, 0); ptr_dec(c);
|
||||||
// pr("result: ", interp);
|
// pr("result: ", interp);
|
||||||
// exit(0);
|
// exit(0);
|
||||||
|
|
||||||
Block* comp_b = compile(
|
Block* comp_b = compile3(
|
||||||
#include "compiler"
|
#include "compiler"
|
||||||
);
|
);
|
||||||
B comp = m_funBlock(comp_b, 0); ptr_dec(comp_b);
|
B comp = m_funBlock(comp_b, 0); ptr_dec(comp_b);
|
||||||
@ -168,7 +172,7 @@ int main() {
|
|||||||
|
|
||||||
|
|
||||||
#ifdef FORMATTER
|
#ifdef FORMATTER
|
||||||
Block* fmt_b = compile(
|
Block* fmt_b = compile3(
|
||||||
#include "formatter"
|
#include "formatter"
|
||||||
);
|
);
|
||||||
B fmtM = m_funBlock(fmt_b, 0); ptr_dec(fmt_b);
|
B fmtM = m_funBlock(fmt_b, 0); ptr_dec(fmt_b);
|
||||||
@ -195,7 +199,7 @@ int main() {
|
|||||||
// }
|
// }
|
||||||
// if (c_src) {
|
// if (c_src) {
|
||||||
// B cbc = c2(comp, inc(compArg), fromUTF8(c_src, c_len));
|
// B cbc = c2(comp, inc(compArg), fromUTF8(c_src, c_len));
|
||||||
// Block* cbc_b = ca3(cbc);
|
// Block* cbc_b = compB(cbc);
|
||||||
// comp = m_funBlock(cbc_b, 0); ptr_dec(cbc_b);
|
// comp = m_funBlock(cbc_b, 0); ptr_dec(cbc_b);
|
||||||
// gc_add(comp);
|
// gc_add(comp);
|
||||||
// free(c_src);
|
// free(c_src);
|
||||||
@ -215,7 +219,7 @@ int main() {
|
|||||||
if (ln[0]==0 || ln[0]==10) break;
|
if (ln[0]==0 || ln[0]==10) break;
|
||||||
B cbc = c2(comp, inc(compArg), fromUTF8(ln, strlen(ln)));
|
B cbc = c2(comp, inc(compArg), fromUTF8(ln, strlen(ln)));
|
||||||
free(ln);
|
free(ln);
|
||||||
Block* cbc_b = ca3(cbc);
|
Block* cbc_b = compB(cbc);
|
||||||
|
|
||||||
#ifdef TIME
|
#ifdef TIME
|
||||||
u64 sns = nsTime();
|
u64 sns = nsTime();
|
||||||
|
|||||||
@ -78,7 +78,7 @@ B repeat_replace(B g, B* q) { // doesn't consume
|
|||||||
if (min) { \
|
if (min) { \
|
||||||
B x2 = inc(x); \
|
B x2 = inc(x); \
|
||||||
B fi = m1_d(inc(rt_undo), inc(f)); \
|
B fi = m1_d(inc(rt_undo), inc(f)); \
|
||||||
for (u64 i = 0; i < min; i++) q[-1-i] = inc(x2 = CN(fi, __VA_ARGS__ x2)); \
|
for (i64 i = 0; i < min; i++) q[-1-i] = inc(x2 = CN(fi, __VA_ARGS__ x2)); \
|
||||||
dec(x2); \
|
dec(x2); \
|
||||||
dec(fi); \
|
dec(fi); \
|
||||||
} \
|
} \
|
||||||
|
|||||||
115
src/ns.c
Normal file
115
src/ns.c
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
#include "ns.h"
|
||||||
|
|
||||||
|
typedef struct NSDesc {
|
||||||
|
struct Value;
|
||||||
|
B nameList;
|
||||||
|
i32 varAm; // number of items in expIDs (currently equal to sc->varAm/body->varAm)
|
||||||
|
i32 expIDs[]; // each item is an index in nameList (or -1), and its position is the corresponding position in sc->vars
|
||||||
|
} NSDesc;
|
||||||
|
typedef struct NS {
|
||||||
|
struct Value;
|
||||||
|
B nameList; // copy of desc->nameList for quick checking; isn't owned
|
||||||
|
NSDesc* desc;
|
||||||
|
Scope* sc;
|
||||||
|
} NS;
|
||||||
|
|
||||||
|
void m_nsDesc(Body* body, bool imm, u8 ty, B nameList, B varIDs, B exported) { // consumes nameList
|
||||||
|
if (!isArr(varIDs) || !isArr(exported)) thrM("Bad namespace description information");
|
||||||
|
|
||||||
|
usz ia = a(varIDs)->ia;
|
||||||
|
if (ia!=a(exported)->ia) thrM("Bad namespace description information");
|
||||||
|
i32 off = (ty==0?0:ty==1?2:3) + (imm?0:3);
|
||||||
|
i32 vam = ia+off;
|
||||||
|
if (vam != body->varAm) thrM("Bad namespace description information");
|
||||||
|
|
||||||
|
NSDesc* rc = c(NSDesc, mm_alloc(fsizeof(NSDesc, expIDs, i32, vam), t_nsDesc, ftag(OBJ_TAG)));
|
||||||
|
rc->nameList = nameList;
|
||||||
|
rc->varAm = vam;
|
||||||
|
BS2B getIDU = TI(varIDs).getU;
|
||||||
|
BS2B getOnU = TI(exported).getU;
|
||||||
|
for (i32 i = 0; i < off; i++) {
|
||||||
|
body->varIDs[i] = -1;
|
||||||
|
rc ->expIDs[i] = -1;
|
||||||
|
}
|
||||||
|
for (usz i = 0; i < ia; i++) {
|
||||||
|
i32 cid = o2i(getIDU(varIDs, i));
|
||||||
|
bool cexp = o2b(getOnU(exported, i));
|
||||||
|
body->varIDs[i+off] = cid;
|
||||||
|
rc->expIDs[i+off] = cexp? cid : -1;
|
||||||
|
}
|
||||||
|
// printf("def %p:\n", rc);
|
||||||
|
// for (usz i = 0; i < vam; i++) printf(" %d: %d %d\n", i, body->varIDs[i], rc->expIDs[i]);
|
||||||
|
body->nsDesc = rc;
|
||||||
|
}
|
||||||
|
B m_ns(Scope* sc, NSDesc* desc) { // consumes both
|
||||||
|
B r = mm_alloc(sizeof(NS), t_ns, ftag(NSP_TAG));
|
||||||
|
NS* rc = c(NS,r);
|
||||||
|
rc->desc = desc;
|
||||||
|
rc->nameList = rc->desc->nameList;
|
||||||
|
rc->sc = sc;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
B ns_getU(B ns, B nameList, i32 nameID) {
|
||||||
|
NS* n = c(NS, ns);
|
||||||
|
NSDesc* d = n->desc;
|
||||||
|
if (n->nameList.u != nameList.u) thrM("TODO cross-program namespace access");
|
||||||
|
i32 varAm = d->varAm;
|
||||||
|
// printf("getting from %p with vam=%d\n", d, d->varAm);
|
||||||
|
assert(nameID<a(nameList)->ia && nameID>=0);
|
||||||
|
for (i32 i = 0; i < varAm; i++) {
|
||||||
|
if (d->expIDs[i]==nameID) return n->sc->vars[i];
|
||||||
|
}
|
||||||
|
thrM("No key found");
|
||||||
|
}
|
||||||
|
|
||||||
|
B ns_nameList(NSDesc* d) {
|
||||||
|
return d->nameList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void ns_free(B x) {
|
||||||
|
NS* c = c(NS, x);
|
||||||
|
ptr_decR(c->desc);
|
||||||
|
ptr_decR(c->sc);
|
||||||
|
}
|
||||||
|
void ns_visit(B x) {
|
||||||
|
NS* c = c(NS, x);
|
||||||
|
mm_visitP(c->desc);
|
||||||
|
mm_visitP(c->sc);
|
||||||
|
}
|
||||||
|
void ns_print(B x) {
|
||||||
|
putchar('{');
|
||||||
|
NSDesc* desc = c(NS,x)->desc;
|
||||||
|
Scope* sc = c(NS,x)->sc;
|
||||||
|
i32 am = desc->varAm;
|
||||||
|
BS2B getNameU = TI(desc->nameList).getU;
|
||||||
|
bool first = true;
|
||||||
|
for (i32 i = 0; i < am; i++) {
|
||||||
|
i32 id = desc->expIDs[i];
|
||||||
|
if (id>=0) {
|
||||||
|
if (first) first=false;
|
||||||
|
else printf(" ⋄ ");
|
||||||
|
printRaw(getNameU(desc->nameList, id));
|
||||||
|
printf("⇐");
|
||||||
|
print(sc->vars[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
putchar('}');
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsDesc_free(B x) {
|
||||||
|
decR(c(NSDesc,x)->nameList);
|
||||||
|
}
|
||||||
|
void nsDesc_visit(B x) {
|
||||||
|
mm_visit(c(NSDesc,x)->nameList);
|
||||||
|
}
|
||||||
|
void nsDesc_print(B x) {
|
||||||
|
printf("(namespace description)");
|
||||||
|
}
|
||||||
|
static inline void ns_init() {
|
||||||
|
ti[t_ns].free = ns_free; ti[t_nsDesc].free = nsDesc_free;
|
||||||
|
ti[t_ns].visit = ns_visit; ti[t_nsDesc].visit = nsDesc_visit;
|
||||||
|
ti[t_ns].print = ns_print; ti[t_nsDesc].print = nsDesc_print;
|
||||||
|
}
|
||||||
9
src/ns.h
Normal file
9
src/ns.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "h.h"
|
||||||
|
typedef struct Scope Scope;
|
||||||
|
typedef struct Body Body;
|
||||||
|
typedef struct NSDesc NSDesc;
|
||||||
|
void m_nsDesc(Body* body, bool imm, u8 ty, B nameList, B varIDs, B exported); // consumes nameList
|
||||||
|
B m_ns(Scope* sc, NSDesc* desc); // consumes both
|
||||||
|
B ns_getU(B ns, B nameList, i32 nameID); // doesn't consume anything, doesn't increment result
|
||||||
|
B ns_nameList(NSDesc* d);
|
||||||
@ -320,7 +320,7 @@ void printAllocStats() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FOR_INIT(F) F(hdr) F(harr) F(fillarr) F(i32arr) F(c32arr) F(f64arr) F(arith) F(fns) F(sfns) F(md1) F(md2) F(sysfn) F(derv) F(comp) F(rtPerf)
|
#define FOR_INIT(F) F(hdr) F(harr) F(fillarr) F(i32arr) F(c32arr) F(f64arr) F(arith) F(fns) F(sfns) F(md1) F(md2) F(sysfn) F(derv) F(comp) F(rtPerf) F(ns)
|
||||||
#define F(X) static inline void X##_init();
|
#define F(X) static inline void X##_init();
|
||||||
FOR_INIT(F)
|
FOR_INIT(F)
|
||||||
#undef F
|
#undef F
|
||||||
|
|||||||
103
src/vm.c
103
src/vm.c
@ -1,4 +1,5 @@
|
|||||||
#include "h.h"
|
#include "h.h"
|
||||||
|
#include "ns.h"
|
||||||
|
|
||||||
// #define GS_REALLOC // whether to dynamically realloc gStack
|
// #define GS_REALLOC // whether to dynamically realloc gStack
|
||||||
#ifndef GS_SIZE
|
#ifndef GS_SIZE
|
||||||
@ -114,14 +115,15 @@ typedef struct Comp {
|
|||||||
Block* blocks[];
|
Block* blocks[];
|
||||||
} Comp;
|
} Comp;
|
||||||
|
|
||||||
typedef struct Block {
|
struct Block {
|
||||||
struct Value;
|
struct Value;
|
||||||
bool imm;
|
bool imm;
|
||||||
u8 ty;
|
u8 ty;
|
||||||
Body* body;
|
Body* body;
|
||||||
} Block;
|
};
|
||||||
|
|
||||||
typedef struct Body {
|
typedef struct NSDesc NSDesc;
|
||||||
|
struct Body {
|
||||||
struct Value;
|
struct Value;
|
||||||
Comp* comp;
|
Comp* comp;
|
||||||
// B* objs;
|
// B* objs;
|
||||||
@ -129,25 +131,29 @@ typedef struct Body {
|
|||||||
u32 maxStack;
|
u32 maxStack;
|
||||||
u16 maxPSC;
|
u16 maxPSC;
|
||||||
u16 varAm;
|
u16 varAm;
|
||||||
|
u32 endStack;
|
||||||
|
NSDesc* nsDesc;
|
||||||
|
i32 varIDs[];
|
||||||
// HArr* vNames;
|
// HArr* vNames;
|
||||||
} Body;
|
};
|
||||||
|
|
||||||
typedef struct Scope {
|
struct Scope {
|
||||||
struct Value;
|
struct Value;
|
||||||
Scope* psc;
|
Scope* psc;
|
||||||
|
Body* body;
|
||||||
u16 varAm;
|
u16 varAm;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
u64 bcInd; // DEBUG: place of this in bytecode array
|
u64 bcInd; // DEBUG: place of this in bytecode array
|
||||||
#endif
|
#endif
|
||||||
B vars[];
|
B vars[];
|
||||||
} Scope;
|
};
|
||||||
|
|
||||||
typedef struct FunBlock { struct Fun; Scope* sc; Block* bl; } FunBlock;
|
typedef struct FunBlock { struct Fun; Scope* sc; Block* bl; } FunBlock;
|
||||||
typedef struct Md1Block { struct Md1; Scope* sc; Block* bl; } Md1Block;
|
typedef struct Md1Block { struct Md1; Scope* sc; Block* bl; } Md1Block;
|
||||||
typedef struct Md2Block { struct Md2; Scope* sc; Block* bl; } Md2Block;
|
typedef struct Md2Block { struct Md2; Scope* sc; Block* bl; } Md2Block;
|
||||||
|
|
||||||
|
|
||||||
Block* compile(B bcq, B objs, B blocksq) { // consumes all
|
Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo) { // consumes all
|
||||||
HArr* blocksH = toHArr(blocksq);
|
HArr* blocksH = toHArr(blocksq);
|
||||||
usz bam = blocksH->ia;
|
usz bam = blocksH->ia;
|
||||||
|
|
||||||
@ -162,22 +168,31 @@ Block* compile(B bcq, B objs, B blocksq) { // consumes all
|
|||||||
comp->objs = toHArr(objs);
|
comp->objs = toHArr(objs);
|
||||||
comp->blockAm = bam;
|
comp->blockAm = bam;
|
||||||
B* blockDefs = blocksH->a;
|
B* blockDefs = blocksH->a;
|
||||||
|
dec(indices);
|
||||||
|
B nameList;
|
||||||
|
if (isNothing(tokenInfo)) {
|
||||||
|
nameList = bi_emptyHVec;
|
||||||
|
} else {
|
||||||
|
B t = TI(tokenInfo).getU(tokenInfo,2);
|
||||||
|
nameList = TI(t).getU(t,0);
|
||||||
|
}
|
||||||
|
|
||||||
for (usz i = 0; i < bam; i++) {
|
for (usz i = 0; i < bam; i++) {
|
||||||
B cbld = blockDefs[i];
|
B cbld = blockDefs[i];
|
||||||
usz cbia = a(cbld)->ia;
|
usz cbia = a(cbld)->ia;
|
||||||
if (cbia!=4 && cbia!=6) thrM("bad compile block");
|
if (cbia!=4 && cbia!=6) thrM("bad compile block");
|
||||||
BS2B bget = TI(cbld).get;
|
BS2B bgetU = TI(cbld).getU;
|
||||||
usz ty = o2s(bget(cbld,0)); if (ty>2) thrM("bad block type");
|
usz ty = o2s(bgetU(cbld,0)); if (ty>2) thrM("bad block type");
|
||||||
bool imm = o2s(bget(cbld,1)); // todo o2b or something
|
bool imm = o2s(bgetU(cbld,1)); // todo o2b or something
|
||||||
usz idx = o2s(bget(cbld,2)); if (idx>=bcl) thrM("oob bytecode index");
|
usz idx = o2s(bgetU(cbld,2)); if (idx>=bcl) thrM("oob bytecode index");
|
||||||
usz vam = o2s(bget(cbld,3)); if (vam!=(u16)vam) thrM("too many variables");
|
usz vam = o2s(bgetU(cbld,3)); if (vam!=(u16)vam) thrM("too many variables");
|
||||||
i32* cbc = bc+idx;
|
i32* cbc = bc+idx;
|
||||||
|
|
||||||
i32* scan = cbc;
|
i32* scan = cbc;
|
||||||
i32 ssz = 0, mssz=0;
|
i32 ssz = 0, mssz=0;
|
||||||
i32 mpsc = 0;
|
i32 mpsc = 0;
|
||||||
while (*scan!=RETN & *scan!=RETD) {
|
while (true) {
|
||||||
|
if (*scan==RETN) { if(ssz!=1)thrM("Wrong stack size before RETN"); break; }
|
||||||
|
if (*scan==RETD) { if(ssz!=1&ssz!=0)thrM("Wrong stack size before RETN"); break; }
|
||||||
ssz+= stackDiff(scan);
|
ssz+= stackDiff(scan);
|
||||||
if (ssz>mssz) mssz = ssz;
|
if (ssz>mssz) mssz = ssz;
|
||||||
if (*scan==LOCO | *scan==LOCM | *scan==LOCU) {
|
if (*scan==LOCO | *scan==LOCM | *scan==LOCU) {
|
||||||
@ -188,12 +203,17 @@ Block* compile(B bcq, B objs, B blocksq) { // consumes all
|
|||||||
}
|
}
|
||||||
if (mpsc>U16_MAX) thrM("LOC_ too deep");
|
if (mpsc>U16_MAX) thrM("LOC_ too deep");
|
||||||
|
|
||||||
Body* body = mm_allocN(sizeof(Body), t_body);
|
Body* body = mm_allocN(fsizeof(Body,varIDs,i32,vam), t_body);
|
||||||
body->comp = comp;
|
body->comp = comp;
|
||||||
body->bc = cbc;
|
body->bc = cbc;
|
||||||
body->maxStack = mssz;
|
body->maxStack = mssz;
|
||||||
body->maxPSC = (u16)mpsc;
|
body->maxPSC = (u16)mpsc;
|
||||||
|
body->endStack = ssz;
|
||||||
body->varAm = (u16)vam;
|
body->varAm = (u16)vam;
|
||||||
|
if (cbia==4) {
|
||||||
|
body->nsDesc = NULL;
|
||||||
|
for (i32 i = 0; i < vam; i++) body->varIDs[i] = -1;
|
||||||
|
} else m_nsDesc(body, imm, ty, inc(nameList), bgetU(cbld,4), bgetU(cbld,5));
|
||||||
ptr_inc(comp);
|
ptr_inc(comp);
|
||||||
|
|
||||||
Block* bl = mm_allocN(sizeof(Block), t_block);
|
Block* bl = mm_allocN(sizeof(Block), t_block);
|
||||||
@ -208,6 +228,7 @@ Block* compile(B bcq, B objs, B blocksq) { // consumes all
|
|||||||
// for (usz i = 0; i < bam; i++) ptr_dec(comp->blocks[i]);
|
// for (usz i = 0; i < bam; i++) ptr_dec(comp->blocks[i]);
|
||||||
ptr_dec(comp);
|
ptr_dec(comp);
|
||||||
ptr_dec(blocksH);
|
ptr_dec(blocksH);
|
||||||
|
dec(tokenInfo);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,14 +240,26 @@ void v_set(Scope* pscs[], B s, B x, bool upd) { // doesn't consume
|
|||||||
if (prev.u==bi_noVar.u) thrM("↩: Updating undefined variable");
|
if (prev.u==bi_noVar.u) thrM("↩: Updating undefined variable");
|
||||||
dec(prev);
|
dec(prev);
|
||||||
} else {
|
} else {
|
||||||
if (prev.u!=bi_noVar.u) thrM("←: redefining variable");
|
if (prev.u!=bi_noVar.u) thrM("←: Redefining variable");
|
||||||
}
|
}
|
||||||
sc->vars[(u32)s.u] = inc(x);
|
sc->vars[(u32)s.u] = inc(x);
|
||||||
} else {
|
} else {
|
||||||
VT(s, t_harr);
|
VT(s, t_harr);
|
||||||
if (isAtm(x) || !eqShape(s, x)) thrM("Assignment: Mismatched shape for spread assignment");
|
|
||||||
usz ia = a(x)->ia;
|
|
||||||
B* sp = harr_ptr(s);
|
B* sp = harr_ptr(s);
|
||||||
|
usz ia = a(s)->ia;
|
||||||
|
if (isAtm(x) || !eqShape(s, x)) {
|
||||||
|
if (isNsp(x)) {
|
||||||
|
for (u64 i = 0; i < ia; i++) {
|
||||||
|
B c = sp[i];
|
||||||
|
if (!isVar(c)) thrM("Assignment: extracting non-name from namespace");
|
||||||
|
Scope* sc = pscs[(u16)(c.u>>32)];
|
||||||
|
i32 nameID = sc->body->varIDs[(u32)c.u];
|
||||||
|
v_set(pscs, c, ns_getU(x, ns_nameList(sc->body->nsDesc), nameID), upd);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
thrM("Assignment: Mismatched shape for spread assignment");
|
||||||
|
}
|
||||||
BS2B xgetU = TI(x).getU;
|
BS2B xgetU = TI(x).getU;
|
||||||
for (u64 i = 0; i < ia; i++) v_set(pscs, sp[i], xgetU(x,i), upd);
|
for (u64 i = 0; i < ia; i++) v_set(pscs, sp[i], xgetU(x,i), upd);
|
||||||
}
|
}
|
||||||
@ -409,7 +442,9 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LOCO: { i32 d = *bc++; i32 p = *bc++;
|
case LOCO: { i32 d = *bc++; i32 p = *bc++;
|
||||||
ADD(inc(pscs[d]->vars[p]));
|
B l = pscs[d]->vars[p];
|
||||||
|
if(l.u==bi_noVar.u) thrM("Reading variable before its defined");
|
||||||
|
ADD(inc(l));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LOCU: { i32 d = *bc++; i32 p = *bc++;
|
case LOCU: { i32 d = *bc++; i32 p = *bc++;
|
||||||
@ -427,14 +462,21 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
|
|||||||
ADD(r);
|
ADD(r);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// not implemented: VARO VARM CHKV VFYM SETH FLDO FLDM NSPM RETD SYSV
|
case RETD: {
|
||||||
|
if (b->endStack) dec(POP);
|
||||||
|
ptr_inc(sc);
|
||||||
|
ptr_inc(b->nsDesc);
|
||||||
|
ADD(m_ns(sc, b->nsDesc));
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
case RETN: goto end;
|
||||||
|
// not implemented: VARO VARM CHKV VFYM SETH FLDO FLDM NSPM SYSV
|
||||||
default:
|
default:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("todo %d\n", bc[-1]); bc++; break;
|
printf("todo %d\n", bc[-1]); bc++; break;
|
||||||
#else
|
#else
|
||||||
UD;
|
UD;
|
||||||
#endif
|
#endif
|
||||||
case RETN: goto end;
|
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_VM
|
#ifdef DEBUG_VM
|
||||||
for(i32 i = 0; i < bcDepth; i++) printf(" ");
|
for(i32 i = 0; i < bcDepth; i++) printf(" ");
|
||||||
@ -456,18 +498,19 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
|
|||||||
}
|
}
|
||||||
|
|
||||||
B actualExec(Block* bl, Scope* psc, i32 ga, B* svar) { // consumes svar contents
|
B actualExec(Block* bl, Scope* psc, i32 ga, B* svar) { // consumes svar contents
|
||||||
Body* bdy = bl->body;
|
Body* body = bl->body;
|
||||||
Scope* sc = mm_allocN(fsizeof(Scope, vars, B, bdy->varAm), t_scope);
|
Scope* sc = mm_allocN(fsizeof(Scope, vars, B, body->varAm), t_scope);
|
||||||
|
sc->body = body; ptr_inc(body);
|
||||||
sc->psc = psc; if(psc) ptr_inc(psc);
|
sc->psc = psc; if(psc) ptr_inc(psc);
|
||||||
u16 varAm = sc->varAm = bdy->varAm;
|
u16 varAm = sc->varAm = body->varAm;
|
||||||
assert(varAm>=ga);
|
assert(varAm>=ga);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
sc->bcInd = bdy->bc-c(I32Arr,bdy->comp->bc)->a;
|
sc->bcInd = body->bc-c(I32Arr,body->comp->bc)->a;
|
||||||
#endif
|
#endif
|
||||||
i32 i = 0;
|
i32 i = 0;
|
||||||
while (i<ga) { sc->vars[i] = svar[i]; i++; }
|
while (i<ga) { sc->vars[i] = svar[i]; i++; }
|
||||||
while (i<varAm) sc->vars[i++] = bi_noVar;
|
while (i<varAm) sc->vars[i++] = bi_noVar;
|
||||||
B r = evalBC(bdy, sc);
|
B r = evalBC(body, sc);
|
||||||
ptr_dec(sc);
|
ptr_dec(sc);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -505,7 +548,7 @@ B m_md2Block(Block* bl, Scope* psc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void comp_free(B x) {
|
void comp_free(B x) {
|
||||||
Comp* c = c(Comp ,x);
|
Comp* c = c(Comp, x);
|
||||||
ptr_decR(c->objs);
|
ptr_decR(c->objs);
|
||||||
decR(c->bc);
|
decR(c->bc);
|
||||||
u32 am = c->blockAm; for(u32 i = 0; i < am; i++) ptr_dec(c->blocks[i]);
|
u32 am = c->blockAm; for(u32 i = 0; i < am; i++) ptr_dec(c->blocks[i]);
|
||||||
@ -513,10 +556,11 @@ void comp_free(B x) {
|
|||||||
void scope_free(B x) {
|
void scope_free(B x) {
|
||||||
Scope* c = c(Scope,x);
|
Scope* c = c(Scope,x);
|
||||||
if (c->psc) ptr_decR(c->psc);
|
if (c->psc) ptr_decR(c->psc);
|
||||||
|
ptr_decR(c->body);
|
||||||
u16 am = c->varAm;
|
u16 am = c->varAm;
|
||||||
for (u32 i = 0; i < am; i++) dec(c->vars[i]);
|
for (u32 i = 0; i < am; i++) dec(c->vars[i]);
|
||||||
}
|
}
|
||||||
void body_free(B x) { Body* c = c(Body ,x); ptr_decR(c->comp); }
|
void body_free(B x) { Body* c = c(Body ,x); ptr_decR(c->comp); if(c->nsDesc)ptr_decR(c->nsDesc); }
|
||||||
void block_free(B x) { Block* c = c(Block,x); ptr_decR(c->body); }
|
void block_free(B x) { Block* c = c(Block,x); ptr_decR(c->body); }
|
||||||
void funBl_free(B x) { FunBlock* c = c(FunBlock,x); ptr_decR(c->sc); ptr_decR(c->bl); }
|
void funBl_free(B x) { FunBlock* c = c(FunBlock,x); ptr_decR(c->sc); ptr_decR(c->bl); }
|
||||||
void md1Bl_free(B x) { Md1Block* c = c(Md1Block,x); ptr_decR(c->sc); ptr_decR(c->bl); }
|
void md1Bl_free(B x) { Md1Block* c = c(Md1Block,x); ptr_decR(c->sc); ptr_decR(c->bl); }
|
||||||
@ -530,10 +574,11 @@ void comp_visit(B x) {
|
|||||||
void scope_visit(B x) {
|
void scope_visit(B x) {
|
||||||
Scope* c = c(Scope,x);
|
Scope* c = c(Scope,x);
|
||||||
if (c->psc) mm_visitP(c->psc);
|
if (c->psc) mm_visitP(c->psc);
|
||||||
|
mm_visitP(c->body);
|
||||||
u16 am = c->varAm;
|
u16 am = c->varAm;
|
||||||
for (u32 i = 0; i < am; i++) mm_visit(c->vars[i]);
|
for (u32 i = 0; i < am; i++) mm_visit(c->vars[i]);
|
||||||
}
|
}
|
||||||
void body_visit(B x) { Body* c = c(Body ,x); mm_visitP(c->comp); }
|
void body_visit(B x) { Body* c = c(Body ,x); mm_visitP(c->comp); if(c->nsDesc)mm_visitP(c->nsDesc); }
|
||||||
void block_visit(B x) { Block* c = c(Block,x); mm_visitP(c->body); }
|
void block_visit(B x) { Block* c = c(Block,x); mm_visitP(c->body); }
|
||||||
void funBl_visit(B x) { FunBlock* c = c(FunBlock,x); mm_visitP(c->sc); mm_visitP(c->bl); }
|
void funBl_visit(B x) { FunBlock* c = c(FunBlock,x); mm_visitP(c->sc); mm_visitP(c->bl); }
|
||||||
void md1Bl_visit(B x) { Md1Block* c = c(Md1Block,x); mm_visitP(c->sc); mm_visitP(c->bl); }
|
void md1Bl_visit(B x) { Md1Block* c = c(Md1Block,x); mm_visitP(c->sc); mm_visitP(c->bl); }
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user