diff --git a/src/builtins/fns.c b/src/builtins/fns.c index 4b19239f..66bbf2cd 100644 --- a/src/builtins/fns.c +++ b/src/builtins/fns.c @@ -349,7 +349,7 @@ void fun_gcFn() { -static void print_funBI(B x) { printf("%s", pfn_repr(c(Fun,x)->extra)); } +static void print_funBI(FILE* f, B x) { fprintf(f, "%s", pfn_repr(c(Fun,x)->extra)); } static B funBI_uc1(B t, B o, B x) { return c(BFn,t)->uc1(t, o, x); } static B funBI_ucw(B t, B o, B w, B x) { return c(BFn,t)->ucw(t, o, w, x); } static B funBI_im(B t, B x) { return c(BFn,t)->im(t, x); } diff --git a/src/builtins/md1.c b/src/builtins/md1.c index 142c09a9..66500de3 100644 --- a/src/builtins/md1.c +++ b/src/builtins/md1.c @@ -517,7 +517,7 @@ B insert_c2(Md1D* d, B w, B x) { B f = d->f; #pragma GCC diagnostic pop -static void print_md1BI(B x) { printf("%s", pm1_repr(c(Md1,x)->extra)); } +static void print_md1BI(FILE* f, B x) { fprintf(f, "%s", pm1_repr(c(Md1,x)->extra)); } static B md1BI_im(Md1D* d, B x) { return ((BMd1*)d->m1)->im(d, x); } static B md1BI_iw(Md1D* d, B w, B x) { return ((BMd1*)d->m1)->iw(d, w, x); } static B md1BI_ix(Md1D* d, B w, B x) { return ((BMd1*)d->m1)->ix(d, w, x); } diff --git a/src/builtins/md2.c b/src/builtins/md2.c index 4a8bd472..ce3992ac 100644 --- a/src/builtins/md2.c +++ b/src/builtins/md2.c @@ -293,7 +293,7 @@ B depth_c1(Md2D* d, B x) { return m2c1(rt_depth, d->f, d->g, x); } B depth_c2(Md2D* d, B w, B x) { return m2c2(rt_depth, d->f, d->g, w, x); } -static void print_md2BI(B x) { printf("%s", pm2_repr(c(Md1,x)->extra)); } +static void print_md2BI(FILE* f, B x) { fprintf(f, "%s", pm2_repr(c(Md1,x)->extra)); } static B md2BI_im(Md2D* d, B x) { return ((BMd2*)d->m2)->im(d, x); } static B md2BI_iw(Md2D* d, B w, B x) { return ((BMd2*)d->m2)->iw(d, w, x); } static B md2BI_ix(Md2D* d, B w, B x) { return ((BMd2*)d->m2)->ix(d, w, x); } diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index cf436c32..77f01da1 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -754,6 +754,7 @@ extern char** environ; #if __has_include() #include #include +typedef struct pollfd pollfd; void shClose(int fd) { if (close(fd)) err("bad file descriptor close"); } // #define shDbg printf @@ -827,8 +828,14 @@ B sh_c2(B t, B w, B x) { // polling mess const u64 bufsz = 1024; TALLOC(char, oBuf, bufsz); - struct pollfd ps[] = {{.fd=p_out[0], .events=POLLIN}, {.fd=p_err[0], .events=POLLIN}, {.fd=p_in[1], .events=POLLOUT}}; - while (poll(&ps[0], iDone? 2 : 3, -1) > 0) { + + pollfd ps[3]; + i32 plen = 0; + ps[plen++] = (pollfd){.fd=p_err[0], .events=POLLIN}; + ps[plen++] = (pollfd){.fd=p_out[0], .events=POLLIN}; + ps[plen++] = (pollfd){.fd=p_in[1], .events=POLLOUT}; + + while (poll(&ps[0], plen - iDone, -1) > 0) { shDbg("next poll; revents: out:%d err:%d in:%d\n", ps[0].revents, ps[1].revents, ps[2].revents); if (ps[0].revents & POLLIN) while(true) { i64 len = read(p_out[0], &oBuf[0], bufsz); shDbg("read stdout "N64d"\n",len); if(len<=0)break; s_out = vec_join(s_out, fromUTF8(oBuf, len)); } if (ps[1].revents & POLLIN) while(true) { i64 len = read(p_err[0], &oBuf[0], bufsz); shDbg("read stderr "N64d"\n",len); if(len<=0)break; s_err = vec_join(s_err, fromUTF8(oBuf, len)); } diff --git a/src/core/derv.c b/src/core/derv.c index c50cf2b4..28d2a20c 100644 --- a/src/core/derv.c +++ b/src/core/derv.c @@ -14,11 +14,11 @@ static void md2H_visit(Value* x) { mm_visitP(((Md2H*)x)->m2); mm_visit(((Md2H*)x static void fork_visit(Value* x) { mm_visit (((Fork*)x)->f ); mm_visit(((Fork*)x)->g); mm_visit(((Fork*)x)->h); } static void atop_visit(Value* x) { mm_visit(((Atop*)x)->g); mm_visit(((Atop*)x)->h); } -static void md1D_print(B x) { printf("(md1D ");print(c(Md1D,x)->f);printf(" ");print(tag(c(Md1D,x)->m1,MD1_TAG)); printf(")"); } -static void md2D_print(B x) { printf("(md2D ");print(c(Md2D,x)->f);printf(" ");print(tag(c(Md2D,x)->m2,MD2_TAG));printf(" ");print(c(Md2D,x)->g);printf(")"); } -static void md2H_print(B x) { printf("(md2H "); print(tag(c(Md2H,x)->m2,MD2_TAG));printf(" ");print(c(Md2H,x)->g);printf(")"); } -static void fork_print(B x) { printf("(fork ");print(c(Fork,x)->f);printf(" ");print( c(Fork,x)->g );printf(" ");print(c(Fork,x)->h);printf(")"); } -static void atop_print(B x) { printf("(atop "); print( c(Atop,x)->g );printf(" ");print(c(Atop,x)->h);printf(")"); } +static void md1D_print(FILE* f, B x) { fprintf(f,"(md1D ");fprint(f,c(Md1D,x)->f);fprintf(f," ");fprint(f,tag(c(Md1D,x)->m1,MD1_TAG)); fprintf(f,")"); } +static void md2D_print(FILE* f, B x) { fprintf(f,"(md2D ");fprint(f,c(Md2D,x)->f);fprintf(f," ");fprint(f,tag(c(Md2D,x)->m2,MD2_TAG));fprintf(f," ");fprint(f,c(Md2D,x)->g);fprintf(f,")"); } +static void md2H_print(FILE* f, B x) { fprintf(f,"(md2H "); fprint(f,tag(c(Md2H,x)->m2,MD2_TAG));fprintf(f," ");fprint(f,c(Md2H,x)->g);fprintf(f,")"); } +static void fork_print(FILE* f, B x) { fprintf(f,"(fork ");fprint(f,c(Fork,x)->f);fprintf(f," ");fprint(f, c(Fork,x)->g );fprintf(f," ");fprint(f,c(Fork,x)->h);fprintf(f,")"); } +static void atop_print(FILE* f, B x) { fprintf(f,"(atop "); fprint(f, c(Atop,x)->g );fprintf(f," ");fprint(f,c(Atop,x)->h);fprintf(f,")"); } B md1D_c1(B t, B x) { Md1D* tc = c(Md1D, t); return ((Md1*)tc->m1)->c1(tc, x); } B md1D_c2(B t, B w, B x) { Md1D* tc = c(Md1D, t); return ((Md1*)tc->m1)->c2(tc, w, x); } diff --git a/src/core/fillarr.c b/src/core/fillarr.c index 65f7b16b..a69157b6 100644 --- a/src/core/fillarr.c +++ b/src/core/fillarr.c @@ -64,7 +64,7 @@ void fillarr_init() { TIi(t_fillarr,freeO) = fillarr_freeO; TIi(t_fillslice,freeO) = slice_freeO; TIi(t_fillarr,freeF) = fillarr_freeF; TIi(t_fillslice,freeF) = slice_freeF; TIi(t_fillarr,visit) = fillarr_visit; TIi(t_fillslice,visit) = slice_visit; - TIi(t_fillarr,print) = arr_print; TIi(t_fillslice,print) = arr_print; + TIi(t_fillarr,print) = farr_print; TIi(t_fillslice,print) = farr_print; TIi(t_fillarr,isArr) = true; TIi(t_fillslice,isArr) = true; TIi(t_fillarr,canStore) = fillarr_canStore; } diff --git a/src/core/harr.c b/src/core/harr.c index 66207b74..2f56c6ca 100644 --- a/src/core/harr.c +++ b/src/core/harr.c @@ -139,17 +139,17 @@ static void harrP_visit(Value* x) { assert(x->type == t_harrPartial); for (usz i = 0; i < am; i++) mm_visit(p[i]); } static B harrP_get(Arr* x, usz n) { err("getting item from t_harrPartial"); } -static void harrP_print(B x) { +static void harrP_print(FILE* f, B x) { B* p = c(HArr,x)->a; usz am = *c(HArr,x)->sh; usz ia = a(x)->ia; - printf("(partial HArr "N64d"/"N64d": ⟨", (u64)am, (u64)ia); + fprintf(f, "(partial HArr "N64d"/"N64d": ⟨", (u64)am, (u64)ia); for (usz i = 0; i < ia; i++) { - if (i) printf(", "); - if (i>=am) printf("?"); - else print(p[i]); + if (i) fprintf(f, ", "); + if (i>=am) fprintf(f, "?"); + else fprint(f, p[i]); } - printf("⟩)"); + fprintf(f, "⟩)"); } void harr_init() { @@ -159,7 +159,7 @@ void harr_init() { TIi(t_harr,freeO) = harr_freeO; TIi(t_hslice,freeO) = slice_freeO; TIi(t_harrPartial,freeO) = harrP_freeO; TIi(t_harr,freeF) = harr_freeF; TIi(t_hslice,freeF) = slice_freeF; TIi(t_harrPartial,freeF) = harrP_freeF; TIi(t_harr,visit) = harr_visit; TIi(t_hslice,visit) = slice_visit; TIi(t_harrPartial,visit) = harrP_visit; - TIi(t_harr,print) = arr_print; TIi(t_hslice,print) = arr_print; TIi(t_harrPartial,print) = harrP_print; + TIi(t_harr,print) = farr_print; TIi(t_hslice,print) = farr_print; TIi(t_harrPartial,print) = harrP_print; TIi(t_harr,isArr) = true; TIi(t_hslice,isArr) = true; TIi(t_harr,canStore) = harr_canStore; bi_emptyHVec = m_harrUv(0).b; gc_add(bi_emptyHVec); diff --git a/src/core/stuff.c b/src/core/stuff.c index bc81b34a..4b7a00fd 100644 --- a/src/core/stuff.c +++ b/src/core/stuff.c @@ -91,76 +91,77 @@ NOINLINE TStack* ts_e(TStack* o, u32 elsz, u64 am) { u64 size = o->size; return n; } -NOINLINE void arr_print(B x) { // should accept refc=0 arguments for debugging purposes +void fprint(FILE* f, B x); +void farr_print(FILE* f, B x) { // should accept refc=0 arguments for debugging purposes ur r = rnk(x); SGetU(x) usz ia = a(x)->ia; if (r!=1) { if (r==0) { - printf("<"); - print(GetU(x,0)); + fprintf(f, "<"); + fprint(f, GetU(x,0)); return; } usz* sh = a(x)->sh; for (i32 i = 0; i < r; i++) { - if(i==0)printf(N64d,(u64)sh[i]); - else printf("‿"N64d,(u64)sh[i]); + if(i==0)fprintf(f, N64d,(u64)sh[i]); + else fprintf(f, "‿"N64d,(u64)sh[i]); } - printf("⥊"); + fprintf(f, "⥊"); } else if (ia>0) { for (usz i = 0; i < ia; i++) { B c = GetU(x,i); if (!isC32(c) || (u32)c.u=='\n') goto reg; } - printf("\""); - for (usz i = 0; i < ia; i++) printUTF8((u32)GetU(x,i).u); // c32, no need to decrement - printf("\""); + fprintf(f, "\""); + for (usz i = 0; i < ia; i++) fprintUTF8(f, (u32)GetU(x,i).u); // c32, no need to decrement + fprintf(f, "\""); return; } reg:; - printf("⟨"); + fprintf(f, "⟨"); for (usz i = 0; i < ia; i++) { - if (i!=0) printf(", "); - print(GetU(x,i)); + if (i!=0) fprintf(f, ", "); + fprint(f, GetU(x,i)); } - printf("⟩"); + fprintf(f, "⟩"); } -NOINLINE void print(B x) { +void fprint(FILE* f, B x) { if (isF64(x)) { NUM_FMT_BUF(buf, x.f); - printf("%s", buf); + fprintf(f, "%s", buf); } else if (isC32(x)) { - if ((u32)x.u>=32) { printf("'"); printUTF8((u32)x.u); printf("'"); } - else if((u32)x.u>15) printf("\\x%x", (u32)x.u); - else printf("\\x0%x", (u32)x.u); + if ((u32)x.u>=32) { fprintf(f, "'"); printUTF8((u32)x.u); fprintf(f, "'"); } + else if((u32)x.u>15) fprintf(f, "\\x%x", (u32)x.u); + else fprintf(f, "\\x0%x", (u32)x.u); } else if (isVal(x)) { #ifdef DEBUG if (isVal(x) && (v(x)->type==t_freed || v(x)->type==t_empty)) { u8 t = v(x)->type; v(x)->type = v(x)->flags; - printf(t==t_freed?"FREED:":"EMPTY:"); - TI(x,print)(x); + fprintf(f, t==t_freed?"FREED:":"EMPTY:"); + TI(x,print)(f, x); v(x)->type = t; return; } #endif - TI(x,print)(x); + TI(x,print)(f, x); } - else if (isVar(x)) printf("(var d=%d i=%d)", (u16)(x.u>>32), (i32)x.u); - else if (isExt(x)) printf("(extvar d=%d i=%d)", (u16)(x.u>>32), (i32)x.u); - else if (x.u==bi_N.u) printf("·"); - else if (x.u==bi_optOut.u) printf("(value optimized out)"); - else if (x.u==bi_noVar.u) printf("(unset variable placeholder)"); - else if (x.u==bi_okHdr.u) printf("(accepted SETH placeholder)"); - else if (x.u==bi_noFill.u) printf("(no fill placeholder)"); - else printf("(todo tag "N64x")", x.u>>48); + else if (isVar(x)) fprintf(f, "(var d=%d i=%d)", (u16)(x.u>>32), (i32)x.u); + else if (isExt(x)) fprintf(f, "(extvar d=%d i=%d)", (u16)(x.u>>32), (i32)x.u); + else if (x.u==bi_N.u) fprintf(f, "·"); + else if (x.u==bi_optOut.u) fprintf(f, "(value optimized out)"); + else if (x.u==bi_noVar.u) fprintf(f, "(unset variable placeholder)"); + else if (x.u==bi_okHdr.u) fprintf(f, "(accepted SETH placeholder)"); + else if (x.u==bi_noFill.u) fprintf(f, "(no fill placeholder)"); + else fprintf(f, "(todo tag "N64x")", x.u>>48); } -NOINLINE void printRaw(B x) { +NOINLINE void fprintRaw(FILE* f, B x) { if (isAtm(x)) { - if (isF64(x)) { NUM_FMT_BUF(buf, x.f); printf("%s", buf); } - else if (isC32(x)) printUTF8((u32)x.u); + if (isF64(x)) { NUM_FMT_BUF(buf, x.f); fprintf(f, "%s", buf); } + else if (isC32(x)) fprintUTF8(f, (u32)x.u); else thrM("bad printRaw argument: atom arguments should be either numerical or characters"); } else { usz ia = a(x)->ia; @@ -168,13 +169,24 @@ NOINLINE void printRaw(B x) { for (usz i = 0; i < ia; i++) { B c = GetU(x,i); #if !CATCH_ERRORS - if (c.u==0 || noFill(c)) { printf(" "); continue; } + if (c.u==0 || noFill(c)) { fprintf(f, " "); continue; } #endif if (!isC32(c)) thrM("bad printRaw argument: expected all character items"); - printUTF8((u32)c.u); + fprintUTF8(f, (u32)c.u); } } } + +NOINLINE void printRaw(B x) { + fprintRaw(stdout, x); +} +NOINLINE void arr_print(B x) { + farr_print(stdout, x); +} +NOINLINE void print(B x) { + fprint(stdout, x); +} + i32 num_fmt(char buf[30], f64 x) { // for (int i = 0; i < 30; i++) buf[i] = 'a'; snprintf(buf, 30, "%.16g", x); // should be %.17g to (probably?) never lose precision, but that also makes things ugly diff --git a/src/core/tyarr.c b/src/core/tyarr.c index 85d8b55c..a618429f 100644 --- a/src/core/tyarr.c +++ b/src/core/tyarr.c @@ -124,7 +124,7 @@ static void bitarr_init() { TIi(t_bitarr,freeO) = tyarr_freeO; TIi(t_bitarr,freeF) = tyarr_freeF; TIi(t_bitarr,visit) = noop_visit; - TIi(t_bitarr,print) = arr_print; + TIi(t_bitarr,print) = farr_print; TIi(t_bitarr,isArr) = true; TIi(t_bitarr,arrD1) = true; TIi(t_bitarr,elType) = el_bit; diff --git a/src/core/tyarrTemplate.c b/src/core/tyarrTemplate.c index ab46cd81..ea256560 100644 --- a/src/core/tyarrTemplate.c +++ b/src/core/tyarrTemplate.c @@ -22,7 +22,7 @@ static void TP(,arr_init)() { TIi(T_ARR,freeO) = tyarr_freeO; TIi(T_SLICE,freeO) = slice_freeO; TIi(T_ARR,freeF) = tyarr_freeF; TIi(T_SLICE,freeF) = slice_freeF; TIi(T_ARR,visit) = noop_visit; TIi(T_SLICE,visit) = slice_visit; - TIi(T_ARR,print) = arr_print; TIi(T_SLICE,print) = arr_print; + TIi(T_ARR,print) = farr_print; TIi(T_SLICE,print) = farr_print; TIi(T_ARR,isArr) = true; TIi(T_SLICE,isArr) = true; TIi(T_ARR,arrD1) = true; TIi(T_SLICE,arrD1) = true; TIi(T_ARR,elType) = TP(el_,); TIi(T_SLICE,elType) = TP(el_,); diff --git a/src/h.h b/src/h.h index 76bfc7ac..4731bc7e 100644 --- a/src/h.h +++ b/src/h.h @@ -317,8 +317,11 @@ static void mm_visitP(void* x); static void dec(B x); static B inc(B x); static void ptr_dec(void* x); -void printRaw(B x); // doesn't consume +void fprint (FILE* f, B x); // doesn't consume +void fprintRaw (FILE* f, B x); // doesn't consume +void farr_print(FILE* f, B x); // doesn't consume void print(B x); // doesn't consume +void printRaw(B x); // doesn't consume void arr_print(B x); // doesn't consume bool equal(B w, B x); // doesn't consume bool eequal(B w, B x); // doesn't consume @@ -443,6 +446,7 @@ typedef struct Md2D Md2D; typedef bool (* B2b)(B); typedef void (* B2v)(B); +typedef void (* FB2v)(FILE*, B); typedef Arr* (*BSS2A)(B, usz, usz); typedef B (* AS2B)(Arr*, usz); typedef B (* BS2B)(B, usz); @@ -492,7 +496,7 @@ typedef B (*D2C2)(Md2D*, B, B); F(B2b, canStore) /* doesn't consume */ \ F(u8, elType) /* guarantees that the corresponding i32any_ptr/f64any_ptr/c32any_ptr/… always succeeds */ \ \ - F(B2v, print) /* doesn't consume */ \ + F(FB2v, print) /* doesn't consume */ \ F(V2v, visit) /* call mm_visit for all referents */ \ F(V2v, freeO) /* like freeF, but doesn't call mm_free for GC to be able to clear cycles */ \ F(B2B, decompose) /* consumes; must return a HArr */ \ diff --git a/src/load.c b/src/load.c index 00b309f1..ce882c34 100644 --- a/src/load.c +++ b/src/load.c @@ -505,7 +505,7 @@ static void empty_free(Value* x) { err("FREEING EMPTY\n"); } static void builtin_free(Value* x) { err("FREEING BUILTIN\n"); } DEF_FREE(def) { } static void def_visit(Value* x) { printf("(no visit for %d=%s)\n", x->type, type_repr(x->type)); } -static void def_print(B x) { printf("(%d=%s)", v(x)->type, type_repr(v(x)->type)); } +static void def_print(FILE* f, B x) { fprintf(f, "(%d=%s)", v(x)->type, type_repr(v(x)->type)); } static bool def_canStore(B x) { return false; } static B def_identity(B f) { return bi_N; } static B def_get(Arr* x, usz n) { err("def_get"); } diff --git a/src/main.c b/src/main.c index 3693b3f8..606596c5 100644 --- a/src/main.c +++ b/src/main.c @@ -152,7 +152,7 @@ int main(int argc, char* argv[]) { if (startREPL) { repl_init(); while (CATCH) { - printf("Error: "); printErrMsg(thrownMsg); putchar('\n'); + fprintf(stderr, "Error: "); printErrMsg(thrownMsg); fputc('\n', stderr); vm_pst(envCurr+1, envStart+envPrevHeight); freeThrown(); #ifdef HEAP_VERIFY diff --git a/src/nfns.c b/src/nfns.c index 5e1c0149..43faa9e5 100644 --- a/src/nfns.c +++ b/src/nfns.c @@ -37,10 +37,10 @@ B nfn_name(B x) { VTY(x, t_nfn); DEF_FREE(nfn) { dec(((NFn*)x)->obj); } void nfn_visit(Value* x) { mm_visit(((NFn*)x)->obj); } -void nfn_print(B x) { printRaw(c(NFnDesc,IGetU(nfn_list,c(NFn,x)->id))->name); } +void nfn_print(FILE* f, B x) { fprintRaw(f, c(NFnDesc,IGetU(nfn_list,c(NFn,x)->id))->name); } DEF_FREE(nfnDesc) { err("nfnDesc shouldn't be freed!"); } void nfnDesc_visit(Value* x) { mm_visit(((NFnDesc*)x)->name); } -void nfnDesc_print(B x) { printf("(native function description)"); } +void nfnDesc_print(FILE* f, B x) { fprintf(f, "(native function description)"); } void nfn_gcRoot() { mm_visit(nfn_list); diff --git a/src/ns.c b/src/ns.c index 4dc9c00c..ac954922 100644 --- a/src/ns.c +++ b/src/ns.c @@ -176,8 +176,8 @@ static void ns_visit(Value* x) { mm_visitP(c->desc); mm_visitP(c->sc); } -static void ns_print(B x) { - putchar('{'); +static void ns_print(FILE* f, B x) { + fputc('{', f); NSDesc* desc = c(NS,x)->desc; Scope* sc = c(NS,x)->sc; i32 am = desc->varAm; @@ -186,13 +186,13 @@ static void ns_print(B x) { i32 id = desc->expGIDs[i]; if (id>=0) { if (first) first=false; - else printf(" ⋄ "); - printRaw(gid2str(id)); - printf("⇐"); - print(sc->vars[i]); + else fprintf(f," ⋄ "); + fprintRaw(f, gid2str(id)); + fprintf(f, "⇐"); + fprint(f, sc->vars[i]); } } - putchar('}'); + fputc('}', f); } B nsFmt(B x) { // consumes B s = emptyCVec(); @@ -213,7 +213,7 @@ B nsFmt(B x) { // consumes return s; } -static void nsDesc_print(B x) { printf("(namespace description)"); } +static void nsDesc_print(FILE* f, B x) { fprintf(f, "(namespace description)"); } diff --git a/src/utils/utf.c b/src/utils/utf.c index 0ebda2c1..9445cdf3 100644 --- a/src/utils/utf.c +++ b/src/utils/utf.c @@ -61,6 +61,12 @@ void printUTF8(u32 c) { else if (c<=0xFFFF) printf("%c%c%c" , 0xE0| c>>12, 0x80|(c>>6 &0x3F), 0x80|(c &0x3F) ); else printf("%c%c%c%c", 0xF0| c>>18, 0x80|(c>>12&0x3F), 0x80|(c>>6&0x3F), 0x80|(c&0x3F)); } +void fprintUTF8(FILE* f, u32 c) { + if (c<128) fprintf(f, "%c", c); + else if (c<=0x07FF) fprintf(f, "%c%c" , 0xC0| c>>6 , 0x80|(c &0x3F) ); + else if (c<=0xFFFF) fprintf(f, "%c%c%c" , 0xE0| c>>12, 0x80|(c>>6 &0x3F), 0x80|(c &0x3F) ); + else fprintf(f, "%c%c%c%c", 0xF0| c>>18, 0x80|(c>>12&0x3F), 0x80|(c>>6&0x3F), 0x80|(c&0x3F)); +} u64 utf8lenB(B x) { // doesn't consume; may error as it verifies whether is all chars diff --git a/src/utils/utf.h b/src/utils/utf.h index c8ff588e..92b466ec 100644 --- a/src/utils/utf.h +++ b/src/utils/utf.h @@ -4,6 +4,7 @@ B fromUTF8(char* s, i64 len); B fromUTF8l(char* s); void printUTF8(u32 c); +void fprintUTF8(FILE* f, u32 c); u64 utf8lenB(B x); // doesn't consume; may error as it verifies whether is all chars void toUTF8(B x, char* p); // doesn't consume; doesn't verify anything; p must have utf8lenB(x) bytes (calculating which should verify that this call is ok), add trailing null yourself diff --git a/src/vm.c b/src/vm.c index d543a622..356b558d 100644 --- a/src/vm.c +++ b/src/vm.c @@ -946,24 +946,24 @@ void vfymO_visit(Value* x) { mm_visit(((VfyObj* )x)->obj); } void bBlks_visit(Value* x) { BlBlocks* c = (BlBlocks*)x; u16 am = c->am; for (i32 i = 0; i < am; i++) mm_visitP(c->a[i]); } void scExt_visit(Value* x) { ScopeExt* c = (ScopeExt*)x; u16 am = c->varAm*2; for (i32 i = 0; i < am; i++) mm_visit(c->vars[i]); } -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 block_print(B x) { printf("(%p: block)",v(x)); } -void scope_print(B x) { printf("(%p: scope; vars:",v(x));Scope*sc=c(Scope,x);for(u64 i=0;ivarAm;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 vfymO_print(B x) { print(c(FldAlias,x)->obj); } -void bBlks_print(B x) { printf("(block list)"); } -void scExt_print(B x) { printf("(scope extension with %d vars)", c(ScopeExt,x)->varAm); } +void comp_print (FILE* f, B x) { fprintf(f,"(%p: comp)",v(x)); } +void body_print (FILE* f, B x) { fprintf(f,"(%p: body varam=%d)",v(x),c(Body,x)->varAm); } +void block_print(FILE* f, B x) { fprintf(f,"(%p: block)",v(x)); } +void scope_print(FILE* f, B x) { fprintf(f,"(%p: scope; vars:",v(x));Scope*sc=c(Scope,x);for(u64 i=0;ivarAm;i++){fprintf(f," ");fprint(f,sc->vars[i]);}fprintf(f,")"); } +void alias_print(FILE* f, B x) { fprintf(f,"(alias %d of ", c(FldAlias,x)->p); fprint(f,c(FldAlias,x)->obj); fprintf(f,")"); } +void vfymO_print(FILE* f, B x) { fprint(f,c(FldAlias,x)->obj); } +void bBlks_print(FILE* f, B x) { fprintf(f,"(block list)"); } +void scExt_print(FILE* f, B x) { fprintf(f,"(scope extension with %d vars)", c(ScopeExt,x)->varAm); } -// 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 md2Bl_print(B x) { printf("(%p: 2-modifier block bl=%p sc=%p)",v(x),c(Md2Block,x)->bl,c(Md2Block,x)->sc); } -// void funBl_print(B x) { printf("(function"" block @%d)",c(FunBlock,x)->bl->body->map[0]); } -// void md1Bl_print(B x) { printf("(1-modifier block @%d)",c(Md1Block,x)->bl->body->map[0]); } -// void md2Bl_print(B x) { printf("(2-modifier block @%d)",c(Md2Block,x)->bl->body->map[0]); } -void funBl_print(B x) { printf("{function"" block}"); } -void md1Bl_print(B x) { printf("{1-modifier block}"); } -void md2Bl_print(B x) { printf("{2-modifier block}"); } +// void funBl_print(FILE* f, B x) { fprintf(f,"(%p: function"" block bl=%p sc=%p)",v(x),c(FunBlock,x)->bl,c(FunBlock,x)->sc); } +// void md1Bl_print(FILE* f, B x) { fprintf(f,"(%p: 1-modifier block bl=%p sc=%p)",v(x),c(Md1Block,x)->bl,c(Md1Block,x)->sc); } +// void md2Bl_print(FILE* f, B x) { fprintf(f,"(%p: 2-modifier block bl=%p sc=%p)",v(x),c(Md2Block,x)->bl,c(Md2Block,x)->sc); } +// void funBl_print(FILE* f, B x) { fprintf(f,"(function"" block @%d)",c(FunBlock,x)->bl->body->map[0]); } +// void md1Bl_print(FILE* f, B x) { fprintf(f,"(1-modifier block @%d)",c(Md1Block,x)->bl->body->map[0]); } +// void md2Bl_print(FILE* f, B x) { fprintf(f,"(2-modifier block @%d)",c(Md2Block,x)->bl->body->map[0]); } +void funBl_print(FILE* f, B x) { fprintf(f,"{function"" block}"); } +void md1Bl_print(FILE* f, B x) { fprintf(f,"{1-modifier block}"); } +void md2Bl_print(FILE* f, B x) { fprintf(f,"{2-modifier block}"); } B block_decompose(B x) { return m_hVec2(m_i32(1), x); } @@ -1147,28 +1147,28 @@ NOINLINE void vm_printPos(Comp* comp, i32 bcPos, i64 pos) { // printf(" inds:%d…%d\n", cs, ce); if (CATCH) { // want to try really hard to print errors freeThrown(); - int start = printf("at "); + int start = fprintf(stderr, "at "); usz srcL = a(src)->ia; SGetU(src) usz srcS = cs; while (srcS>0 && o2cu(GetU(src,srcS-1))!='\n') srcS--; usz srcE = srcS; while (srcEsrcE) ce = srcE; cs-= srcS; ce-= srcS; - putchar('\n'); - for (i32 i = 0; i < cs+start; i++) putchar(' '); - for (i32 i = cs; i < ce; i++) putchar('^'); - putchar('\n'); + fputc('\n', stderr); + for (i32 i = 0; i < cs+start; i++) fputc(' ', stderr); + for (i32 i = cs; i < ce; i++) fputc('^', stderr); + fputc('\n', stderr); return; } B s = emptyCVec(); - printRaw(vm_fmtPoint(src, s, comp->path, cs, ce)); - putchar('\n'); + fprintRaw(stderr, vm_fmtPoint(src, s, comp->path, cs, ce)); + fputc('\n', stderr); popCatch(); //print_BCStream((u32*)i32arr_ptr(comp->bc)+bcPos); } else { #ifdef DEBUG - if (pos!=-1) printf(N64d": ", pos); - printf("source unknown\n"); + if (pos!=-1) fprintf(stderr, N64d": ", pos); + fprintf(stderr, "source unknown\n"); #endif } } @@ -1180,7 +1180,7 @@ NOINLINE void vm_pst(Env* s, Env* e) { // e not included while (i>=0) { Env* c = s+i; if (l>30 && i==l-10) { - printf("("N64d" entries omitted)\n", l-20); + fprintf(stderr, "("N64d" entries omitted)\n", l-20); i = 10; } Comp* comp = c->sc->body->bl->comp; @@ -1213,11 +1213,11 @@ NOINLINE void printErrMsg(B msg) { SGetU(msg) usz msgLen = a(msg)->ia; for (usz i = 0; i < msgLen; i++) if (!isC32(GetU(msg,i))) goto base; - printRaw(msg); + fprintRaw(stderr,msg); return; } base: - print(msg); + fprint(stderr, msg); } @@ -1240,7 +1240,7 @@ NOINLINE NORETURN void throwImpl(bool rethrow) { longjmp(cf->jmp, 1); } else { // uncaught error assert(cf==cfStart); - printf("Error: "); printErrMsg(thrownMsg); putchar('\n'); fflush(stdout); + fprintf(stderr, "Error: "); printErrMsg(thrownMsg); fputc('\n',stderr); fflush(stderr); Env* envEnd = envCurr+1; unwindEnv(envStart-1); vm_pst(envCurr+1, envEnd);