Skip to content

Commit 4a8df96

Browse files
committed
inspect charlists
1 parent 2e03506 commit 4a8df96

File tree

4 files changed

+67
-10
lines changed

4 files changed

+67
-10
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
## Unreleased
44

5+
- The `inspect` function in the `string` module will now print lists of ascii
6+
characters in a human readable format, to aid with debugging programs that use
7+
Erlang character lists.
58
- The deprecated `debug` function in the `io` module has been removed.
69
- The deprecated `from` function in the `dynamic` module has been removed.
710

src/gleam_stdlib.erl

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,14 @@
2727
((X) >= $a) andalso ((X) =< $f) -> (X) - $a + 10
2828
end).
2929

30-
-define(is_lowercase_char(X), (X > 96 andalso X < 123)).
31-
-define(is_underscore_char(X), (X == 95)).
32-
-define(is_digit_char(X), (X > 47 andalso X < 58)).
30+
-define(is_lowercase_char(X),
31+
(X > 96 andalso X < 123)).
32+
-define(is_underscore_char(X),
33+
(X == 95)).
34+
-define(is_digit_char(X),
35+
(X > 47 andalso X < 58)).
36+
-define(is_ascii_character(X),
37+
(erlang:is_integer(X) andalso X >= 32 andalso X =< 126)).
3338

3439
uppercase(X) -> X - 32.
3540

@@ -289,7 +294,8 @@ inspect(Binary) when is_binary(Binary) ->
289294
inspect(Bits) when is_bitstring(Bits) ->
290295
inspect_bit_array(Bits);
291296
inspect(List) when is_list(List) ->
292-
case inspect_list(List) of
297+
case inspect_list(List, true) of
298+
{charlist, _} -> ["charlist.from_string(\"", list_to_binary(List), "\")"];
293299
{proper, Elements} -> ["[", Elements, "]"];
294300
{improper, Elements} -> ["//erl([", Elements, "])"]
295301
end;
@@ -356,14 +362,17 @@ inspect_maybe_gleam_atom(A, B, C) ->
356362
erlang:display({A, B, C}),
357363
throw({gleam_error, A, B, C}).
358364

359-
inspect_list([]) ->
365+
inspect_list([], _) ->
360366
{proper, []};
361-
inspect_list([First]) ->
367+
inspect_list([First], true) when ?is_ascii_character(First) ->
368+
{charlist, nil};
369+
inspect_list([First], _) ->
362370
{proper, [inspect(First)]};
363-
inspect_list([First | Rest]) when is_list(Rest) ->
364-
{Kind, Inspected} = inspect_list(Rest),
371+
inspect_list([First | Rest], ValidCharlist) when is_list(Rest) ->
372+
StillValidCharlist = ValidCharlist andalso ?is_ascii_character(First),
373+
{Kind, Inspected} = inspect_list(Rest, StillValidCharlist),
365374
{Kind, [inspect(First), <<", ">> | Inspected]};
366-
inspect_list([First | ImproperTail]) ->
375+
inspect_list([First | ImproperTail], _) ->
367376
{improper, [inspect(First), <<" | ">>, inspect(ImproperTail)]}.
368377

369378
inspect_bit_array(Bits) ->

src/gleam_stdlib.mjs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
toBitArray,
1010
bitArraySlice,
1111
NonEmpty,
12+
Empty,
1213
CustomType,
1314
} from "./gleam.mjs";
1415
import { Some, None } from "./gleam/option.mjs";
@@ -780,7 +781,37 @@ function inspectCustomType(record) {
780781
}
781782

782783
export function inspectList(list) {
783-
return `[${list.toArray().map(inspect).join(", ")}]`;
784+
if (list instanceof Empty) {
785+
return "[]";
786+
}
787+
788+
let char_out = 'charlist.from_string("';
789+
let list_out = "[";
790+
791+
let current = list;
792+
while (current instanceof NonEmpty) {
793+
let element = current.head;
794+
current = current.tail;
795+
796+
if (list_out !== "[") {
797+
list_out += ", ";
798+
}
799+
list_out += inspect(element);
800+
801+
if (char_out) {
802+
if (Number.isInteger(element) && element >= 32 && element <= 126) {
803+
char_out += String.fromCharCode(element);
804+
} else {
805+
char_out = null;
806+
}
807+
}
808+
}
809+
810+
if (char_out) {
811+
return char_out + '")';
812+
} else {
813+
return list_out + "]";
814+
}
784815
}
785816

786817
export function inspectUtfCodepoint(codepoint) {

test/gleam/string_test.gleam

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,20 @@ pub fn inspect_test() {
12181218
|> should.equal("<<255, 2, 0>>")
12191219
}
12201220

1221+
pub fn inspect_charlist_test() {
1222+
let list = [
1223+
70, 97, 105, 108, 101, 100, 32, 116, 111, 32, 108, 111, 97, 100, 32, 78, 73,
1224+
70, 32, 108, 105, 98, 114, 97, 114, 121, 58, 32, 39, 47, 114, 117, 110, 47,
1225+
99, 117, 114, 114, 101, 110, 116, 45, 115, 121, 115, 116, 101, 109, 47, 115,
1226+
119, 47, 115, 104, 97, 114, 101, 47, 110, 105, 120, 45, 108, 100, 47, 108,
1227+
105, 98, 47, 108, 105, 98, 99, 114, 121, 112, 116, 111, 46, 115, 111, 46, 51,
1228+
]
1229+
string.inspect(list)
1230+
|> should.equal(
1231+
"charlist.from_string(\"Failed to load NIF library: '/run/current-system/sw/share/nix-ld/lib/libcrypto.so.3\")",
1232+
)
1233+
}
1234+
12211235
@target(javascript)
12221236
pub fn target_inspect_test() {
12231237
// Due to Erlang's internal representation, on Erlang this passes, instead:

0 commit comments

Comments
 (0)