Current section
Files
Jump to
Current section
Files
src/glue@internal@code.erl
-module(glue@internal@code).
-compile([no_auto_import, nowarn_unused_vars]).
-export([function_to_string/1]).
-export_type([function_/0, statement/0, expression/0, clause/0, pattern/0, generator/0]).
-type function_() :: {function,
binary(),
list({binary(), binary()}),
binary(),
list(statement())}.
-type statement() :: {expression, expression()} |
{'let', binary(), expression()}.
-type expression() :: {variable, binary()} |
{fn, list(binary()), list(statement())} |
{int, integer()} |
{call, expression(), list(expression())} |
{'case', expression(), list(clause())} |
{list, list(expression())}.
-type clause() :: {clause, pattern(), expression()}.
-type pattern() :: {constructor, binary(), list(pattern())}.
-type generator() :: {generator, binary(), integer()}.
-spec write(generator(), binary()) -> generator().
write(Gen, Code) ->
erlang:setelement(2, Gen, <<(erlang:element(2, Gen))/binary, Code/binary>>).
-spec write_parameters(generator(), list({binary(), binary()})) -> generator().
write_parameters(Gen, Parameters) ->
_pipe = Parameters,
gleam@list:index_fold(
_pipe,
Gen,
fun(Gen@1, Parameters@1, I) -> _pipe@1 = case I of
0 ->
Gen@1;
_ ->
write(Gen@1, <<", "/utf8>>)
end,
_pipe@2 = write(_pipe@1, erlang:element(1, Parameters@1)),
_pipe@3 = write(_pipe@2, <<": "/utf8>>),
write(_pipe@3, erlang:element(2, Parameters@1)) end
).
-spec indent_up(generator()) -> generator().
indent_up(Gen) ->
erlang:setelement(3, Gen, erlang:element(3, Gen) + 1).
-spec indent_down(generator()) -> generator().
indent_down(Gen) ->
erlang:setelement(3, Gen, erlang:element(3, Gen) - 1).
-spec indent(generator()) -> generator().
indent(Gen) ->
_pipe = Gen,
write(_pipe, gleam@string:repeat(<<" "/utf8>>, erlang:element(3, Gen))).
-spec newline(generator()) -> generator().
newline(Gen) ->
_pipe = Gen,
write(_pipe, <<"\n"/utf8>>).
-spec finish(generator()) -> binary().
finish(Gen) ->
erlang:element(2, Gen).
-spec write_fn(generator(), list(binary()), list(statement())) -> generator().
write_fn(Gen, Parameters, Body) ->
Write_parameter = fun(Gen@1, Parameter, I) -> _pipe = case I of
0 ->
Gen@1;
_ ->
write(Gen@1, <<", "/utf8>>)
end,
write(_pipe, Parameter) end,
_pipe@1 = Gen,
_pipe@2 = write(_pipe@1, <<"fn("/utf8>>),
_pipe@3 = gleam@list:index_fold(Parameters, _pipe@2, Write_parameter),
_pipe@4 = write(_pipe@3, <<") {"/utf8>>),
_pipe@5 = newline(_pipe@4),
_pipe@6 = indent_up(_pipe@5),
_pipe@7 = write_statements(_pipe@6, Body),
_pipe@8 = indent_down(_pipe@7),
_pipe@9 = indent(_pipe@8),
write(_pipe@9, <<"}"/utf8>>).
-spec write_statements(generator(), list(statement())) -> generator().
write_statements(Gen, Statements) ->
gleam@list:fold(Statements, Gen, fun(Gen@1, Statement) -> _pipe = Gen@1,
_pipe@1 = indent(_pipe),
_pipe@2 = write_statement(_pipe@1, Statement),
newline(_pipe@2) end).
-spec write_statement(generator(), statement()) -> generator().
write_statement(Gen, Statement) ->
case Statement of
{'let', Name, Expression} ->
_pipe = Gen,
_pipe@1 = write(_pipe, <<"let "/utf8>>),
_pipe@2 = write(_pipe@1, Name),
_pipe@3 = write(_pipe@2, <<" = "/utf8>>),
write_expression(_pipe@3, Expression);
{expression, Expression@1} ->
_pipe@4 = Gen,
write_expression(_pipe@4, Expression@1)
end.
-spec write_expression(generator(), expression()) -> generator().
write_expression(Gen, Expression) ->
case Expression of
{variable, Name} ->
write(Gen, Name);
{int, I} ->
write(Gen, gleam@int:to_string(I));
{fn, Parameters, Body} ->
write_fn(Gen, Parameters, Body);
{call, Function, Arguments} ->
write_call(Gen, Function, Arguments);
{'case', Expression@1, Clauses} ->
write_case(Gen, Expression@1, Clauses);
{list, Expressions} ->
write_list(Gen, Expressions)
end.
-spec function_to_string(function_()) -> binary().
function_to_string(Function) ->
_pipe = {generator, <<""/utf8>>, 0},
_pipe@1 = write(_pipe, <<"pub fn "/utf8>>),
_pipe@2 = write(_pipe@1, erlang:element(2, Function)),
_pipe@3 = write(_pipe@2, <<"("/utf8>>),
_pipe@4 = write_parameters(_pipe@3, erlang:element(3, Function)),
_pipe@5 = write(_pipe@4, <<") -> "/utf8>>),
_pipe@6 = write(_pipe@5, erlang:element(4, Function)),
_pipe@7 = write(_pipe@6, <<" {"/utf8>>),
_pipe@8 = newline(_pipe@7),
_pipe@9 = indent_up(_pipe@8),
_pipe@10 = write_statements(_pipe@9, erlang:element(5, Function)),
_pipe@11 = indent_down(_pipe@10),
_pipe@12 = write(_pipe@11, <<"}"/utf8>>),
_pipe@13 = newline(_pipe@12),
finish(_pipe@13).
-spec write_argument(generator(), expression(), integer()) -> generator().
write_argument(Gen, Argument, I) ->
_pipe = case I of
0 ->
Gen;
_ ->
write(Gen, <<", "/utf8>>)
end,
write_expression(_pipe, Argument).
-spec write_call(generator(), expression(), list(expression())) -> generator().
write_call(Gen, Function, Arguments) ->
_pipe = Gen,
_pipe@1 = write_expression(_pipe, Function),
_pipe@2 = write(_pipe@1, <<"("/utf8>>),
_pipe@3 = gleam@list:index_fold(Arguments, _pipe@2, fun write_argument/3),
write(_pipe@3, <<")"/utf8>>).
-spec write_list(generator(), list(expression())) -> generator().
write_list(Gen, Expressions) ->
_pipe = Gen,
_pipe@1 = write(_pipe, <<"["/utf8>>),
_pipe@2 = gleam@list:index_fold(Expressions, _pipe@1, fun write_argument/3),
write(_pipe@2, <<"]"/utf8>>).
-spec write_constructor_pattern(generator(), binary(), list(pattern())) -> generator().
write_constructor_pattern(Gen, Name, Patterns) ->
Gen@1 = write(Gen, Name),
case Patterns of
[] ->
Gen@1;
_ ->
_pipe = Gen@1,
_pipe@1 = write(_pipe, <<"("/utf8>>),
_pipe@2 = gleam@list:index_fold(
Patterns,
_pipe@1,
fun write_pattern_argument/3
),
write(_pipe@2, <<")"/utf8>>)
end.
-spec write_pattern_argument(generator(), pattern(), integer()) -> generator().
write_pattern_argument(Gen, Argument, I) ->
_pipe = case I of
0 ->
Gen;
_ ->
write(Gen, <<", "/utf8>>)
end,
write_pattern(_pipe, Argument).
-spec write_pattern(generator(), pattern()) -> generator().
write_pattern(Gen, Pattern) ->
case Pattern of
{constructor, Name, []} ->
write(Gen, Name);
{constructor, Name@1, Patterns} ->
write_constructor_pattern(Gen, Name@1, Patterns)
end.
-spec write_clause(generator(), clause()) -> generator().
write_clause(Gen, Clause) ->
_pipe = Gen,
_pipe@1 = indent(_pipe),
_pipe@2 = write_pattern(_pipe@1, erlang:element(2, Clause)),
_pipe@3 = write(_pipe@2, <<" -> "/utf8>>),
_pipe@4 = indent_up(_pipe@3),
_pipe@5 = write_expression(_pipe@4, erlang:element(3, Clause)),
_pipe@6 = indent_down(_pipe@5),
newline(_pipe@6).
-spec write_case(generator(), expression(), list(clause())) -> generator().
write_case(Gen, Expression, Clauses) ->
_pipe = Gen,
_pipe@1 = write(_pipe, <<"case "/utf8>>),
_pipe@2 = write_expression(_pipe@1, Expression),
_pipe@3 = write(_pipe@2, <<" {"/utf8>>),
_pipe@4 = newline(_pipe@3),
_pipe@5 = indent_up(_pipe@4),
_pipe@6 = gleam@list:fold(Clauses, _pipe@5, fun write_clause/2),
_pipe@7 = indent_down(_pipe@6),
_pipe@8 = indent(_pipe@7),
write(_pipe@8, <<"}"/utf8>>).