diff --git a/src/fns.c b/src/fns.c index cfd92539..0c7d1a91 100644 --- a/src/fns.c +++ b/src/fns.c @@ -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]); } diff --git a/src/h.h b/src/h.h index c476475c..5db21f33 100644 --- a/src/h.h +++ b/src/h.h @@ -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(); diff --git a/src/load.c b/src/load.c new file mode 100644 index 00000000..5faaed09 --- /dev/null +++ b/src/load.c @@ -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 +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index c1c0534e..2e1e8e3f 100644 --- a/src/main.c +++ b/src/main.c @@ -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 diff --git a/src/md1.c b/src/md1.c index 7e13471a..6f489733 100644 --- a/src/md1.c +++ b/src/md1.c @@ -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 diff --git a/src/md2.c b/src/md2.c index def30f2c..61eb8ee2 100644 --- a/src/md2.c +++ b/src/md2.c @@ -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 diff --git a/src/stuff.c b/src/stuff.c index 2b965fdf..6d34ab4e 100644 --- a/src/stuff.c +++ b/src/stuff.c @@ -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 diff --git a/src/sysfn.c b/src/sysfn.c index 82a6c417..09692a67 100644 --- a/src/sysfn.c +++ b/src/sysfn.c @@ -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); diff --git a/src/utf.c b/src/utf.c index 977dec3c..2ac6904d 100644 --- a/src/utf.c +++ b/src/utf.c @@ -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) );