From a9c70d9d729b1a4e396f37ff6466a2608a395a2c Mon Sep 17 00:00:00 2001 From: dzaima Date: Mon, 9 Jan 2023 01:14:33 +0200 Subject: [PATCH] printing method overhaul --- src/builtins/sysfn.c | 3 ++- src/core/stuff.c | 44 +++++++++++++++----------------------------- src/utils/utf.c | 39 ++++++++++++++++++++++++++++++++------- src/utils/utf.h | 6 ++++-- src/vm.c | 7 +++++-- 5 files changed, 58 insertions(+), 41 deletions(-) diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index 27b1af91..ead2c4c6 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -252,7 +252,8 @@ B casrt_c1(B t, B x) { B sys_c1(B t, B x); B out_c1(B t, B x) { - if (isArr(x) && RNK(x)>1) thrF("•Out: Argument cannot have rank %i", RNK(x)); + if (isAtm(x)) thrM("•Out: Argument must be a list"); + if (RNK(x)>1) thrF("•Out: Argument cannot have rank %i", RNK(x)); printRaw(x); putchar('\n'); return x; } diff --git a/src/core/stuff.c b/src/core/stuff.c index 778aeb32..256befa6 100644 --- a/src/core/stuff.c +++ b/src/core/stuff.c @@ -95,7 +95,6 @@ NOINLINE TStack* ts_e(TStack* o, u32 elsz, u64 am) { u64 size = o->size; return n; } -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) @@ -108,27 +107,29 @@ void farr_print(FILE* f, B x) { // should accept refc=0 arguments for debugging } usz* sh = SH(x); for (i32 i = 0; i < r; i++) { - if(i==0)fprintf(f, N64d,(u64)sh[i]); - else fprintf(f, "‿"N64d,(u64)sh[i]); + if(i!=0) fprintCodepoint(f, U'‿'); + fprintf(f, N64d, (u64)sh[i]); } - fprintf(f, "⥊"); + fprintCodepoint(f, U'⥊'); } 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; + if (!elChr(TI(x,elType))) { + for (usz i = 0; i < ia; i++) { + B c = GetU(x, i); + if (!isC32(c) || o2cG(c)<32) goto reg; + } } fprintf(f, "\""); - for (usz i = 0; i < ia; i++) fprintUTF8(f, (u32)GetU(x,i).u); // c32, no need to decrement + fprintsB(f, x); fprintf(f, "\""); return; } reg:; - fprintf(f, "⟨"); + fprintCodepoint(f, U'⟨'); for (usz i = 0; i < ia; i++) { if (i!=0) fprintf(f, ", "); fprint(f, GetU(x,i)); } - fprintf(f, "⟩"); + fprintCodepoint(f, U'⟩'); } void fprint(FILE* f, B x) { @@ -136,9 +137,9 @@ void fprint(FILE* f, B x) { NUM_FMT_BUF(buf, x.f); fprintf(f, "%s", buf); } else if (isC32(x)) { - if ((u32)x.u>=32) { fprintf(f, "'"); fprintUTF8(f, (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); + if (o2cG(x)>=32) fprintsU32(f, (u32[3]){'\'', o2cG(x), '\''}, 3); + else if (o2cG(x)>=16) fprintf(f, "\\x%x", o2cG(x)); + else fprintf(f, "\\x0%x", o2cG(x)); } else if (isVal(x)) { #ifdef DEBUG if (isVal(x) && (TY(x)==t_freed || TY(x)==t_empty)) { @@ -163,22 +164,7 @@ void fprint(FILE* f, B x) { } NOINLINE void fprintRaw(FILE* f, B x) { - if (isAtm(x)) { - if (isF64(x)) { NUM_FMT_BUF(buf, x.f); fprintf(f, "%s", buf); } - else if (isC32(x)) fprintUTF8(f, (u32)x.u); - else thrM("•Out: Unexpected argument type"); - } else { - usz ia = IA(x); - SGetU(x) - for (usz i = 0; i < ia; i++) { - B c = GetU(x,i); - #if !CATCH_ERRORS - if (c.u==0 || noFill(c)) { fprintf(f, " "); continue; } - #endif - if (!isC32(c)) thrM("•Out: Unexpected element in argument"); - fprintUTF8(f, (u32)c.u); - } - } + fprintsB(f, x); } NOINLINE void printRaw(B x) { diff --git a/src/utils/utf.c b/src/utils/utf.c index 1cb77491..bf528b74 100644 --- a/src/utils/utf.c +++ b/src/utils/utf.c @@ -53,20 +53,45 @@ B utf8DecodeA(I8Arr* a) { // consumes a return r; } -void printUTF8(u32 c) { - if (c<128) printf("%c", c); - else if (c<=0x07FF) printf("%c%c" , 0xC0| c>>6 , 0x80|(c &0x3F) ); - 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) { +void fprintCodepoint(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)); } +void fprintsU32(FILE* f, u32* s, usz len) { + for (usz i = 0; i < len; i++) fprintCodepoint(f, s[i]); +} +void fprintsB(FILE* f, B x) { + u8 xe = TI(x,elType); + usz ia = IA(x); + if (ia==0) return; + if (xe==el_c32) { + fprintsU32(f, c32any_ptr(x), ia); + } else { + incG(x); + if (!elChr(xe)) { x=chr_squeeze(x); xe=TI(x,elType); } + if (!elChr(xe)) { + #if !CATCH_ERRORS + SGetU(x) + for (usz i = 0; i < ia; i++) { + B c = GetU(x, i); + if (isC32(c)) fprintCodepoint(f, o2cG(c)); + else if (c.u==0 || noFill(c)) fprintf(f, " "); + else thrM("Trying to output non-character"); + } + return; + #endif + thrM("Trying to output non-character"); + } + x = taga(cpyC32Arr(x)); + fprintsU32(f, c32any_ptr(x), ia); + decG(x); + } +} + u64 utf8lenB(B x) { // doesn't consume; may error as it verifies whether is all chars assert(isArr(x)); SGetU(x) diff --git a/src/utils/utf.h b/src/utils/utf.h index b66ab547..eccbad29 100644 --- a/src/utils/utf.h +++ b/src/utils/utf.h @@ -1,7 +1,9 @@ #pragma once -void printUTF8(u32 c); -void fprintUTF8(FILE* f, u32 c); +void fprintCodepoint(FILE* f, u32 v); // single codepoint +void fprintsUTF8(FILE* f, char* s); // UTF-8, null-terminated +void fprintsU32(FILE* f, u32* s, usz len); // unicode codepoints +void fprintsB(FILE* f, B x); // codepoints of x; doesn't consume; assumes argument is an array, doesn't care about rank, throws if its elements are not characters 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 005ff9f0..98b12123 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1339,6 +1339,9 @@ NOINLINE void vm_printPos(Comp* comp, i32 bcPos, i64 pos) { // want to try really hard to print errors if (!cbqn_initialized) goto native_print; + #if FORCE_NATIVE_ERROR_PRINT + goto native_print; + #endif if (CATCH) goto native_print; B s = emptyCVec(); @@ -1355,7 +1358,7 @@ native_print: usz srcL = IA(src); SGetU(src) usz srcS = cs; while (srcS>0 && o2cG(GetU(src,srcS-1))!='\n') srcS--; - usz srcE = srcS; while (srcEsrcE) ce = srcE; cs-= srcS; ce-= srcS; fputc('\n', stderr); @@ -1598,7 +1601,7 @@ NOINLINE void printErrMsg(B msg) { SGetU(msg) usz msgLen = IA(msg); for (usz i = 0; i < msgLen; i++) if (!isC32(GetU(msg,i))) goto base; - fprintRaw(stderr,msg); + fprintRaw(stderr, msg); return; } base: