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,
|
||||
|
||||
/*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
|
||||
/*28*/ t_funPerf, t_md1Perf, t_md2Perf,
|
||||
/*29*/ t_funPerf, t_md1Perf, t_md2Perf,
|
||||
#endif
|
||||
t_COUNT
|
||||
};
|
||||
@ -346,6 +347,7 @@ i32 o2cu (B x) { return (u32)x.u; }
|
||||
usz o2su (B x) { return (usz)x.f; }
|
||||
f64 o2fu (B x) { return 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_f64(B x) { return isF64(x) || isI32(x); }
|
||||
|
||||
|
||||
24
src/main.c
24
src/main.c
@ -50,6 +50,7 @@
|
||||
#include "md1.c"
|
||||
#include "md2.c"
|
||||
#include "vm.c"
|
||||
#include "ns.c"
|
||||
#include "rtPerf.c"
|
||||
|
||||
void pr(char* a, B b) {
|
||||
@ -60,12 +61,15 @@ void pr(char* a, B b) {
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
Block* ca3(B x) {
|
||||
B* xp = harr_ptr(x);
|
||||
Block* r = compile(inc(xp[0]),inc(xp[1]),inc(xp[2]));
|
||||
Block* compB(B x) {
|
||||
BS2B xget = TI(x).get;
|
||||
Block* r = compile(xget(x,0),xget(x,1),xget(x,2),xget(x,3),xget(x,4));
|
||||
dec(x);
|
||||
return r;
|
||||
}
|
||||
Block* compile3(B bc, B objs, B blocks) {
|
||||
return compile(bc, objs, blocks, bi_N, bi_N);
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
@ -99,14 +103,14 @@ int main() {
|
||||
#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};
|
||||
#else
|
||||
Block* runtime0_b = compile(
|
||||
Block* runtime0_b = compile3(
|
||||
#include "runtime0"
|
||||
);
|
||||
B r0r = m_funBlock(runtime0_b, 0); ptr_dec(runtime0_b);
|
||||
B* runtime_0 = toHArr(r0r)->a;
|
||||
#endif
|
||||
|
||||
Block* runtime_b = compile(
|
||||
Block* runtime_b = compile3(
|
||||
#include "runtime1"
|
||||
);
|
||||
|
||||
@ -153,14 +157,14 @@ int main() {
|
||||
|
||||
|
||||
// uncomment to use src/interp; needed for test.bqn
|
||||
// Block* c = ca3(
|
||||
// Block* c = compB(
|
||||
// #include "interp"
|
||||
// );
|
||||
// B interp = m_funBlock(c, 0); ptr_dec(c);
|
||||
// pr("result: ", interp);
|
||||
// exit(0);
|
||||
|
||||
Block* comp_b = compile(
|
||||
Block* comp_b = compile3(
|
||||
#include "compiler"
|
||||
);
|
||||
B comp = m_funBlock(comp_b, 0); ptr_dec(comp_b);
|
||||
@ -168,7 +172,7 @@ int main() {
|
||||
|
||||
|
||||
#ifdef FORMATTER
|
||||
Block* fmt_b = compile(
|
||||
Block* fmt_b = compile3(
|
||||
#include "formatter"
|
||||
);
|
||||
B fmtM = m_funBlock(fmt_b, 0); ptr_dec(fmt_b);
|
||||
@ -195,7 +199,7 @@ int main() {
|
||||
// }
|
||||
// if (c_src) {
|
||||
// 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);
|
||||
// gc_add(comp);
|
||||
// free(c_src);
|
||||
@ -215,7 +219,7 @@ int main() {
|
||||
if (ln[0]==0 || ln[0]==10) break;
|
||||
B cbc = c2(comp, inc(compArg), fromUTF8(ln, strlen(ln)));
|
||||
free(ln);
|
||||
Block* cbc_b = ca3(cbc);
|
||||
Block* cbc_b = compB(cbc);
|
||||
|
||||
#ifdef TIME
|
||||
u64 sns = nsTime();
|
||||
|
||||
@ -78,7 +78,7 @@ B repeat_replace(B g, B* q) { // doesn't consume
|
||||
if (min) { \
|
||||
B x2 = inc(x); \
|
||||
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(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
|
||||
}
|
||||
|
||||
#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();
|
||||
FOR_INIT(F)
|
||||
#undef F
|
||||
|
||||
103
src/vm.c
103
src/vm.c
@ -1,4 +1,5 @@
|
||||
#include "h.h"
|
||||
#include "ns.h"
|
||||
|
||||
// #define GS_REALLOC // whether to dynamically realloc gStack
|
||||
#ifndef GS_SIZE
|
||||
@ -114,14 +115,15 @@ typedef struct Comp {
|
||||
Block* blocks[];
|
||||
} Comp;
|
||||
|
||||
typedef struct Block {
|
||||
struct Block {
|
||||
struct Value;
|
||||
bool imm;
|
||||
u8 ty;
|
||||
Body* body;
|
||||
} Block;
|
||||
};
|
||||
|
||||
typedef struct Body {
|
||||
typedef struct NSDesc NSDesc;
|
||||
struct Body {
|
||||
struct Value;
|
||||
Comp* comp;
|
||||
// B* objs;
|
||||
@ -129,25 +131,29 @@ typedef struct Body {
|
||||
u32 maxStack;
|
||||
u16 maxPSC;
|
||||
u16 varAm;
|
||||
u32 endStack;
|
||||
NSDesc* nsDesc;
|
||||
i32 varIDs[];
|
||||
// HArr* vNames;
|
||||
} Body;
|
||||
};
|
||||
|
||||
typedef struct Scope {
|
||||
struct Scope {
|
||||
struct Value;
|
||||
Scope* psc;
|
||||
Body* body;
|
||||
u16 varAm;
|
||||
#ifdef DEBUG
|
||||
u64 bcInd; // DEBUG: place of this in bytecode array
|
||||
#endif
|
||||
B vars[];
|
||||
} Scope;
|
||||
};
|
||||
|
||||
typedef struct FunBlock { struct Fun; Scope* sc; Block* bl; } FunBlock;
|
||||
typedef struct Md1Block { struct Md1; Scope* sc; Block* bl; } Md1Block;
|
||||
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);
|
||||
usz bam = blocksH->ia;
|
||||
|
||||
@ -162,22 +168,31 @@ Block* compile(B bcq, B objs, B blocksq) { // consumes all
|
||||
comp->objs = toHArr(objs);
|
||||
comp->blockAm = bam;
|
||||
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++) {
|
||||
B cbld = blockDefs[i];
|
||||
usz cbia = a(cbld)->ia;
|
||||
if (cbia!=4 && cbia!=6) thrM("bad compile block");
|
||||
BS2B bget = TI(cbld).get;
|
||||
usz ty = o2s(bget(cbld,0)); if (ty>2) thrM("bad block type");
|
||||
bool imm = o2s(bget(cbld,1)); // todo o2b or something
|
||||
usz idx = o2s(bget(cbld,2)); if (idx>=bcl) thrM("oob bytecode index");
|
||||
usz vam = o2s(bget(cbld,3)); if (vam!=(u16)vam) thrM("too many variables");
|
||||
BS2B bgetU = TI(cbld).getU;
|
||||
usz ty = o2s(bgetU(cbld,0)); if (ty>2) thrM("bad block type");
|
||||
bool imm = o2s(bgetU(cbld,1)); // todo o2b or something
|
||||
usz idx = o2s(bgetU(cbld,2)); if (idx>=bcl) thrM("oob bytecode index");
|
||||
usz vam = o2s(bgetU(cbld,3)); if (vam!=(u16)vam) thrM("too many variables");
|
||||
i32* cbc = bc+idx;
|
||||
|
||||
i32* scan = cbc;
|
||||
i32 ssz = 0, mssz=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);
|
||||
if (ssz>mssz) mssz = ssz;
|
||||
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");
|
||||
|
||||
Body* body = mm_allocN(sizeof(Body), t_body);
|
||||
Body* body = mm_allocN(fsizeof(Body,varIDs,i32,vam), t_body);
|
||||
body->comp = comp;
|
||||
body->bc = cbc;
|
||||
body->maxStack = mssz;
|
||||
body->maxPSC = (u16)mpsc;
|
||||
body->endStack = ssz;
|
||||
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);
|
||||
|
||||
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]);
|
||||
ptr_dec(comp);
|
||||
ptr_dec(blocksH);
|
||||
dec(tokenInfo);
|
||||
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");
|
||||
dec(prev);
|
||||
} 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);
|
||||
} else {
|
||||
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);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
case LOCU: { i32 d = *bc++; i32 p = *bc++;
|
||||
@ -427,14 +462,21 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
|
||||
ADD(r);
|
||||
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:
|
||||
#ifdef DEBUG
|
||||
printf("todo %d\n", bc[-1]); bc++; break;
|
||||
#else
|
||||
UD;
|
||||
#endif
|
||||
case RETN: goto end;
|
||||
}
|
||||
#ifdef DEBUG_VM
|
||||
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
|
||||
Body* bdy = bl->body;
|
||||
Scope* sc = mm_allocN(fsizeof(Scope, vars, B, bdy->varAm), t_scope);
|
||||
Body* body = bl->body;
|
||||
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);
|
||||
u16 varAm = sc->varAm = bdy->varAm;
|
||||
u16 varAm = sc->varAm = body->varAm;
|
||||
assert(varAm>=ga);
|
||||
#ifdef DEBUG
|
||||
sc->bcInd = bdy->bc-c(I32Arr,bdy->comp->bc)->a;
|
||||
sc->bcInd = body->bc-c(I32Arr,body->comp->bc)->a;
|
||||
#endif
|
||||
i32 i = 0;
|
||||
while (i<ga) { sc->vars[i] = svar[i]; i++; }
|
||||
while (i<varAm) sc->vars[i++] = bi_noVar;
|
||||
B r = evalBC(bdy, sc);
|
||||
B r = evalBC(body, sc);
|
||||
ptr_dec(sc);
|
||||
return r;
|
||||
}
|
||||
@ -505,7 +548,7 @@ B m_md2Block(Block* bl, Scope* psc) {
|
||||
}
|
||||
|
||||
void comp_free(B x) {
|
||||
Comp* c = c(Comp ,x);
|
||||
Comp* c = c(Comp, x);
|
||||
ptr_decR(c->objs);
|
||||
decR(c->bc);
|
||||
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) {
|
||||
Scope* c = c(Scope,x);
|
||||
if (c->psc) ptr_decR(c->psc);
|
||||
ptr_decR(c->body);
|
||||
u16 am = c->varAm;
|
||||
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 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); }
|
||||
@ -530,10 +574,11 @@ void comp_visit(B x) {
|
||||
void scope_visit(B x) {
|
||||
Scope* c = c(Scope,x);
|
||||
if (c->psc) mm_visitP(c->psc);
|
||||
mm_visitP(c->body);
|
||||
u16 am = c->varAm;
|
||||
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 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); }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user