•BQN, split runtime/compiler loading out of main

This commit is contained in:
dzaima 2021-05-09 17:31:31 +03:00
parent 0dede67d2a
commit 0f844b4e09
9 changed files with 200 additions and 153 deletions

View File

@ -39,7 +39,13 @@ B fmtN_c1(B t, B x) {
B fmtF_c1(B t, B x) {
if (!isVal(x)) return m_str32(U"(fmtF: not given a function)");
u8 fl = v(x)->flags;
if (fl==0 || fl>rtLen) return m_str32(U"(fmtF: not given a runtime primitive)");
if (fl==0 || fl>rtLen) {
u8 ty = v(x)->type;
if (ty==t_funBI) { B r = fromUTF8l(format_pf (c(Fun,x)->extra)); dec(x); return r; }
if (ty==t_md1BI) { B r = fromUTF8l(format_pm1(c(Md1,x)->extra)); dec(x); return r; }
if (ty==t_md2BI) { B r = fromUTF8l(format_pm2(c(Md2,x)->extra)); dec(x); return r; }
return m_str32(U"(fmtF: not given a runtime primitive)");
}
dec(x);
return m_c32(U"+-×÷⋆√⌊⌈|¬∧∨<>≠=≤≥≡≢⊣⊢⥊∾≍↑↓↕«»⌽⍉/⍋⍒⊏⊑⊐⊒∊⍷⊔!˙˜˘¨⌜⁼´˝`∘○⊸⟜⌾⊘◶⎉⚇⍟⎊"[fl-1]);
}

View File

@ -107,7 +107,7 @@ char* format_type(u8 u) {
/*sfns.c*/ F(shape,"") F(pick,"") F(pair,"{𝕨‿𝕩}") F(select,"") F(slash,"/") F(join,"") F(couple,"") F(shiftb,"»") F(shifta,"«") F(take,"") F(drop,"") \
/*derv.c*/ F(fork,"(fork)") F(atop,"(atop)") F(md1d,"(derived 1-modifier)") F(md2d,"(derived 2-modifier)") \
/*sysfn.c*/ F(type,"•Type") F(decp,"•Decompose") F(primInd,"•PrimInd") F(glyph,"•Glyph") F(fill,"•FillFn") \
/*sysfn.c*/ F(grLen,"•GroupLen") F(grOrd,"•groupOrd") F(asrt,"!") F(sys,"•getsys") F(internal,"•Internal") F(show,"•Show") F(out,"•Out")
/*sysfn.c*/ F(grLen,"•GroupLen") F(grOrd,"•groupOrd") F(asrt,"!") F(sys,"•getsys") F(bqn,"•bqn") F(internal,"•Internal") F(show,"•Show") F(out,"•Out")
enum PrimFns {
#define F(N,X) pf_##N,
@ -230,6 +230,8 @@ B m_v4(B a, B b, B c, B d); // consumes all
B m_unit(B a); // consumes
B m_str32(u32* s); // meant to be used as m_str32(U"{𝕨‿𝕩}"), so doesn't free for you
B bqn_exec(B str); // consumes
NORETURN void thr(B b);
NORETURN void thrM(char* s);
jmp_buf* prepareCatch();

149
src/load.c Normal file
View File

@ -0,0 +1,149 @@
#include "h.h"
Block* compB(B x) { // consumes
BS2B xget = TI(x).get;
usz xia = a(x)->ia;
if (xia!=5 & xia!=3) thrM("compB: bad item count");
Block* r = xia==5? compile(xget(x,0),xget(x,1),xget(x,2),xget(x,3),xget(x,4))
: compile(xget(x,0),xget(x,1),xget(x,2),bi_N,bi_N);
dec(x);
return r;
}
Block* compile3(B bc, B objs, B blocks) { // consumes all
return compile(bc, objs, blocks, bi_N, bi_N);
}
B load_comp;
B load_compArg;
#ifdef FORMATTER
B load_fmt;
B bqn_fmt(B x) { // consumes
return c1(load_fmt, x);
}
#endif
Block* bqn_comp(B str) { // consumes
return compB(c2(load_comp, inc(load_compArg), str));
}
B bqn_exec(B str) { // consumes
Block* block = bqn_comp(str);
B res = m_funBlock(block, 0);
ptr_dec(block);
return res;
}
void bqn_setComp(B comp) {
load_comp = comp;
gc_add(load_comp);
}
static inline void load_init() {
B fruntime[] = {
/* +-×÷⋆√⌊⌈|¬ */ bi_add , bi_sub , bi_mul , bi_div , bi_pow , bi_N , bi_floor, bi_ceil, bi_stile , bi_not,
/* ∧∨<>≠=≤≥≡≢ */ bi_and , bi_or , bi_lt , bi_gt , bi_ne , bi_eq , bi_le , bi_ge , bi_feq , bi_fne,
/* ⊣⊢⥊∾≍↑↓↕«» */ bi_ltack, bi_rtack , bi_shape, bi_join , bi_couple, bi_take , bi_drop , bi_ud , bi_shifta, bi_shiftb,
/* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ bi_N , bi_N , bi_slash, bi_N , bi_N , bi_select, bi_pick , bi_N , bi_N , bi_N,
/* ⍷⊔!˙˜˘¨⌜⁼´ */ bi_N , bi_N , bi_asrt , bi_const, bi_swap , bi_N , bi_each , bi_tbl , bi_N , bi_fold,
/* ˝`∘○⊸⟜⌾⊘◶⎉ */ bi_N , bi_scan , bi_atop , bi_over , bi_before, bi_after , bi_N , bi_val , bi_cond , bi_N,
/* ⚇⍟⎊ */ bi_N , bi_repeat, bi_catch
};
bool rtComplete[] = {
/* +-×÷⋆√⌊⌈|¬ */ 1,1,1,1,1,0,1,1,1,1,
/* ∧∨<>≠=≤≥≡≢ */ 1,1,1,1,1,1,1,1,1,1,
/* ⊣⊢⥊∾≍↑↓↕«» */ 1,1,0,1,1,0,0,0,1,1,
/* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ 0,0,1,0,0,1,0,0,0,0,
/* ⍷⊔!˙˜˘¨⌜⁼´ */ 0,0,1,1,1,0,1,1,0,1,
/* ˝`∘○⊸⟜⌾⊘◶⎉ */ 0,1,1,1,1,1,0,1,0,0,
/* ⚇⍟⎊ */ 0,1,1
};
assert(sizeof(fruntime)/sizeof(B) == rtLen);
for (i32 i = 0; i < rtLen; i++) inc(fruntime[i]);
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 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 = compile3(
#include "runtime0"
);
B r0r = m_funBlock(runtime0_b, 0); ptr_dec(runtime0_b);
B* runtime_0 = toHArr(r0r)->a;
#endif
Block* runtime_b = compile3(
#include "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);
runtimeLen = c(Arr,rtObjRaw)->ia;
HArr_p runtimeH = m_harrUc(rtObjRaw);
BS2B rtObjGet = TI(rtObjRaw).get;
rt_sortAsc = rtObjGet(rtObjRaw, 10); gc_add(rt_sortAsc);
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);
for (usz i = 0; i < runtimeLen; i++) {
#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); }
r = rtPerf_wrap(r);
runtimeH.a[i] = r;
if (isVal(r)) v(r)->flags|= i+1;
}
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);
#ifdef NO_COMP
Block* c = compB(
#include "interp"
);
B interp = m_funBlock(c, 0); ptr_dec(c);
print(interp);
printf("\n");
dec(interp);
exit(0);
#else // use compiler
Block* comp_b = compile3(
#include "compiler"
);
load_comp = m_funBlock(comp_b, 0); ptr_dec(comp_b);
gc_add(load_comp);
#ifdef FORMATTER
Block* fmt_b = compile3(
#include "formatter"
);
B fmtM = m_funBlock(fmt_b, 0); ptr_dec(fmt_b);
load_fmt = TI(fmtM).m1_d(fmtM, m_caB(4, (B[]){inc(bi_type), inc(bi_decp), inc(bi_fmtF), inc(bi_fmtN)}));
gc_add(load_fmt);
#endif
gc_enable();
#endif // NO_COMP
}

View File

@ -21,6 +21,7 @@
// #define FORMATTER // use self-hosted formatter for output
// #define TIME // output runtime of every expression
// #define RT_PERF // time runtime primitives
// #define NO_COMP // don't load the compiler, instead execute src/interp; needed for ./precompiled.bqn
#ifdef CATCH_ERRORS
#define PROPER_FILLS (EACH_FILLS&SFNS_FILLS)
@ -52,135 +53,11 @@
#include "vm.c"
#include "ns.c"
#include "rtPerf.c"
void pr(char* a, B b) {
printf("%s", a);
print(b);
puts("");
dec(b);
fflush(stdout);
}
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);
}
#include "load.c"
int main() {
cbqn_init();
B fruntime[] = {
/* +-×÷⋆√⌊⌈|¬ */ bi_add , bi_sub , bi_mul , bi_div , bi_pow , bi_N , bi_floor, bi_ceil, bi_stile , bi_not,
/* ∧∨<>≠=≤≥≡≢ */ bi_and , bi_or , bi_lt , bi_gt , bi_ne , bi_eq , bi_le , bi_ge , bi_feq , bi_fne,
/* ⊣⊢⥊∾≍↑↓↕«» */ bi_ltack, bi_rtack , bi_shape, bi_join , bi_couple, bi_take , bi_drop , bi_ud , bi_shifta, bi_shiftb,
/* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ bi_N , bi_N , bi_slash, bi_N , bi_N , bi_select, bi_pick , bi_N , bi_N , bi_N,
/* ⍷⊔!˙˜˘¨⌜⁼´ */ bi_N , bi_N , bi_asrt , bi_const, bi_swap , bi_N , bi_each , bi_tbl , bi_N , bi_fold,
/* ˝`∘○⊸⟜⌾⊘◶⎉ */ bi_N , bi_scan , bi_atop , bi_over , bi_before, bi_after , bi_N , bi_val , bi_cond , bi_N,
/* ⚇⍟⎊ */ bi_N , bi_repeat, bi_catch
};
bool rtComplete[] = {
/* +-×÷⋆√⌊⌈|¬ */ 1,1,1,1,1,0,1,1,1,1,
/* ∧∨<>≠=≤≥≡≢ */ 1,1,1,1,1,1,1,1,1,1,
/* ⊣⊢⥊∾≍↑↓↕«» */ 1,1,0,1,1,0,0,0,1,1,
/* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ 0,0,1,0,0,1,0,0,0,0,
/* ⍷⊔!˙˜˘¨⌜⁼´ */ 0,0,1,1,1,0,1,1,0,1,
/* ˝`∘○⊸⟜⌾⊘◶⎉ */ 0,1,1,1,1,1,0,1,0,0,
/* ⚇⍟⎊ */ 0,1,1
};
assert(sizeof(fruntime)/sizeof(B) == rtLen);
for (i32 i = 0; i < rtLen; i++) inc(fruntime[i]);
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 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 = compile3(
#include "runtime0"
);
B r0r = m_funBlock(runtime0_b, 0); ptr_dec(runtime0_b);
B* runtime_0 = toHArr(r0r)->a;
#endif
Block* runtime_b = compile3(
#include "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);
runtimeLen = c(Arr,rtObjRaw)->ia;
HArr_p runtimeH = m_harrUc(rtObjRaw);
BS2B rtObjGet = TI(rtObjRaw).get;
rt_sortAsc = rtObjGet(rtObjRaw, 10); gc_add(rt_sortAsc);
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);
for (usz i = 0; i < runtimeLen; i++) {
#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); }
r = rtPerf_wrap(r);
runtimeH.a[i] = r;
if (isVal(r)) v(r)->flags|= i+1;
}
dec(rtObjRaw);
B* runtime = runtimeH.a;
B rtObj = runtimeH.b;
dec(c1(rtFinish, m_v2(inc(bi_decp), inc(bi_primInd)))); dec(rtFinish);
B compArg = m_v2(FAKE_RUNTIME? frtObj : rtObj, inc(bi_sys)); gc_add(FAKE_RUNTIME? rtObj : frtObj);
gc_add(compArg);
// uncomment to use src/interp; needed for test.bqn
// Block* c = compB(
// #include "interp"
// );
// B interp = m_funBlock(c, 0); ptr_dec(c);
// pr("result: ", interp);
// exit(0);
Block* comp_b = compile3(
#include "compiler"
);
B comp = m_funBlock(comp_b, 0); ptr_dec(comp_b);
gc_add(comp);
#ifdef FORMATTER
Block* fmt_b = compile3(
#include "formatter"
);
B fmtM = m_funBlock(fmt_b, 0); ptr_dec(fmt_b);
B fmt = TI(fmtM).m1_d(fmtM, m_caB(4, (B[]){inc(bi_type), inc(bi_decp), inc(bi_fmtF), inc(bi_fmtN)}));
gc_add(fmt);
#endif
// uncomment to self-compile and use that for the REPL
// expects a copy of mlochbaum/BQN/src/c.bqn to be at the execution directory (with •args replaced with the array in glyphs.bqn)
// char* c_src = NULL;
@ -194,17 +71,14 @@ int main() {
// if (c_src) fread(c_src, 1, c_len, f);
// fclose(f);
// } else {
// c_src = NULL;
// }
// if (c_src) {
// bqn_setComp(bqn_exec(fromUTF8(c_src, c_len)));
// } else {
// printf("couldn't read c.bqn\n");
// exit(1);
// }
// if (c_src) {
// B cbc = c2(comp, inc(compArg), fromUTF8(c_src, c_len));
// Block* cbc_b = compB(cbc);
// comp = m_funBlock(cbc_b, 0); ptr_dec(cbc_b);
// gc_add(comp);
// free(c_src);
// }
gc_enable();
while (CATCH) {
printf("caught: ");
@ -217,26 +91,26 @@ int main() {
size_t gl = 0;
getline(&ln, &gl, stdin);
if (ln[0]==0 || ln[0]==10) break;
B cbc = c2(comp, inc(compArg), fromUTF8(ln, strlen(ln)));
Block* block = bqn_comp(fromUTF8(ln, strlen(ln)));
free(ln);
Block* cbc_b = compB(cbc);
#ifdef TIME
u64 sns = nsTime();
B res = m_funBlock(cbc_b, 0);
B res = m_funBlock(block, 0);
u64 ens = nsTime();
printf("%fms\n", (ens-sns)/1e6);
#else
B res = m_funBlock(cbc_b, 0);
B res = m_funBlock(block, 0);
#endif
ptr_dec(cbc_b);
ptr_dec(block);
#ifdef FORMATTER
B resFmt = c1(fmt, res);
B resFmt = bqn_fmt(res);
printRaw(resFmt); dec(resFmt);
printf("\n");
#else
pr("", res);
print(res); putchar('\n'); fflush(stdout);
dec(res);
#endif
#ifdef HEAP_VERIFY

View File

@ -186,11 +186,11 @@ B swap_c2(B d, B w, B x) { return c2(c(Md1D,d)->f, x , w); }
#define bd(NAME) bi_##NAME = mm_alloc(sizeof(Md1), t_md1BI, ftag(MD1_TAG)); c(Md1,bi_##NAME)->c2 = NAME##_c2; c(Md1,bi_##NAME)->c1 = c1_invalid; c(Md1,bi_##NAME)->extra=pm1_##NAME; gc_add(bi_##NAME);
#define bm(NAME) bi_##NAME = mm_alloc(sizeof(Md1), t_md1BI, ftag(MD1_TAG)); c(Md1,bi_##NAME)->c2 = c2_invalid;c(Md1,bi_##NAME)->c1 = NAME##_c1 ; c(Md1,bi_##NAME)->extra=pm1_##NAME; gc_add(bi_##NAME);
void print_md1_def(B x) { printf("%s", format_pm1(c(Md1,x)->extra)); }
void print_md1BI(B x) { printf("%s", format_pm1(c(Md1,x)->extra)); }
B bi_tbl, bi_each, bi_fold, bi_scan, bi_const, bi_swap;
static inline void md1_init() { ba(tbl) ba(each) ba(fold) ba(scan) ba(const) ba(swap)
ti[t_md1BI].print = print_md1_def;
ti[t_md1BI].print = print_md1BI;
}
#undef ba

View File

@ -122,11 +122,11 @@ B cond_c2(B d, B w, B x) { B g=c(Md2D,d)->g;
#define bd(NAME) bi_##NAME = mm_alloc(sizeof(Md2), t_md2BI, ftag(MD2_TAG)); c(Md2,bi_##NAME)->c2 = NAME##_c2; c(Md2,bi_##NAME)->c1 = c1_invalid; c(Md1,bi_##NAME)->extra=pm2_##NAME; gc_add(bi_##NAME);
#define bm(NAME) bi_##NAME = mm_alloc(sizeof(Md2), t_md2BI, ftag(MD2_TAG)); c(Md2,bi_##NAME)->c2 = c2_invalid;c(Md2,bi_##NAME)->c1 = NAME##_c1; c(Md1,bi_##NAME)->extra=pm2_##NAME; gc_add(bi_##NAME);
void print_md2_def(B x) { printf("%s", format_pm2(c(Md1,x)->extra)); }
void print_md2BI(B x) { printf("%s", format_pm2(c(Md1,x)->extra)); }
B bi_val, bi_repeat, bi_atop, bi_over, bi_before, bi_after, bi_cond, bi_fillBy, bi_catch;
static inline void md2_init() { ba(val) ba(repeat) ba(atop) ba(over) ba(before) ba(after) ba(cond) ba(fillBy) ba(catch)
ti[t_md2BI].print = print_md2_def;
ti[t_md2BI].print = print_md2BI;
}
#undef ba

View File

@ -86,7 +86,9 @@ void printRaw(B x) {
BS2B xgetU = TI(x).getU;
for (usz i = 0; i < ia; i++) {
B c = xgetU(x,i);
#ifndef CATCH_ERRORS
if (c.u==0 || noFill(c)) { printf(" "); continue; }
#endif
if (!isC32(c)) thrM("bad printRaw argument: expected all character items");
printUTF8((u32)c.u);
}
@ -320,7 +322,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) F(ns)
#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) F(load)
#define F(X) static inline void X##_init();
FOR_INIT(F)
#undef F

View File

@ -147,13 +147,22 @@ B sys_c1(B t, B x);
B out_c1(B t, B x) { printRaw(x); putchar('\n'); return x; }
B show_c1(B t, B x) { print (x); putchar('\n'); return x; }
B bqn_c1(B t, B x) {
if (isAtm(x) || rnk(x)!=1) thrM("•BQN: Argument must be a character vector");
if (a(x)->type!=t_c32arr && a(x)->type!=t_c32slice) {
usz ia = a(x)->ia;
BS2B xgetU = TI(x).getU;
for (usz i = 0; i < ia; i++) if (!isC32(xgetU(x,i))) thrM("•BQN: Argument must be a character vector");
}
return bqn_exec(x);
}
#define ba(N) bi_##N = mm_alloc(sizeof(BFn), t_funBI, ftag(FUN_TAG)); c(Fun,bi_##N)->c2 = N##_c2 ;c(Fun,bi_##N)->c1 = N##_c1 ; c(Fun,bi_##N)->extra=pf_##N; c(BFn,bi_##N)->ident=bi_N; gc_add(bi_##N);
#define bd(N) bi_##N = mm_alloc(sizeof(BFn), t_funBI, ftag(FUN_TAG)); c(Fun,bi_##N)->c2 = N##_c2 ;c(Fun,bi_##N)->c1 = c1_invalid; c(Fun,bi_##N)->extra=pf_##N; c(BFn,bi_##N)->ident=bi_N; gc_add(bi_##N);
#define bm(N) bi_##N = mm_alloc(sizeof(BFn), t_funBI, ftag(FUN_TAG)); c(Fun,bi_##N)->c2 = c2_invalid;c(Fun,bi_##N)->c1 = N##_c1 ; c(Fun,bi_##N)->extra=pf_##N; c(BFn,bi_##N)->ident=bi_N; gc_add(bi_##N);
B bi_type, bi_decp, bi_primInd, bi_glyph, bi_fill, bi_grLen, bi_grOrd, bi_asrt, bi_out, bi_show, bi_sys, bi_internal;
static inline void sysfn_init() { bm(type) bm(decp) bm(primInd) bm(glyph) ba(fill) ba(grLen) bd(grOrd) ba(asrt) bm(out) bm(show) bm(sys) bd(internal) }
B bi_type, bi_decp, bi_primInd, bi_glyph, bi_fill, bi_grLen, bi_grOrd, bi_asrt, bi_out, bi_show, bi_sys, bi_bqn, bi_internal;
static inline void sysfn_init() { bm(type) bm(decp) bm(primInd) bm(glyph) ba(fill) ba(grLen) bd(grOrd) ba(asrt) bm(out) bm(show) bm(sys) bm(bqn) bd(internal) }
#undef ba
#undef bd
@ -166,12 +175,13 @@ B sys_c1(B t, B x) {
BS2B xgetU = TI(x).getU;
for (; i < a(x)->ia; i++) {
B c = xgetU(x,i);
if (eqStr(c, U"internal")) r.a[i] = inc(bi_internal);
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"internal")) r.a[i] = inc(bi_internal);
else if (eqStr(c, U"type")) r.a[i] = inc(bi_type);
else if (eqStr(c, U"decompose")) r.a[i] = inc(bi_decp);
else if (eqStr(c, U"primind")) r.a[i] = inc(bi_primInd);
else if (eqStr(c, U"type")) r.a[i] = inc(bi_type);
else 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"bqn")) r.a[i] = inc(bi_bqn);
else { dec(x); thrM("Unknown system function"); }
}
return harr_fcd(r, x);

View File

@ -36,6 +36,10 @@ B fromUTF8(char* s, i64 len) {
return r;
}
B fromUTF8l(char* s) {
return fromUTF8(s, strlen(s));
}
void printUTF8(u32 c) {
if (c<128) printf("%c", c);
else if (c<=0x07FF) printf("%c%c" , 0xC0| c>>6 , 0x80| (c &0x3F) );