store directly needed blocks in bodies
This commit is contained in:
parent
582273229b
commit
7bf3b4be50
@ -14,7 +14,7 @@ tests ← •FLines path∾"/test/cases/prim.bqn"
|
|||||||
'%'⊸∊◶{𝕤
|
'%'⊸∊◶{𝕤
|
||||||
•Out 𝕩
|
•Out 𝕩
|
||||||
"src/gen/interp" •FChars ⟨1,path,𝕩⟩ •Import "cc.bqn"
|
"src/gen/interp" •FChars ⟨1,path,𝕩⟩ •Import "cc.bqn"
|
||||||
(×⊑)◶@‿{𝕤⋄•Out "############ Failed to compile! ############" ⋄ •Out¨1↓𝕩}{env⇐<"PATH="∾envP}•SH"./debugBuild"‿"-DNO_COMP"
|
(×⊑)◶@‿{𝕤⋄•Out "############ Failed to compile! ############" ⋄ •Out¨1↓𝕩}{env⇐<"PATH="∾envP}•SH"./debugBuild"‿"-DPRECOMP"
|
||||||
code‿out‿err←•SH"./BQN"
|
code‿out‿err←•SH"./BQN"
|
||||||
•Out out
|
•Out out
|
||||||
{𝕤⋄•Out"exit code "∾(⍕code) ⋄ •Out err}⍟(×code) err
|
{𝕤⋄•Out"exit code "∾(⍕code) ⋄ •Out err}⍟(×code) err
|
||||||
|
|||||||
@ -337,7 +337,7 @@ char* format_type(u8 u) {
|
|||||||
case t_md1D:return"md1D"; case t_md2D:return"md2D"; case t_md2H:return"md2H";
|
case t_md1D:return"md1D"; case t_md2D:return"md2D"; case t_md2H:return"md2H";
|
||||||
case t_harr :return"harr" ; case t_i8arr :return"i8arr" ; case t_i32arr :return"i32arr" ; case t_fillarr :return"fillarr" ; case t_c32arr :return"c32arr" ; case t_f64arr :return"f64arr" ;
|
case t_harr :return"harr" ; case t_i8arr :return"i8arr" ; case t_i32arr :return"i32arr" ; case t_fillarr :return"fillarr" ; case t_c32arr :return"c32arr" ; case t_f64arr :return"f64arr" ;
|
||||||
case t_hslice:return"hslice"; case t_i8slice:return"i8slice"; case t_i32slice:return"i32slice"; case t_fillslice:return"fillslice"; case t_c32slice:return"c32slice"; case t_f64slice:return"f64slice";
|
case t_hslice:return"hslice"; case t_i8slice:return"i8slice"; case t_i32slice:return"i32slice"; case t_fillslice:return"fillslice"; case t_c32slice:return"c32slice"; case t_f64slice:return"f64slice";
|
||||||
case t_comp:return"comp"; case t_block:return"block"; case t_body:return"body"; case t_scope:return"scope";
|
case t_comp:return"comp"; case t_block:return"block"; case t_body:return"body"; case t_scope:return"scope"; case t_blBlocks: return "block list";
|
||||||
case t_ns:return"ns"; case t_nsDesc:return"nsDesc"; case t_fldAlias:return"alias"; case t_hashmap:return"hashmap"; case t_temp:return"temporary";
|
case t_ns:return"ns"; case t_nsDesc:return"nsDesc"; case t_fldAlias:return"alias"; case t_hashmap:return"hashmap"; case t_temp:return"temporary";
|
||||||
case t_freed:return"(freed by GC)"; case t_harrPartial:return"partHarr";
|
case t_freed:return"(freed by GC)"; case t_harrPartial:return"partHarr";
|
||||||
#ifdef RT_WRAP
|
#ifdef RT_WRAP
|
||||||
@ -457,7 +457,7 @@ B bqn_merge(B x) { // consumes
|
|||||||
NOINLINE void printAllocStats() {
|
NOINLINE void printAllocStats() {
|
||||||
#ifdef ALLOC_STAT
|
#ifdef ALLOC_STAT
|
||||||
printf("total ever allocated: %lu\n", talloc);
|
printf("total ever allocated: %lu\n", talloc);
|
||||||
printf("allocated heap size: %ld\n", mm_heapAllocated());
|
printf("allocated heap size: %ld\n", mm_heapAlloc);
|
||||||
printf("used heap size: %ld\n", mm_heapUsed());
|
printf("used heap size: %ld\n", mm_heapUsed());
|
||||||
ctr_a[t_harr]+= ctr_a[t_harrPartial];
|
ctr_a[t_harr]+= ctr_a[t_harrPartial];
|
||||||
ctr_a[t_harrPartial] = 0;
|
ctr_a[t_harrPartial] = 0;
|
||||||
|
|||||||
@ -8,7 +8,6 @@ static void mm_free(Value* x);
|
|||||||
static u64 mm_size(Value* x);
|
static u64 mm_size(Value* x);
|
||||||
static void mm_visit(B x);
|
static void mm_visit(B x);
|
||||||
static void mm_visitP(void* x);
|
static void mm_visitP(void* x);
|
||||||
static u64 mm_heapAllocated();
|
|
||||||
u64 mm_heapUsed();
|
u64 mm_heapUsed();
|
||||||
void printAllocStats();
|
void printAllocStats();
|
||||||
static B mm_alloc(usz sz, u8 type, u64 tag) {
|
static B mm_alloc(usz sz, u8 type, u64 tag) {
|
||||||
@ -31,7 +30,7 @@ typedef struct TAlloc {
|
|||||||
#define TFREE(N) mm_free((Value*)TOBJ(N));
|
#define TFREE(N) mm_free((Value*)TOBJ(N));
|
||||||
#define TREALLOC(N, AM) talloc_realloc(TOBJ(N), AM)
|
#define TREALLOC(N, AM) talloc_realloc(TOBJ(N), AM)
|
||||||
#define TSIZE(N) (mm_size(TOBJ(N))-TOFF)
|
#define TSIZE(N) (mm_size(TOBJ(N))-TOFF)
|
||||||
static inline void* talloc_realloc(TAlloc* t, u64 am) {
|
static inline void* talloc_realloc(TAlloc* t, u64 am) { // TODO maybe shouldn't be inline?
|
||||||
u64 stored = mm_size((Value*)t)-TOFF;
|
u64 stored = mm_size((Value*)t)-TOFF;
|
||||||
if (stored > am) return t->data;
|
if (stored > am) return t->data;
|
||||||
TALLOC(u8,r,am);
|
TALLOC(u8,r,am);
|
||||||
@ -40,6 +39,26 @@ static inline void* talloc_realloc(TAlloc* t, u64 am) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct TStack {
|
||||||
|
struct Value;
|
||||||
|
usz size;
|
||||||
|
usz cap;
|
||||||
|
u8 data[];
|
||||||
|
} TStack;
|
||||||
|
#define TSALLOC(T,N) u32 N##_e=sizeof(T); TStack* N##_o = (TStack*)mm_allocN(sizeof(TStack)+N##_e*2, t_temp); N##_o->size=0; N##_o->cap=2; T* N = (T*)N##_o->data;
|
||||||
|
#define TSFREE(N) mm_free((Value*)N##_o);
|
||||||
|
#define TSADD(N,X) { if (N##_o->size==N##_o->cap) { N##_o = tstack_ext(N##_o, N##_e); N = (void*)N##_o->data; } N[N##_o->size++] = X; }
|
||||||
|
#define TSSIZE(N) (N##_o->size)
|
||||||
|
static NOINLINE TStack* tstack_ext(TStack* o, u32 elsz) {
|
||||||
|
usz ncap = o->cap*2;
|
||||||
|
TStack* n = (TStack*)mm_allocN(sizeof(TStack) + elsz*ncap, t_temp);
|
||||||
|
memcpy(n->data, o->data, o->cap*elsz);
|
||||||
|
n->cap = ncap;
|
||||||
|
n->size = o->size;
|
||||||
|
mm_free((Value*)o);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
// shape mess
|
// shape mess
|
||||||
|
|
||||||
typedef struct ShArr {
|
typedef struct ShArr {
|
||||||
|
|||||||
11
src/h.h
11
src/h.h
@ -28,7 +28,8 @@
|
|||||||
// #define TIME // output runtime of every expression
|
// #define TIME // output runtime of every expression
|
||||||
// #define RT_PERF // time runtime primitives
|
// #define RT_PERF // time runtime primitives
|
||||||
// #define RT_VERIFY // compare native and runtime versions of primitives
|
// #define RT_VERIFY // compare native and runtime versions of primitives
|
||||||
// #define NO_COMP // don't load the compiler, instead execute src/interp; needed for ./precompiled.bqn
|
// #define NO_RT // whether to completely disable self-hosted runtime loading
|
||||||
|
// #define PRECOMP // execute just precompiled code at src/gen/interp
|
||||||
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@ -133,11 +134,11 @@ enum Type {
|
|||||||
/*13*/ t_harr , t_i8arr , t_i32arr , t_fillarr , t_c32arr , t_f64arr ,
|
/*13*/ t_harr , t_i8arr , t_i32arr , t_fillarr , t_c32arr , t_f64arr ,
|
||||||
/*19*/ t_hslice, t_i8slice, t_i32slice, t_fillslice, t_c32slice, t_f64slice,
|
/*19*/ t_hslice, t_i8slice, t_i32slice, t_fillslice, t_c32slice, t_f64slice,
|
||||||
|
|
||||||
/*25*/ t_comp, t_block, t_body, t_scope,
|
/*25*/ t_comp, t_block, t_body, t_scope, t_blBlocks,
|
||||||
/*29*/ t_ns, t_nsDesc, t_fldAlias, t_hashmap, t_temp,
|
/*30*/ t_ns, t_nsDesc, t_fldAlias, t_hashmap, t_temp,
|
||||||
/*34*/ t_freed, t_harrPartial,
|
/*35*/ t_freed, t_harrPartial,
|
||||||
#ifdef RT_WRAP
|
#ifdef RT_WRAP
|
||||||
/*36*/ t_funWrap, t_md1Wrap, t_md2Wrap,
|
/*37*/ t_funWrap, t_md1Wrap, t_md2Wrap,
|
||||||
#endif
|
#endif
|
||||||
t_COUNT
|
t_COUNT
|
||||||
};
|
};
|
||||||
|
|||||||
158
src/load.c
158
src/load.c
@ -30,19 +30,19 @@ Block* load_compObj(B x, B src) { // consumes
|
|||||||
BS2B xget = TI(x).get;
|
BS2B xget = TI(x).get;
|
||||||
usz xia = a(x)->ia;
|
usz xia = a(x)->ia;
|
||||||
if (xia!=5 & xia!=3) thrM("load_compObj: bad item count");
|
if (xia!=5 & xia!=3) thrM("load_compObj: bad item count");
|
||||||
Block* r = xia==5? compile(xget(x,0),xget(x,1),xget(x,2),xget(x,3),xget(x,4), src)
|
Block* r = xia==5? compile(xget(x,0),xget(x,1),xget(x,2),xget(x,3),xget(x,4), src, NULL)
|
||||||
: compile(xget(x,0),xget(x,1),xget(x,2),bi_N, bi_N, src);
|
: compile(xget(x,0),xget(x,1),xget(x,2),bi_N, bi_N, src, NULL);
|
||||||
dec(x);
|
dec(x);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
#include "gen/src"
|
#include "gen/src"
|
||||||
#if RT_SRC
|
#if RT_SRC
|
||||||
Block* load_compImport(B bc, B objs, B blocks, B inds, B src) { // consumes all
|
Block* load_compImport(B bc, B objs, B blocks, B inds, B src) { // consumes all
|
||||||
return compile(bc, objs, blocks, inds, bi_N, src);
|
return compile(bc, objs, blocks, inds, bi_N, src, NULL);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Block* load_compImport(B bc, B objs, B blocks) { // consumes all
|
Block* load_compImport(B bc, B objs, B blocks) { // consumes all
|
||||||
return compile(bc, objs, blocks, bi_N, bi_N, bi_N);
|
return compile(bc, objs, blocks, bi_N, bi_N, bi_N, NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -110,82 +110,86 @@ static inline void load_init() { // very last init function
|
|||||||
for (i32 i = 0; i < rtLen; i++) inc(fruntime[i]);
|
for (i32 i = 0; i < rtLen; i++) inc(fruntime[i]);
|
||||||
B frtObj = m_caB(rtLen, fruntime);
|
B frtObj = m_caB(rtLen, fruntime);
|
||||||
|
|
||||||
B provide[] = {bi_type,bi_fill,bi_log,bi_grLen,bi_grOrd,bi_asrt,bi_add,bi_sub,bi_mul,bi_div,bi_pow,bi_floor,bi_eq,bi_le,bi_fne,bi_shape,bi_pick,bi_ud,bi_tbl,bi_scan,bi_fillBy,bi_val,bi_catch};
|
#ifndef NO_RT
|
||||||
|
B provide[] = {bi_type,bi_fill,bi_log,bi_grLen,bi_grOrd,bi_asrt,bi_add,bi_sub,bi_mul,bi_div,bi_pow,bi_floor,bi_eq,bi_le,bi_fne,bi_shape,bi_pick,bi_ud,bi_tbl,bi_scan,bi_fillBy,bi_val,bi_catch};
|
||||||
#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};
|
#ifndef ALL_R0
|
||||||
#else
|
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};
|
||||||
Block* runtime0_b = load_compImport(
|
|
||||||
#include "gen/runtime0"
|
|
||||||
);
|
|
||||||
B r0r = m_funBlock(runtime0_b, 0); ptr_dec(runtime0_b);
|
|
||||||
B* runtime_0 = toHArr(r0r)->a;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Block* runtime_b = load_compImport(
|
|
||||||
#include "gen/runtime1"
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifdef ALL_R0
|
|
||||||
dec(r0r);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
B rtRes = m_funBlock(runtime_b, 0); ptr_dec(runtime_b);
|
|
||||||
B rtObjRaw = TI(rtRes).get(rtRes,0);
|
|
||||||
B rtFinish = TI(rtRes).get(rtRes,1);
|
|
||||||
dec(rtRes);
|
|
||||||
|
|
||||||
if (c(Arr,rtObjRaw)->ia != rtLen) err("incorrectly defined rtLen!");
|
|
||||||
HArr_p runtimeH = m_harrUc(rtObjRaw);
|
|
||||||
BS2B rtObjGet = TI(rtObjRaw).get;
|
|
||||||
|
|
||||||
rt_sortDsc = rtObjGet(rtObjRaw, 11); gc_add(rt_sortDsc);
|
|
||||||
rt_merge = rtObjGet(rtObjRaw, 13); gc_add(rt_merge);
|
|
||||||
rt_undo = rtObjGet(rtObjRaw, 48); gc_add(rt_undo);
|
|
||||||
rt_select = rtObjGet(rtObjRaw, 35); gc_add(rt_select);
|
|
||||||
rt_slash = rtObjGet(rtObjRaw, 32); gc_add(rt_slash);
|
|
||||||
rt_join = rtObjGet(rtObjRaw, 23); gc_add(rt_join);
|
|
||||||
rt_ud = rtObjGet(rtObjRaw, 27); gc_add(rt_ud);
|
|
||||||
rt_pick = rtObjGet(rtObjRaw, 36); gc_add(rt_pick);
|
|
||||||
rt_take = rtObjGet(rtObjRaw, 25); gc_add(rt_take);
|
|
||||||
rt_drop = rtObjGet(rtObjRaw, 26); gc_add(rt_drop);
|
|
||||||
rt_group = rtObjGet(rtObjRaw, 41); gc_add(rt_group);
|
|
||||||
rt_under = rtObjGet(rtObjRaw, 56); gc_add(rt_under);
|
|
||||||
rt_reverse = rtObjGet(rtObjRaw, 30); gc_add(rt_reverse);
|
|
||||||
rt_indexOf = rtObjGet(rtObjRaw, 37); gc_add(rt_indexOf);
|
|
||||||
rt_count = rtObjGet(rtObjRaw, 38); gc_add(rt_count);
|
|
||||||
rt_memberOf= rtObjGet(rtObjRaw, 39); gc_add(rt_memberOf);
|
|
||||||
rt_find = rtObjGet(rtObjRaw, 40); gc_add(rt_find);
|
|
||||||
rt_cell = rtObjGet(rtObjRaw, 45); gc_add(rt_cell);
|
|
||||||
|
|
||||||
for (usz i = 0; i < rtLen; i++) {
|
|
||||||
#ifdef RT_WRAP
|
|
||||||
r1Objs[i] = rtObjGet(rtObjRaw, i); gc_add(r1Objs[i]);
|
|
||||||
#endif
|
|
||||||
#ifdef ALL_R1
|
|
||||||
B r = rtObjGet(rtObjRaw, i);
|
|
||||||
#else
|
#else
|
||||||
B r = rtComplete[i]? inc(fruntime[i]) : rtObjGet(rtObjRaw, i);
|
Block* runtime0_b = load_compImport(
|
||||||
|
#include "gen/runtime0"
|
||||||
|
);
|
||||||
|
B r0r = m_funBlock(runtime0_b, 0); ptr_dec(runtime0_b);
|
||||||
|
B* runtime_0 = toHArr(r0r)->a;
|
||||||
#endif
|
#endif
|
||||||
if (isNothing(r)) { printf("· in runtime!\n"); exit(1); }
|
|
||||||
if (isVal(r)) v(r)->flags|= i+1;
|
Block* runtime_b = load_compImport(
|
||||||
#ifdef RT_WRAP
|
#include "gen/runtime1"
|
||||||
r = rtWrap_wrap(r);
|
);
|
||||||
|
|
||||||
|
#ifdef ALL_R0
|
||||||
|
dec(r0r);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
B rtRes = m_funBlock(runtime_b, 0); ptr_dec(runtime_b);
|
||||||
|
B rtObjRaw = TI(rtRes).get(rtRes,0);
|
||||||
|
B rtFinish = TI(rtRes).get(rtRes,1);
|
||||||
|
dec(rtRes);
|
||||||
|
|
||||||
|
if (c(Arr,rtObjRaw)->ia != rtLen) err("incorrectly defined rtLen!");
|
||||||
|
HArr_p runtimeH = m_harrUc(rtObjRaw);
|
||||||
|
BS2B rtObjGet = TI(rtObjRaw).get;
|
||||||
|
|
||||||
|
rt_sortDsc = rtObjGet(rtObjRaw, 11); gc_add(rt_sortDsc);
|
||||||
|
rt_merge = rtObjGet(rtObjRaw, 13); gc_add(rt_merge);
|
||||||
|
rt_undo = rtObjGet(rtObjRaw, 48); gc_add(rt_undo);
|
||||||
|
rt_select = rtObjGet(rtObjRaw, 35); gc_add(rt_select);
|
||||||
|
rt_slash = rtObjGet(rtObjRaw, 32); gc_add(rt_slash);
|
||||||
|
rt_join = rtObjGet(rtObjRaw, 23); gc_add(rt_join);
|
||||||
|
rt_ud = rtObjGet(rtObjRaw, 27); gc_add(rt_ud);
|
||||||
|
rt_pick = rtObjGet(rtObjRaw, 36); gc_add(rt_pick);
|
||||||
|
rt_take = rtObjGet(rtObjRaw, 25); gc_add(rt_take);
|
||||||
|
rt_drop = rtObjGet(rtObjRaw, 26); gc_add(rt_drop);
|
||||||
|
rt_group = rtObjGet(rtObjRaw, 41); gc_add(rt_group);
|
||||||
|
rt_under = rtObjGet(rtObjRaw, 56); gc_add(rt_under);
|
||||||
|
rt_reverse = rtObjGet(rtObjRaw, 30); gc_add(rt_reverse);
|
||||||
|
rt_indexOf = rtObjGet(rtObjRaw, 37); gc_add(rt_indexOf);
|
||||||
|
rt_count = rtObjGet(rtObjRaw, 38); gc_add(rt_count);
|
||||||
|
rt_memberOf= rtObjGet(rtObjRaw, 39); gc_add(rt_memberOf);
|
||||||
|
rt_find = rtObjGet(rtObjRaw, 40); gc_add(rt_find);
|
||||||
|
rt_cell = rtObjGet(rtObjRaw, 45); gc_add(rt_cell);
|
||||||
|
|
||||||
|
for (usz i = 0; i < rtLen; i++) {
|
||||||
|
#ifdef RT_WRAP
|
||||||
|
r1Objs[i] = rtObjGet(rtObjRaw, i); gc_add(r1Objs[i]);
|
||||||
|
#endif
|
||||||
|
#ifdef ALL_R1
|
||||||
|
B r = rtObjGet(rtObjRaw, i);
|
||||||
|
#else
|
||||||
|
B r = rtComplete[i]? inc(fruntime[i]) : rtObjGet(rtObjRaw, i);
|
||||||
|
#endif
|
||||||
|
if (isNothing(r)) { printf("· in runtime!\n"); exit(1); }
|
||||||
if (isVal(r)) v(r)->flags|= i+1;
|
if (isVal(r)) v(r)->flags|= i+1;
|
||||||
#endif
|
#ifdef RT_WRAP
|
||||||
runtimeH.a[i] = r;
|
r = rtWrap_wrap(r);
|
||||||
}
|
if (isVal(r)) v(r)->flags|= i+1;
|
||||||
dec(rtObjRaw);
|
#endif
|
||||||
B* runtime = runtimeH.a;
|
runtimeH.a[i] = r;
|
||||||
B rtObj = runtimeH.b;
|
}
|
||||||
dec(c1(rtFinish, m_v2(inc(bi_decp), inc(bi_primInd)))); dec(rtFinish);
|
dec(rtObjRaw);
|
||||||
|
B* runtime = runtimeH.a;
|
||||||
|
B rtObj = runtimeH.b;
|
||||||
|
dec(c1(rtFinish, m_v2(inc(bi_decp), inc(bi_primInd)))); dec(rtFinish);
|
||||||
|
load_compArg = m_v2(FAKE_RUNTIME? frtObj : rtObj, inc(bi_sys)); gc_add(FAKE_RUNTIME? rtObj : frtObj);
|
||||||
|
gc_add(load_compArg);
|
||||||
|
#else
|
||||||
|
B* runtime = fruntime;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
load_compArg = m_v2(FAKE_RUNTIME? frtObj : rtObj, inc(bi_sys)); gc_add(FAKE_RUNTIME? rtObj : frtObj);
|
|
||||||
gc_add(load_compArg);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef NO_COMP
|
#ifdef PRECOMP
|
||||||
Block* c = load_compObj(
|
Block* c = load_compObj(
|
||||||
#include "gen/interp"
|
#include "gen/interp"
|
||||||
, bi_N
|
, bi_N
|
||||||
@ -194,6 +198,12 @@ static inline void load_init() { // very last init function
|
|||||||
print(interp);
|
print(interp);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
dec(interp);
|
dec(interp);
|
||||||
|
#ifdef HEAP_VERIFY
|
||||||
|
heapVerify();
|
||||||
|
#endif
|
||||||
|
rtWrap_print();
|
||||||
|
CTR_FOR(CTR_PRINT)
|
||||||
|
printAllocStats();
|
||||||
exit(0);
|
exit(0);
|
||||||
#else // use compiler
|
#else // use compiler
|
||||||
Block* comp_b = load_compImport(
|
Block* comp_b = load_compImport(
|
||||||
@ -216,7 +226,7 @@ static inline void load_init() { // very last init function
|
|||||||
dec(fmtM);
|
dec(fmtM);
|
||||||
#endif
|
#endif
|
||||||
gc_enable();
|
gc_enable();
|
||||||
#endif // NO_COMP
|
#endif // PRECOMP
|
||||||
}
|
}
|
||||||
|
|
||||||
B bqn_execFile(B path, B args) { // consumes both
|
B bqn_execFile(B path, B args) { // consumes both
|
||||||
|
|||||||
171
src/vm.c
171
src/vm.c
@ -119,26 +119,86 @@ void gsPrint() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Block* compileBlock(B block, Comp* comp, bool* bDone, i32* bc, usz bcIA, B blocks, B nameList, Scope* sc, i32 depth) {
|
||||||
|
usz cIA = a(block)->ia;
|
||||||
|
if (cIA!=4 && cIA!=6) thrM("VM compiler: Bad block info size");
|
||||||
NOINLINE Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo, B src) { // consumes all
|
BS2B bgetU = TI(block).getU;
|
||||||
HArr* blocksH = toHArr(blocksq);
|
usz ty = o2s(bgetU(block,0)); if (ty>2) thrM("VM compiler: Bad type");
|
||||||
usz bam = blocksH->ia;
|
bool imm = o2b(bgetU(block,1));
|
||||||
|
usz idx = o2s(bgetU(block,2)); if (idx>=bcIA) thrM("VM compiler: Bytecode index out of bounds");
|
||||||
|
usz vam = o2s(bgetU(block,3)); if (vam!=(u16)vam) thrM("VM compiler: >2⋆16 variables not supported"); // TODO any reason for this? 2⋆32 vars should just work, no?
|
||||||
|
i32* thisBC = bc+idx;
|
||||||
|
i32 h = 0; // stack height
|
||||||
|
i32 hM = 0; // max stack height
|
||||||
|
i32 mpsc = 0;
|
||||||
|
i32* c = thisBC;
|
||||||
|
TSALLOC(Block*,nBlT);
|
||||||
|
while (true) {
|
||||||
|
i32* n = nextBC(c);
|
||||||
|
if (n-thisBC-1 >= bcIA) thrM("VM compiler: No RETN/RETD found before end of bytecode");
|
||||||
|
switch (*c) {
|
||||||
|
case RETN: if(h!=1) thrM("VM compiler: Wrong stack size before RETN");
|
||||||
|
goto returned;
|
||||||
|
case RETD: if(h!=1&h!=0) thrM("VM compiler: Wrong stack size before RETD");
|
||||||
|
goto returned;
|
||||||
|
case DFND:
|
||||||
|
u32 id = c[1];
|
||||||
|
if ((u32)id >= a(blocks)->ia) thrM("VM compiler: DFND index out-of-bounds");
|
||||||
|
if (bDone[id]) thrM("VM compiler: DFND of the same block in multiple places");
|
||||||
|
bDone[id] = true;
|
||||||
|
c[1] = TSSIZE(nBlT);
|
||||||
|
TSADD(nBlT, compileBlock(TI(blocks).getU(blocks,id), comp, bDone, bc, bcIA, blocks, nameList, sc, depth+1));
|
||||||
|
break;
|
||||||
|
case LOCO: case LOCM: case LOCU:
|
||||||
|
if (c[1]>mpsc) mpsc = c[1];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
h+= stackDiff(c);
|
||||||
|
if (h<0) thrM("VM compiler: Stack size goes negative");
|
||||||
|
if (h>hM) hM = h;
|
||||||
|
c = n;
|
||||||
|
} returned:;
|
||||||
|
u64 blC = TSSIZE(nBlT);
|
||||||
|
BlBlocks* nBl = mm_allocN(fsizeof(BlBlocks,a,Block*,blC), t_blBlocks);
|
||||||
|
nBl->am = blC;
|
||||||
|
memcpy(nBl->a, nBlT, blC*sizeof(Block*));
|
||||||
|
TSFREE(nBlT);
|
||||||
|
if (mpsc>U16_MAX) thrM("VM compiler: LOC_ too deep");
|
||||||
|
|
||||||
// B* objPtr = harr_ptr(objs); usz objIA = a(objs)->ia;
|
Body* body = mm_allocN(fsizeof(Body,varIDs,i32,vam), t_body);
|
||||||
// for (usz i = 0; i < objIA; i++) objPtr[i] = c2(bi_fill, c1(bi_pick, inc(objPtr[i])), objPtr[i]);
|
body->comp = comp; ptr_inc(comp);
|
||||||
|
body->bc = thisBC;
|
||||||
|
body->blocks = nBl;
|
||||||
|
body->maxStack = hM;
|
||||||
|
body->maxPSC = (u16)mpsc;
|
||||||
|
body->endStack = h;
|
||||||
|
body->varAm = (u16)vam;
|
||||||
|
if (cIA==4) {
|
||||||
|
body->nsDesc = NULL;
|
||||||
|
for (i32 i = 0; i < vam; i++) body->varIDs[i] = -1;
|
||||||
|
} else m_nsDesc(body, imm, ty, inc(nameList), bgetU(block,4), bgetU(block,5));
|
||||||
|
|
||||||
|
Block* bl = mm_allocN(sizeof(Block), t_block);
|
||||||
|
bl->body = body;
|
||||||
|
bl->imm = imm;
|
||||||
|
bl->ty = (u8)ty;
|
||||||
|
return bl;
|
||||||
|
}
|
||||||
|
|
||||||
|
NOINLINE Block* compile(B bcq, B objs, B blocks, B indices, B tokenInfo, B src, Scope* sc) { // consumes all; assumes arguments are valid (verifies some stuff, but definitely not everything)
|
||||||
|
usz bIA = a(blocks)->ia;
|
||||||
|
|
||||||
I32Arr* bca = toI32Arr(bcq);
|
I32Arr* bca = toI32Arr(bcq);
|
||||||
i32* bc = bca->a;
|
i32* bc = bca->a;
|
||||||
usz bcl = bca->ia;
|
usz bcIA = bca->ia;
|
||||||
Comp* comp = mm_allocN(fsizeof(Comp,blocks,Block*,bam), t_comp);
|
Comp* comp = mm_allocN(sizeof(Comp), t_comp);
|
||||||
comp->bc = tag(bca, ARR_TAG);
|
comp->bc = tag(bca, ARR_TAG);
|
||||||
comp->indices = indices;
|
comp->indices = indices;
|
||||||
comp->src = src;
|
comp->src = src;
|
||||||
comp->objs = toHArr(objs);
|
comp->objs = toHArr(objs);
|
||||||
comp->blockAm = bam;
|
comp->blockAm = 0;
|
||||||
B* blockDefs = blocksH->a;
|
|
||||||
B nameList;
|
B nameList;
|
||||||
if (isNothing(tokenInfo)) {
|
if (isNothing(tokenInfo)) {
|
||||||
nameList = bi_emptyHVec;
|
nameList = bi_emptyHVec;
|
||||||
@ -147,68 +207,19 @@ NOINLINE Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo, B src)
|
|||||||
nameList = TI(t).getU(t,0);
|
nameList = TI(t).getU(t,0);
|
||||||
}
|
}
|
||||||
if (!isNothing(src) && !isNothing(indices)) {
|
if (!isNothing(src) && !isNothing(indices)) {
|
||||||
if (isAtm(indices) || rnk(indices)!=1 || a(indices)->ia!=2) thrM("compile: bad indices");
|
if (isAtm(indices) || rnk(indices)!=1 || a(indices)->ia!=2) thrM("VM compiler: Bad indices");
|
||||||
for (i32 i = 0; i < 2; i++) {
|
for (i32 i = 0; i < 2; i++) {
|
||||||
B ind = TI(indices).getU(indices,i);
|
B ind = TI(indices).getU(indices,i);
|
||||||
if (isAtm(ind) || rnk(ind)!=1 || a(ind)->ia!=bcl) thrM("compile: bad indices");
|
if (isAtm(ind) || rnk(ind)!=1 || a(ind)->ia!=bcIA) thrM("VM compiler: Bad indices");
|
||||||
BS2B indGetU = TI(ind).getU;
|
BS2B indGetU = TI(ind).getU;
|
||||||
for (usz j = 0; j < bcl; j++) o2i(indGetU(ind,j));
|
for (usz j = 0; j < bcIA; j++) o2i(indGetU(ind,j));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TALLOC(bool,bDone,bIA);
|
||||||
for (usz i = 0; i < bam; i++) {
|
for (usz i = 0; i < bIA; i++) bDone[i] = false;
|
||||||
B cbld = blockDefs[i];
|
Block* ret = compileBlock(TI(blocks).getU(blocks, 0), comp, bDone, bc, bcIA, blocks, nameList, sc, 0);
|
||||||
usz cbia = a(cbld)->ia;
|
TFREE(bDone);
|
||||||
if (cbia!=4 && cbia!=6) thrM("bad compile block");
|
ptr_dec(comp); dec(blocks); dec(tokenInfo);
|
||||||
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 (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 < 0) thrM("Invalid bytecode: stack size goes negative");
|
|
||||||
if (ssz>mssz) mssz = ssz;
|
|
||||||
if (*scan==LOCO | *scan==LOCM | *scan==LOCU) {
|
|
||||||
if (scan[1]>mpsc) mpsc = scan[1];
|
|
||||||
}
|
|
||||||
scan = nextBC(scan);
|
|
||||||
if (scan-bc >= bcl) thrM("no RETN/RETD found at end of bytecode");
|
|
||||||
}
|
|
||||||
if (mpsc>U16_MAX) thrM("LOC_ too deep");
|
|
||||||
|
|
||||||
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);
|
|
||||||
bl->body = body;
|
|
||||||
bl->imm = imm;
|
|
||||||
bl->ty = (u8)ty;
|
|
||||||
comp->blocks[i] = bl;
|
|
||||||
}
|
|
||||||
|
|
||||||
Block* ret = c(Block,inc(tag(comp->blocks[0], OBJ_TAG)));
|
|
||||||
// TODO store blocks in each body, then decrement each of comp->blocks; also then move temp block list out of Comp as it's useless then
|
|
||||||
// for (usz i = 0; i < bam; i++) ptr_dec(comp->blocks[i]);
|
|
||||||
ptr_dec(comp);
|
|
||||||
ptr_dec(blocksH);
|
|
||||||
dec(tokenInfo);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,7 +301,7 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
|
|||||||
printf("new eval\n");
|
printf("new eval\n");
|
||||||
#endif
|
#endif
|
||||||
B* objs = b->comp->objs->a;
|
B* objs = b->comp->objs->a;
|
||||||
Block** blocks = b->comp->blocks;
|
Block** blocks = b->blocks->a; // b->comp->blocks;
|
||||||
i32* bc = b->bc;
|
i32* bc = b->bc;
|
||||||
pushEnv(sc, bc);
|
pushEnv(sc, bc);
|
||||||
gsReserve(b->maxStack);
|
gsReserve(b->maxStack);
|
||||||
@ -527,11 +538,6 @@ B m_md2Block(Block* bl, Scope* psc) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void comp_free(Value* x) {
|
|
||||||
Comp* c = (Comp*)x;
|
|
||||||
ptr_decR(c->objs); decR(c->bc); decR(c->src); decR(c->indices);
|
|
||||||
u32 am = c->blockAm; for(u32 i = 0; i < am; i++) ptr_dec(c->blocks[i]);
|
|
||||||
}
|
|
||||||
void scope_free(Value* x) {
|
void scope_free(Value* x) {
|
||||||
Scope* c = (Scope*)x;
|
Scope* c = (Scope*)x;
|
||||||
if (c->psc) ptr_decR(c->psc);
|
if (c->psc) ptr_decR(c->psc);
|
||||||
@ -539,18 +545,15 @@ void scope_free(Value* x) {
|
|||||||
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(Value* x) { Body* c = (Body *)x; ptr_decR(c->comp); if(c->nsDesc)ptr_decR(c->nsDesc); }
|
void comp_free(Value* x) { Comp* c = (Comp *)x; ptr_decR(c->objs); decR(c->bc); decR(c->src); decR(c->indices); }
|
||||||
|
void body_free(Value* x) { Body* c = (Body *)x; ptr_decR(c->comp); if(c->nsDesc)ptr_decR(c->nsDesc); ptr_decR(c->blocks); }
|
||||||
void block_free(Value* x) { Block* c = (Block *)x; ptr_decR(c->body); }
|
void block_free(Value* x) { Block* c = (Block *)x; ptr_decR(c->body); }
|
||||||
void funBl_free(Value* x) { FunBlock* c = (FunBlock*)x; ptr_decR(c->sc); ptr_decR(c->bl); }
|
void funBl_free(Value* x) { FunBlock* c = (FunBlock*)x; ptr_decR(c->sc); ptr_decR(c->bl); }
|
||||||
void md1Bl_free(Value* x) { Md1Block* c = (Md1Block*)x; ptr_decR(c->sc); ptr_decR(c->bl); }
|
void md1Bl_free(Value* x) { Md1Block* c = (Md1Block*)x; ptr_decR(c->sc); ptr_decR(c->bl); }
|
||||||
void md2Bl_free(Value* x) { Md2Block* c = (Md2Block*)x; ptr_decR(c->sc); ptr_decR(c->bl); }
|
void md2Bl_free(Value* x) { Md2Block* c = (Md2Block*)x; ptr_decR(c->sc); ptr_decR(c->bl); }
|
||||||
void alias_free(Value* x) { dec(((FldAlias*)x)->obj); }
|
void alias_free(Value* x) { dec(((FldAlias*)x)->obj); }
|
||||||
|
void bBlks_free(Value* x) { BlBlocks* c = (BlBlocks*)x; u16 am = c->am; for (u32 i = 0; i < am; i++) ptr_dec(c->a[i]); }
|
||||||
|
|
||||||
void comp_visit(Value* x) {
|
|
||||||
Comp* c = (Comp*)x;
|
|
||||||
mm_visitP(c->objs); mm_visit(c->bc); mm_visit(c->src); mm_visit(c->indices);
|
|
||||||
u32 am = c->blockAm; for(u32 i = 0; i < am; i++) mm_visitP(c->blocks[i]);
|
|
||||||
}
|
|
||||||
void scope_visit(Value* x) {
|
void scope_visit(Value* x) {
|
||||||
Scope* c = (Scope*)x;
|
Scope* c = (Scope*)x;
|
||||||
if (c->psc) mm_visitP(c->psc);
|
if (c->psc) mm_visitP(c->psc);
|
||||||
@ -558,18 +561,21 @@ void scope_visit(Value* x) {
|
|||||||
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(Value* x) { Body* c = (Body *)x; mm_visitP(c->comp); if(c->nsDesc)mm_visitP(c->nsDesc); }
|
void comp_visit(Value* x) { Comp* c = (Comp *)x; mm_visitP(c->objs); mm_visit(c->bc); mm_visit(c->src); mm_visit(c->indices); }
|
||||||
|
void body_visit(Value* x) { Body* c = (Body *)x; mm_visitP(c->comp); if(c->nsDesc)mm_visitP(c->nsDesc); mm_visitP(c->blocks); }
|
||||||
void block_visit(Value* x) { Block* c = (Block *)x; mm_visitP(c->body); }
|
void block_visit(Value* x) { Block* c = (Block *)x; mm_visitP(c->body); }
|
||||||
void funBl_visit(Value* x) { FunBlock* c = (FunBlock*)x; mm_visitP(c->sc); mm_visitP(c->bl); }
|
void funBl_visit(Value* x) { FunBlock* c = (FunBlock*)x; mm_visitP(c->sc); mm_visitP(c->bl); }
|
||||||
void md1Bl_visit(Value* x) { Md1Block* c = (Md1Block*)x; mm_visitP(c->sc); mm_visitP(c->bl); }
|
void md1Bl_visit(Value* x) { Md1Block* c = (Md1Block*)x; mm_visitP(c->sc); mm_visitP(c->bl); }
|
||||||
void md2Bl_visit(Value* x) { Md2Block* c = (Md2Block*)x; mm_visitP(c->sc); mm_visitP(c->bl); }
|
void md2Bl_visit(Value* x) { Md2Block* c = (Md2Block*)x; mm_visitP(c->sc); mm_visitP(c->bl); }
|
||||||
void alias_visit(Value* x) { mm_visit(((FldAlias*)x)->obj); }
|
void alias_visit(Value* x) { mm_visit(((FldAlias*)x)->obj); }
|
||||||
|
void bBlks_visit(Value* x) { BlBlocks* c = (BlBlocks*)x; u16 am = c->am; for (u32 i = 0; i < am; i++) mm_visitP(c->a[i]); }
|
||||||
|
|
||||||
void comp_print (B x) { printf("(%p: comp)",v(x)); }
|
void comp_print (B x) { printf("(%p: comp)",v(x)); }
|
||||||
void body_print (B x) { printf("(%p: body varam=%d)",v(x),c(Body,x)->varAm); }
|
void body_print (B x) { printf("(%p: body varam=%d)",v(x),c(Body,x)->varAm); }
|
||||||
void block_print(B x) { printf("(%p: block for %p)",v(x),c(Block,x)->body); }
|
void block_print(B x) { printf("(%p: block for %p)",v(x),c(Block,x)->body); }
|
||||||
void scope_print(B x) { printf("(%p: scope; vars:",v(x));Scope*sc=c(Scope,x);for(u64 i=0;i<sc->varAm;i++){printf(" ");print(sc->vars[i]);}printf(")"); }
|
void scope_print(B x) { printf("(%p: scope; vars:",v(x));Scope*sc=c(Scope,x);for(u64 i=0;i<sc->varAm;i++){printf(" ");print(sc->vars[i]);}printf(")"); }
|
||||||
void alias_print(B x) { printf("(alias %d of ", c(FldAlias,x)->p); print(c(FldAlias,x)->obj); printf(")"); }
|
void alias_print(B x) { printf("(alias %d of ", c(FldAlias,x)->p); print(c(FldAlias,x)->obj); printf(")"); }
|
||||||
|
void bBlks_print(B x) { printf("(block list)"); }
|
||||||
|
|
||||||
// void funBl_print(B x) { printf("(%p: function"" block bl=%p sc=%p)",v(x),c(FunBlock,x)->bl,c(FunBlock,x)->sc); }
|
// void funBl_print(B x) { printf("(%p: function"" block bl=%p sc=%p)",v(x),c(FunBlock,x)->bl,c(FunBlock,x)->sc); }
|
||||||
// void md1Bl_print(B x) { printf("(%p: 1-modifier block bl=%p sc=%p)",v(x),c(Md1Block,x)->bl,c(Md1Block,x)->sc); }
|
// void md1Bl_print(B x) { printf("(%p: 1-modifier block bl=%p sc=%p)",v(x),c(Md1Block,x)->bl,c(Md1Block,x)->sc); }
|
||||||
@ -609,6 +615,7 @@ void comp_init() {
|
|||||||
ti[t_body ].free = body_free; ti[t_body ].visit = body_visit; ti[t_body ].print = body_print;
|
ti[t_body ].free = body_free; ti[t_body ].visit = body_visit; ti[t_body ].print = body_print;
|
||||||
ti[t_block ].free = block_free; ti[t_block ].visit = block_visit; ti[t_block ].print = block_print;
|
ti[t_block ].free = block_free; ti[t_block ].visit = block_visit; ti[t_block ].print = block_print;
|
||||||
ti[t_scope ].free = scope_free; ti[t_scope ].visit = scope_visit; ti[t_scope ].print = scope_print;
|
ti[t_scope ].free = scope_free; ti[t_scope ].visit = scope_visit; ti[t_scope ].print = scope_print;
|
||||||
|
ti[t_blBlocks ].free = bBlks_free; ti[t_blBlocks ].visit = bBlks_visit; ti[t_blBlocks ].print = bBlks_print;
|
||||||
ti[t_fldAlias ].free = alias_free; ti[t_fldAlias ].visit = alias_visit; ti[t_fldAlias ].print = alias_print;
|
ti[t_fldAlias ].free = alias_free; ti[t_fldAlias ].visit = alias_visit; ti[t_fldAlias ].print = alias_print;
|
||||||
ti[t_fun_block].free = funBl_free; ti[t_fun_block].visit = funBl_visit; ti[t_fun_block].print = funBl_print; ti[t_fun_block].decompose = block_decompose;
|
ti[t_fun_block].free = funBl_free; ti[t_fun_block].visit = funBl_visit; ti[t_fun_block].print = funBl_print; ti[t_fun_block].decompose = block_decompose;
|
||||||
ti[t_md1_block].free = md1Bl_free; ti[t_md1_block].visit = md1Bl_visit; ti[t_md1_block].print = md1Bl_print; ti[t_md1_block].decompose = block_decompose; ti[t_md1_block].m1_d=bl_m1d;
|
ti[t_md1_block].free = md1Bl_free; ti[t_md1_block].visit = md1Bl_visit; ti[t_md1_block].print = md1Bl_print; ti[t_md1_block].decompose = block_decompose; ti[t_md1_block].m1_d=bl_m1d;
|
||||||
|
|||||||
22
src/vm.h
22
src/vm.h
@ -1,7 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
typedef struct Comp Comp;
|
||||||
|
typedef struct BlBlocks BlBlocks;
|
||||||
typedef struct Block Block;
|
typedef struct Block Block;
|
||||||
typedef struct Body Body;
|
typedef struct Body Body;
|
||||||
typedef struct Scope Scope;
|
typedef struct Scope Scope;
|
||||||
|
typedef struct ScopeExt ScopeExt;
|
||||||
|
|
||||||
typedef struct Comp {
|
typedef struct Comp {
|
||||||
struct Value;
|
struct Value;
|
||||||
@ -10,9 +13,14 @@ typedef struct Comp {
|
|||||||
B indices;
|
B indices;
|
||||||
HArr* objs;
|
HArr* objs;
|
||||||
u32 blockAm;
|
u32 blockAm;
|
||||||
Block* blocks[];
|
|
||||||
} Comp;
|
} Comp;
|
||||||
|
|
||||||
|
struct BlBlocks {
|
||||||
|
struct Value;
|
||||||
|
u32 am;
|
||||||
|
Block* a[];
|
||||||
|
};
|
||||||
|
|
||||||
struct Block {
|
struct Block {
|
||||||
struct Value;
|
struct Value;
|
||||||
bool imm;
|
bool imm;
|
||||||
@ -24,6 +32,7 @@ typedef struct NSDesc NSDesc;
|
|||||||
struct Body {
|
struct Body {
|
||||||
struct Value;
|
struct Value;
|
||||||
Comp* comp;
|
Comp* comp;
|
||||||
|
BlBlocks* blocks;
|
||||||
// B* objs;
|
// B* objs;
|
||||||
i32* bc; // pointer in comp->bc
|
i32* bc; // pointer in comp->bc
|
||||||
u32 maxStack;
|
u32 maxStack;
|
||||||
@ -34,20 +43,29 @@ struct Body {
|
|||||||
i32 varIDs[];
|
i32 varIDs[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ScopeExt {
|
||||||
|
u16 varAm;
|
||||||
|
B vars[];
|
||||||
|
};
|
||||||
|
|
||||||
struct Scope {
|
struct Scope {
|
||||||
struct Value;
|
struct Value;
|
||||||
Scope* psc;
|
Scope* psc;
|
||||||
Body* body;
|
Body* body;
|
||||||
u16 varAm;
|
u16 varAm;
|
||||||
|
ScopeExt* ext;
|
||||||
B vars[];
|
B vars[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo, B src, Scope* sc);
|
||||||
|
|
||||||
|
|
||||||
typedef struct Env {
|
typedef struct Env {
|
||||||
Scope* sc;
|
Scope* sc;
|
||||||
union { i32* bcL; i32 bcV; };
|
union { i32* bcL; i32 bcV; };
|
||||||
} Env;
|
} Env;
|
||||||
|
|
||||||
Block* compile(B bcq, B objs, B blocksq, B indices, B tokenInfo, B src);
|
|
||||||
void vm_pst(Env* s, Env* e);
|
void vm_pst(Env* s, Env* e);
|
||||||
void vm_pstLive();
|
void vm_pstLive();
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user