From 174ff879466ba39574f5082a309b5e29138c9233 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Thu, 16 Jan 2020 18:10:17 -0600 Subject: [PATCH 1/3] Change printing of abstracts with tostring in pp This change makes pretty printing not hide "abstractness". --- src/boot/boot.janet | 2 +- src/core/pp.c | 93 +++++++++++++++++++++++++-------------------- 2 files changed, 53 insertions(+), 42 deletions(-) diff --git a/src/boot/boot.janet b/src/boot/boot.janet index 6d8f5625..7613e5a9 100644 --- a/src/boot/boot.janet +++ b/src/boot/boot.janet @@ -224,7 +224,7 @@ r (gensym)] ~(let [,f (,fiber/new (fn [] ,body) :ie) ,r (,resume ,f)] - (if (= (,fiber/status ,f) :error) + (if (,= (,fiber/status ,f) :error) (do (def ,err ,r) ,(if fib ~(def ,fib ,f)) ,;(tuple/slice catch 1)) ,r)))) diff --git a/src/core/pp.c b/src/core/pp.c index 07b3f549..7516e3b8 100644 --- a/src/core/pp.c +++ b/src/core/pp.c @@ -181,49 +181,43 @@ static void janet_escape_buffer_b(JanetBuffer *buffer, JanetBuffer *bx) { janet_escape_string_impl(buffer, bx->data, bx->count); } -void janet_description_b(JanetBuffer *buffer, Janet x) { +void janet_to_string_b(JanetBuffer *buffer, Janet x) { switch (janet_type(x)) { case JANET_NIL: janet_buffer_push_cstring(buffer, "nil"); - return; + break; case JANET_BOOLEAN: janet_buffer_push_cstring(buffer, janet_unwrap_boolean(x) ? "true" : "false"); - return; + break; case JANET_NUMBER: number_to_string_b(buffer, janet_unwrap_number(x)); - return; - case JANET_KEYWORD: - janet_buffer_push_u8(buffer, ':'); - /* fallthrough */ + break; + case JANET_STRING: case JANET_SYMBOL: + case JANET_KEYWORD: janet_buffer_push_bytes(buffer, janet_unwrap_string(x), janet_string_length(janet_unwrap_string(x))); - return; - case JANET_STRING: - janet_escape_string_b(buffer, janet_unwrap_string(x)); - return; + break; case JANET_BUFFER: { - JanetBuffer *b = janet_unwrap_buffer(x); - if (b == buffer) { - /* Ensures buffer won't resize while escaping */ - janet_buffer_ensure(b, 5 * b->count + 3, 1); - } - janet_escape_buffer_b(buffer, b); - return; + JanetBuffer *to = janet_unwrap_buffer(x); + /* Prevent resizing buffer while appending */ + if (buffer == to) janet_buffer_extra(buffer, to->count); + janet_buffer_push_bytes(buffer, to->data, to->count); + break; } - case JANET_ABSTRACT: { - void *p = janet_unwrap_abstract(x); - const JanetAbstractType *at = janet_abstract_type(p); - if (at->tostring) { - at->tostring(p, buffer); - } else { - const char *n = at->name; - string_description_b(buffer, n, janet_unwrap_abstract(x)); + case JANET_ABSTRACT: + { + JanetAbstract p = janet_unwrap_abstract(x); + const JanetAbstractType *t = janet_abstract_type(p); + if (t->tostring != NULL) { + t->tostring(p, buffer); + } else { + string_description_b(buffer, t->name, p); + } } return; - } case JANET_CFUNCTION: { Janet check = janet_table_get(janet_vm_registry, x); if (janet_checktype(check, JANET_SYMBOL)) { @@ -255,26 +249,43 @@ void janet_description_b(JanetBuffer *buffer, Janet x) { } } -void janet_to_string_b(JanetBuffer *buffer, Janet x) { + +void janet_description_b(JanetBuffer *buffer, Janet x) { switch (janet_type(x)) { default: - janet_description_b(buffer, x); break; - case JANET_BUFFER: { - JanetBuffer *to = janet_unwrap_buffer(x); - /* Prevent resizing buffer while appending */ - if (buffer == to) janet_buffer_extra(buffer, to->count); - janet_buffer_push_bytes(buffer, to->data, to->count); - break; - } - case JANET_STRING: - case JANET_SYMBOL: case JANET_KEYWORD: - janet_buffer_push_bytes(buffer, - janet_unwrap_string(x), - janet_string_length(janet_unwrap_string(x))); + janet_buffer_push_u8(buffer, ':'); break; + case JANET_STRING: + janet_escape_string_b(buffer, janet_unwrap_string(x)); + return; + case JANET_BUFFER: { + JanetBuffer *b = janet_unwrap_buffer(x); + if (b == buffer) { + /* Ensures buffer won't resize while escaping */ + janet_buffer_ensure(b, 5 * b->count + 3, 1); + } + janet_escape_buffer_b(buffer, b); + return; + } + case JANET_ABSTRACT: + { + JanetAbstract p = janet_unwrap_abstract(x); + const JanetAbstractType *t = janet_abstract_type(p); + if (t->tostring != NULL) { + janet_buffer_push_cstring(buffer, "<"); + janet_buffer_push_cstring(buffer, t->name); + janet_buffer_push_cstring(buffer, " "); + t->tostring(p, buffer); + janet_buffer_push_cstring(buffer, ">"); + } else { + string_description_b(buffer, t->name, p); + } + return; + } } + janet_to_string_b(buffer, x); } const uint8_t *janet_description(Janet x) { From 6d9e51e4be05a92b97c4b1c2663695b1c393ac23 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Thu, 16 Jan 2020 18:12:05 -0600 Subject: [PATCH 2/3] Fix documentation for if-with. It was the same as when-with. --- src/boot/boot.janet | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/boot/boot.janet b/src/boot/boot.janet index 7613e5a9..18f6b5ff 100644 --- a/src/boot/boot.janet +++ b/src/boot/boot.janet @@ -313,8 +313,9 @@ ,;body))) (defmacro if-with - "Similar to with, but if binding is false or nil, returns - nil without evaluating the body. Otherwise, the same as with." + "Similar to with, but if binding is false or nil, evaluates + the falsey path. Otherwise, evaluates the truthy path. In both cases, + ctor is bound to binding." [[binding ctor dtor] truthy &opt falsey ] ~(if-let [,binding ,ctor] (defer (,(or dtor :close) ,binding) ,truthy) From 77bb0ebe3fa6f222f01311c7346fb38f679ab457 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Thu, 16 Jan 2020 18:57:01 -0600 Subject: [PATCH 3/3] Add limits to format to discourage huge prints. This should make system crashing prints happen less often in repl. Instead, display a ... --- src/core/pp.c | 92 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 32 deletions(-) diff --git a/src/core/pp.c b/src/core/pp.c index 7516e3b8..56a36f08 100644 --- a/src/core/pp.c +++ b/src/core/pp.c @@ -207,17 +207,16 @@ void janet_to_string_b(JanetBuffer *buffer, Janet x) { janet_buffer_push_bytes(buffer, to->data, to->count); break; } - case JANET_ABSTRACT: - { - JanetAbstract p = janet_unwrap_abstract(x); - const JanetAbstractType *t = janet_abstract_type(p); - if (t->tostring != NULL) { - t->tostring(p, buffer); - } else { - string_description_b(buffer, t->name, p); - } + case JANET_ABSTRACT: { + JanetAbstract p = janet_unwrap_abstract(x); + const JanetAbstractType *t = janet_abstract_type(p); + if (t->tostring != NULL) { + t->tostring(p, buffer); + } else { + string_description_b(buffer, t->name, p); } - return; + } + return; case JANET_CFUNCTION: { Janet check = janet_table_get(janet_vm_registry, x); if (janet_checktype(check, JANET_SYMBOL)) { @@ -269,21 +268,20 @@ void janet_description_b(JanetBuffer *buffer, Janet x) { janet_escape_buffer_b(buffer, b); return; } - case JANET_ABSTRACT: - { - JanetAbstract p = janet_unwrap_abstract(x); - const JanetAbstractType *t = janet_abstract_type(p); - if (t->tostring != NULL) { - janet_buffer_push_cstring(buffer, "<"); - janet_buffer_push_cstring(buffer, t->name); - janet_buffer_push_cstring(buffer, " "); - t->tostring(p, buffer); - janet_buffer_push_cstring(buffer, ">"); - } else { - string_description_b(buffer, t->name, p); - } - return; + case JANET_ABSTRACT: { + JanetAbstract p = janet_unwrap_abstract(x); + const JanetAbstractType *t = janet_abstract_type(p); + if (t->tostring != NULL) { + janet_buffer_push_cstring(buffer, "<"); + janet_buffer_push_cstring(buffer, t->name); + janet_buffer_push_cstring(buffer, " "); + t->tostring(p, buffer); + janet_buffer_push_cstring(buffer, ">"); + } else { + string_description_b(buffer, t->name, p); } + return; + } } janet_to_string_b(buffer, x); } @@ -342,6 +340,7 @@ static void print_newline(struct pretty *S, int just_a_space) { /* Color coding for types */ static const char janet_cycle_color[] = "\x1B[36m"; +static const char janet_class_color[] = "\x1B[34m"; static const char *janet_pretty_colors[] = { "\x1B[32m", "\x1B[36m", @@ -363,6 +362,8 @@ static const char *janet_pretty_colors[] = { #define JANET_PRETTY_DICT_ONELINE 4 #define JANET_PRETTY_IND_ONELINE 10 +#define JANET_PRETTY_DICT_LIMIT 16 +#define JANET_PRETTY_ARRAY_LIMIT 16 /* Helper for pretty printing */ static void janet_pretty_one(struct pretty *S, Janet x, int is_dict_value) { @@ -429,9 +430,22 @@ static void janet_pretty_one(struct pretty *S, Janet x, int is_dict_value) { if (!isarray && !(S->flags & JANET_PRETTY_ONELINE) && len >= JANET_PRETTY_IND_ONELINE) janet_buffer_push_u8(S->buffer, ' '); if (is_dict_value && len >= JANET_PRETTY_IND_ONELINE) print_newline(S, 0); - for (i = 0; i < len; i++) { - if (i) print_newline(S, len < JANET_PRETTY_IND_ONELINE); - janet_pretty_one(S, arr[i], 0); + if (len > JANET_PRETTY_ARRAY_LIMIT) { + for (i = 0; i < 3; i++) { + if (i) print_newline(S, 0); + janet_pretty_one(S, arr[i], 0); + } + print_newline(S, 0); + janet_buffer_push_cstring(S->buffer, "..."); + for (i = 0; i < 3; i++) { + print_newline(S, 0); + janet_pretty_one(S, arr[len - 3 + i], 0); + } + } else { + for (i = 0; i < len; i++) { + if (i) print_newline(S, len < JANET_PRETTY_IND_ONELINE); + janet_pretty_one(S, arr[i], 0); + } } } S->indent -= 2; @@ -449,10 +463,17 @@ static void janet_pretty_one(struct pretty *S, Janet x, int is_dict_value) { JanetTable *t = janet_unwrap_table(x); JanetTable *proto = t->proto; if (NULL != proto) { - Janet name = janet_table_get(proto, janet_csymbolv(":name")); - if (janet_checktype(name, JANET_SYMBOL)) { - const uint8_t *sym = janet_unwrap_symbol(name); - janet_buffer_push_bytes(S->buffer, sym, janet_string_length(sym)); + Janet name = janet_table_get(proto, janet_ckeywordv("name")); + const uint8_t *n; + int32_t len; + if (janet_bytes_view(name, &n, &len)) { + if (S->flags & JANET_PRETTY_COLOR) { + janet_buffer_push_cstring(S->buffer, janet_class_color); + } + janet_buffer_push_bytes(S->buffer, n, len); + if (S->flags & JANET_PRETTY_COLOR) { + janet_buffer_push_cstring(S->buffer, "\x1B[0m"); + } } } janet_buffer_push_cstring(S->buffer, "{"); @@ -466,8 +487,9 @@ static void janet_pretty_one(struct pretty *S, Janet x, int is_dict_value) { int32_t i = 0, len = 0, cap = 0; int first_kv_pair = 1; const JanetKV *kvs = NULL; + int counter = 0; janet_dictionary_view(x, &kvs, &len, &cap); - if (!istable && len >= JANET_PRETTY_DICT_ONELINE) + if (!istable && !(S->flags & JANET_PRETTY_ONELINE) && len >= JANET_PRETTY_DICT_ONELINE) janet_buffer_push_u8(S->buffer, ' '); if (is_dict_value && len >= JANET_PRETTY_DICT_ONELINE) print_newline(S, 0); for (i = 0; i < cap; i++) { @@ -480,6 +502,12 @@ static void janet_pretty_one(struct pretty *S, Janet x, int is_dict_value) { janet_pretty_one(S, kvs[i].key, 0); janet_buffer_push_u8(S->buffer, ' '); janet_pretty_one(S, kvs[i].value, 1); + counter++; + if (counter == 10) { + print_newline(S, 0); + janet_buffer_push_cstring(S->buffer, "..."); + break; + } } } }