diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index c09ed4d0..217dda95 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -228,6 +228,10 @@ B makeRand_c1(B t, B x) { +B exit_c1(B t, B x) { + bqn_exit(q_i32(x)? o2i(x) : 0); +} + static B makeRel(B md) { // doesn't consume return m1_d(inc(md), path_dir(inc(comp_currPath))); } @@ -243,6 +247,7 @@ B sys_c1(B t, B x) { B c = xgetU(x,i); if (eqStr(c, U"out")) r.a[i] = inc(bi_out); else if (eqStr(c, U"show")) r.a[i] = inc(bi_show); + else if (eqStr(c, U"exit")) r.a[i] = inc(bi_exit); else if (eqStr(c, U"internal")) r.a[i] = getInternalNS(); else if (eqStr(c, U"type")) r.a[i] = inc(bi_type); else if (eqStr(c, U"decompose")) r.a[i] = inc(bi_decp); diff --git a/src/core/stuff.h b/src/core/stuff.h index f3dd43e3..ffa7ae26 100644 --- a/src/core/stuff.h +++ b/src/core/stuff.h @@ -8,6 +8,7 @@ static void mm_free(Value* x); static u64 mm_size(Value* x); static void mm_visit(B x); static void mm_visitP(void* x); +NORETURN void bqn_exit(i32 code); u64 mm_heapUsed(); void printAllocStats(); static B mm_alloc(usz sz, u8 type, u64 tag) { diff --git a/src/h.h b/src/h.h index 4c6dcc90..f723ee4f 100644 --- a/src/h.h +++ b/src/h.h @@ -161,7 +161,7 @@ char* format_type(u8 u); /* sfns.c*/A(shape,"⥊") A(pick,"⊑") A(pair,"{𝕨‿𝕩}") A(select,"⊏") A(slash,"/") A(join,"∾") A(couple,"≍") A(shiftb,"»") A(shifta,"«") A(take,"↑") A(drop,"↓") A(group,"⊔") A(reverse,"⌽") \ /* sort.c*/A(gradeUp,"⍋") A(gradeDown,"⍒") \ /* sysfn.c*/M(type,"•Type") M(decp,"•Decompose") M(primInd,"•PrimInd") M(glyph,"•Glyph") A(fill,"•FillFn") M(sys,"•getsys") A(grLen,"•GroupLen") D(grOrd,"•groupOrd") \ -/* sysfn.c*/M(repr,"•Repr") A(asrt,"!") M(out,"•Out") M(show,"•Show") M(bqn,"•BQN") D(cmp,"•Cmp") A(hash,"•Hash") M(makeRand,"•MakeRand") \ +/* sysfn.c*/M(repr,"•Repr") A(asrt,"!") M(out,"•Out") M(show,"•Show") M(bqn,"•BQN") D(cmp,"•Cmp") A(hash,"•Hash") M(makeRand,"•MakeRand") M(exit,"•Exit") \ /*internal.c*/M(itype,"•internal.Type") M(refc,"•internal.Refc") M(squeeze,"•internal.Squeeze") M(isPure,"•internal.IsPure") A(info,"•internal.Info") \ /*internal.c*/D(variation,"•internal.Variation") A(listVariations,"•internal.ListVariations") M(clearRefs,"•internal.ClearRefs") M(unshare,"•internal.Unshare") diff --git a/src/load.c b/src/load.c index d9be7767..9c1cfb79 100644 --- a/src/load.c +++ b/src/load.c @@ -264,7 +264,13 @@ B bqn_execFile(B path, B args) { // consumes both return bqn_exec(file_chars(inc(path)), path, args); } - +void rtWrap_print(); +void bqn_exit(i32 code) { + rtWrap_print(); + CTR_FOR(CTR_PRINT) + printAllocStats(); + exit(code); +} static void freed_visit(Value* x) { diff --git a/src/main.c b/src/main.c index 83db7eb4..61342315 100644 --- a/src/main.c +++ b/src/main.c @@ -5,7 +5,6 @@ // TODO these are hacks around not needing tiny headers Block* bqn_comp(B str, B path, B args); Block* bqn_compSc(B str, B path, B args, Scope* sc, bool repl); -void rtWrap_print(); static B replPath; static Scope* gsc; @@ -50,9 +49,7 @@ int main(int argc, char* argv[]) { #ifdef COMP_COMP_TIME gc_add(srcB); for (i32 i = 0; i < 100; i++) { dec(bqn_exec(inc(srcB), bi_N, bi_N)); gc_maybeGC(); } - rtWrap_print(); - CTR_FOR(CTR_PRINT) - exit(0); + bqn_exit(0); #endif bqn_setComp(bqn_exec(srcB, bi_N, bi_N)); } else { @@ -142,6 +139,7 @@ int main(int argc, char* argv[]) { args = ap.b; } dec(bqn_execFile(src, args)); + gc_forceGC(); } } if (startREPL) { @@ -195,9 +193,6 @@ int main(int argc, char* argv[]) { #ifdef HEAP_VERIFY heapVerify(); #endif - rtWrap_print(); - CTR_FOR(CTR_PRINT) - // printf("done\n");fflush(stdout); while(1); - printAllocStats(); + bqn_exit(0); #undef INIT }