-module(girard@internal@printer).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/girard/internal/printer.gleam").
-export([new_names/0, print/2, to_string/1]).
-export_type([names/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(false).
-type names() :: {names, gleam@dict:dict(integer(), binary()), integer()}.
-file("src/girard/internal/printer.gleam", 16).
?DOC(false).
-spec new_names() -> names().
new_names() ->
{names, maps:new(), 0}.
-file("src/girard/internal/printer.gleam", 81).
?DOC(false).
-spec is_reserved(binary()) -> boolean().
is_reserved(Name) ->
case Name of
<<"as"/utf8>> ->
true;
<<"assert"/utf8>> ->
true;
<<"case"/utf8>> ->
true;
<<"const"/utf8>> ->
true;
<<"echo"/utf8>> ->
true;
<<"fn"/utf8>> ->
true;
<<"if"/utf8>> ->
true;
<<"import"/utf8>> ->
true;
<<"let"/utf8>> ->
true;
<<"opaque"/utf8>> ->
true;
<<"panic"/utf8>> ->
true;
<<"pub"/utf8>> ->
true;
<<"todo"/utf8>> ->
true;
<<"type"/utf8>> ->
true;
<<"use"/utf8>> ->
true;
_ ->
false
end.
-file("src/girard/internal/printer.gleam", 103).
?DOC(false).
-spec letters(integer()) -> binary().
letters(N) ->
Letter = gleam@string:utf_codepoint(97 + (N rem 26)),
Prefix = case N div 26 of
0 ->
<<""/utf8>>;
Higher ->
letters(Higher - 1)
end,
case Letter of
{ok, Codepoint} ->
<<Prefix/binary,
(gleam_stdlib:utf_codepoint_list_to_string([Codepoint]))/binary>>;
{error, _} ->
<<"t"/utf8, (erlang:integer_to_binary(N))/binary>>
end.
-file("src/girard/internal/printer.gleam", 73).
?DOC(false).
-spec next_name(integer()) -> {binary(), integer()}.
next_name(N) ->
Name = letters(N),
case is_reserved(Name) of
true ->
next_name(N + 1);
false ->
{Name, N + 1}
end.
-file("src/girard/internal/printer.gleam", 61).
?DOC(false).
-spec var_name(names(), integer()) -> {binary(), names()}.
var_name(Names, Id) ->
case gleam_stdlib:map_get(erlang:element(2, Names), Id) of
{ok, Name} ->
{Name, Names};
{error, _} ->
{Name@1, Next} = next_name(erlang:element(3, Names)),
{Name@1,
{names,
gleam@dict:insert(erlang:element(2, Names), Id, Name@1),
Next}}
end.
-file("src/girard/internal/printer.gleam", 51).
?DOC(false).
-spec print_list(names(), list(girard@types:type())) -> {binary(), names()}.
print_list(Names, Types_) ->
{Rev, Names@3} = gleam@list:fold(
Types_,
{[], Names},
fun(Acc, T) ->
{Rendered, Names@1} = Acc,
{S, Names@2} = print(Names@1, T),
{[S | Rendered], Names@2}
end
),
{gleam@string:join(lists:reverse(Rev), <<", "/utf8>>), Names@3}.
-file("src/girard/internal/printer.gleam", 22).
?DOC(false).
-spec print(names(), girard@types:type()) -> {binary(), names()}.
print(Names, Type_) ->
case Type_ of
{named, _, Name, []} ->
{Name, Names};
{named, _, Name@1, Args} ->
{Rendered, Names@1} = print_list(Names, Args),
{<<<<<<Name@1/binary, "("/utf8>>/binary, Rendered/binary>>/binary,
")"/utf8>>,
Names@1};
{fn, Args@1, Ret} ->
{Rendered_args, Names@2} = print_list(Names, Args@1),
{Rendered_ret, Names@3} = print(Names@2, Ret),
{<<<<<<"fn("/utf8, Rendered_args/binary>>/binary, ") -> "/utf8>>/binary,
Rendered_ret/binary>>,
Names@3};
{tuple, Elements} ->
{Rendered@1, Names@4} = print_list(Names, Elements),
{<<<<"#("/utf8, Rendered@1/binary>>/binary, ")"/utf8>>, Names@4};
{var, Id} ->
var_name(Names, Id)
end.
-file("src/girard/internal/printer.gleam", 47).
?DOC(false).
-spec to_string(girard@types:type()) -> binary().
to_string(Type_) ->
erlang:element(1, print(new_names(), Type_)).