Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

gleam / compiler-core / templates / echo.erl
7.2 kB 210 lines
1-define(is_lowercase_char(X), 2 (X > 96 andalso X < 123)). 3 4-define(is_underscore_char(X), 5 (X == 95)). 6 7-define(is_digit_char(X), 8 (X > 47 andalso X < 58)). 9 10-define(is_ascii_character(X), 11 (erlang:is_integer(X) andalso X >= 32 andalso X =< 126)). 12 13-define(could_be_record(Tuple), 14 erlang:is_tuple(Tuple) andalso 15 erlang:is_atom(erlang:element(1, Tuple)) andalso 16 erlang:element(1, Tuple) =/= false andalso 17 erlang:element(1, Tuple) =/= true andalso 18 erlang:element(1, Tuple) =/= nil 19). 20-define(is_atom_char(C), 21 (?is_lowercase_char(C) orelse 22 ?is_underscore_char(C) orelse 23 ?is_digit_char(C)) 24). 25 26-define(grey, "\e[90m"). 27-define(reset_color, "\e[39m"). 28 29echo(Value, Message, Filepath, Line) -> 30 StringLine = erlang:integer_to_list(Line), 31 StringValue = echo@inspect(Value), 32 StringMessage = 33 case Message of 34 nil -> ""; 35 M -> [" ", M] 36 end, 37 38 io:put_chars( 39 standard_error, 40 [ 41 ?grey, Filepath, $:, StringLine, ?reset_color, StringMessage, $\n, 42 StringValue, $\n 43 ] 44 ), 45 Value. 46 47echo@inspect(Value) -> 48 case Value of 49 nil -> "Nil"; 50 true -> "True"; 51 false -> "False"; 52 Int when erlang:is_integer(Int) -> erlang:integer_to_list(Int); 53 Float when erlang:is_float(Float) -> io_lib_format:fwrite_g(Float); 54 Binary when erlang:is_binary(Binary) -> inspect@binary(Binary); 55 Bits when erlang:is_bitstring(Bits) -> inspect@bit_array(Bits); 56 Atom when erlang:is_atom(Atom) -> inspect@atom(Atom); 57 List when erlang:is_list(List) -> inspect@list(List); 58 Map when erlang:is_map(Map) -> inspect@map(Map); 59 Record when ?could_be_record(Record) -> inspect@record(Record); 60 Tuple when erlang:is_tuple(Tuple) -> inspect@tuple(Tuple); 61 Function when erlang:is_function(Function) -> inspect@function(Function); 62 Any -> ["//erl(", io_lib:format("~p", [Any]), ")"] 63 end. 64 65inspect@bit_array(Bits) -> 66 Pieces = inspect@bit_array_pieces(Bits, []), 67 Inner = lists:join(", ", lists:reverse(Pieces)), 68 ["<<", Inner, ">>"]. 69 70inspect@bit_array_pieces(Bits, Acc) -> 71 case Bits of 72 <<>> -> 73 Acc; 74 <<Byte, Rest/bitstring>> -> 75 inspect@bit_array_pieces(Rest, [erlang:integer_to_binary(Byte) | Acc]); 76 _ -> 77 Size = erlang:bit_size(Bits), 78 <<RemainingBits:Size>> = Bits, 79 SizeString = [":size(", erlang:integer_to_binary(Size), ")"], 80 Piece = [erlang:integer_to_binary(RemainingBits), SizeString], 81 [Piece | Acc] 82 end. 83 84inspect@binary(Binary) -> 85 case inspect@maybe_utf8_string(Binary, <<>>) of 86 {ok, InspectedUtf8String} -> 87 InspectedUtf8String; 88 {error, not_a_utf8_string} -> 89 Segments = [erlang:integer_to_list(X) || <<X>> <= Binary], 90 ["<<", lists:join(", ", Segments), ">>"] 91 end. 92 93inspect@atom(Atom) -> 94 Binary = erlang:atom_to_binary(Atom), 95 case inspect@maybe_gleam_atom(Binary, none, <<>>) of 96 {ok, Inspected} -> Inspected; 97 {error, _} -> ["atom.create(\"", Binary, "\")"] 98 end. 99 100inspect@list(List) -> 101 case inspect@list_loop(List, true) of 102 {charlist, _} -> ["charlist.from_string(\"", erlang:list_to_binary(List), "\")"]; 103 {proper, Elements} -> ["[", Elements, "]"]; 104 {improper, Elements} -> ["//erl([", Elements, "])"] 105 end. 106 107inspect@map(Map) -> 108 Fields = [ 109 [<<"#(">>, echo@inspect(Key), <<", ">>, echo@inspect(Value), <<")">>] 110 || {Key, Value} <- maps:to_list(Map) 111 ], 112 ["dict.from_list([", lists:join(", ", Fields), "])"]. 113 114inspect@record(Record) -> 115 [Atom | ArgsList] = Tuple = erlang:tuple_to_list(Record), 116 case inspect@maybe_gleam_atom(Atom, none, <<>>) of 117 {ok, Tag} -> 118 Args = lists:join(", ", lists:map(fun echo@inspect/1, ArgsList)), 119 [Tag, "(", Args, ")"]; 120 _ -> 121 inspect@tuple(Tuple) 122 end. 123 124inspect@tuple(Tuple) when erlang:is_tuple(Tuple) -> 125 inspect@tuple(erlang:tuple_to_list(Tuple)); 126inspect@tuple(Tuple) -> 127 Elements = lists:map(fun echo@inspect/1, Tuple), 128 ["#(", lists:join(", ", Elements), ")"]. 129 130inspect@function(Function) -> 131 {arity, Arity} = erlang:fun_info(Function, arity), 132 ArgsAsciiCodes = lists:seq($a, $a + Arity - 1), 133 Args = lists:join(", ", lists:map(fun(Arg) -> <<Arg>> end, ArgsAsciiCodes)), 134 ["//fn(", Args, ") { ... }"]. 135 136inspect@maybe_utf8_string(Binary, Acc) -> 137 case Binary of 138 <<>> -> 139 {ok, <<$", Acc/binary, $">>}; 140 <<First/utf8, Rest/binary>> -> 141 Escaped = inspect@escape_grapheme(First), 142 inspect@maybe_utf8_string(Rest, <<Acc/binary, Escaped/binary>>); 143 _ -> 144 {error, not_a_utf8_string} 145 end. 146 147inspect@escape_grapheme(Char) -> 148 case Char of 149 $" -> <<$\\, $">>; 150 $\\ -> <<$\\, $\\>>; 151 $\r -> <<$\\, $r>>; 152 $\n -> <<$\\, $n>>; 153 $\t -> <<$\\, $t>>; 154 $\f -> <<$\\, $f>>; 155 X when X > 126, X < 160 -> inspect@convert_to_u(X); 156 X when X < 32 -> inspect@convert_to_u(X); 157 Other -> <<Other/utf8>> 158 end. 159 160inspect@convert_to_u(Code) -> 161 erlang:list_to_binary(io_lib:format("\\u{~4.16.0B}", [Code])). 162 163inspect@list_loop(List, Ascii) -> 164 case List of 165 [] -> 166 {proper, []}; 167 [First] when Ascii andalso ?is_ascii_character(First) -> 168 {charlist, nil}; 169 [First] -> 170 {proper, [echo@inspect(First)]}; 171 [First | Rest] when erlang:is_list(Rest) -> 172 StillAscii = Ascii andalso ?is_ascii_character(First), 173 {Kind, Inspected} = inspect@list_loop(Rest, StillAscii), 174 {Kind, [echo@inspect(First), ", " | Inspected]}; 175 [First | ImproperRest] -> 176 {improper, [echo@inspect(First), " | ", echo@inspect(ImproperRest)]} 177 end. 178 179inspect@maybe_gleam_atom(Atom, PrevChar, Acc) when erlang:is_atom(Atom) -> 180 Binary = erlang:atom_to_binary(Atom), 181 inspect@maybe_gleam_atom(Binary, PrevChar, Acc); 182inspect@maybe_gleam_atom(Atom, PrevChar, Acc) -> 183 case {Atom, PrevChar} of 184 {<<>>, none} -> 185 {error, nil}; 186 {<<First, _/binary>>, none} when ?is_digit_char(First) -> 187 {error, nil}; 188 {<<"_", _/binary>>, none} -> 189 {error, nil}; 190 {<<"_">>, _} -> 191 {error, nil}; 192 {<<"_", _/binary>>, $_} -> 193 {error, nil}; 194 {<<First, _/binary>>, _} when not ?is_atom_char(First) -> 195 {error, nil}; 196 {<<First, Rest/binary>>, none} -> 197 inspect@maybe_gleam_atom(Rest, First, <<Acc/binary, (inspect@uppercase(First))>>); 198 {<<"_", Rest/binary>>, _} -> 199 inspect@maybe_gleam_atom(Rest, $_, Acc); 200 {<<First, Rest/binary>>, $_} -> 201 inspect@maybe_gleam_atom(Rest, First, <<Acc/binary, (inspect@uppercase(First))>>); 202 {<<First, Rest/binary>>, _} -> 203 inspect@maybe_gleam_atom(Rest, First, <<Acc/binary, First>>); 204 {<<>>, _} -> 205 {ok, Acc}; 206 _ -> 207 erlang:throw({gleam_error, echo, Atom, PrevChar, Acc}) 208 end. 209 210inspect@uppercase(X) -> X - 32.