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