-module(internal@codegen@statements). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([nil/0, ok/1, error/1, int/1, list/1, variant/2, variable/1, compare/3, case_stmt/2, clause/2, underscore/0, unused_var/1, literal/1, var_pattern/1, function/3, arg_untyped/1, arg_typed/2, call/2, use_arg/1, name_of_var/1, let_var/2, let_array/2, let_tuple/2, multiply/1, direct/1, generate/1]). -export_type([gleam_statement/0, comparison_operator/0, clause/0, pattern/0, argument/0]). -type gleam_statement() :: nil_val | {int_val, integer()} | {list_val, list(gleam_statement())} | {string_val, binary()} | {tuple_val, list(gleam_statement())} | {variant_val, binary(), list(gleam_statement())} | {var_primitive, binary()} | {comparison, gleam_statement(), comparison_operator(), gleam_statement()} | {case_statement, list(gleam_statement()), list(clause())} | {function, binary(), list(argument()), list(gleam_statement())} | {function_call, binary(), list(gleam_statement())} | {use_arg, gleam_statement()} | {let_var, pattern(), gleam_statement()} | {let_array, list(pattern()), gleam_statement()} | {let_tuple, list(pattern()), gleam_statement()} | {multiply, list(gleam_statement())} | {direct, binary()}. -type comparison_operator() :: lt | lte | eq | neq | gt | gte. -opaque clause() :: {clause, list(pattern()), gleam_statement()}. -opaque pattern() :: {anything, gleam@option:option(binary())} | {constant_pattern, binary()} | {variable, binary()}. -opaque argument() :: {argument, binary(), gleam@option:option(internal@codegen@types:gleam_type())}. -spec nil() -> gleam_statement(). nil() -> nil_val. -spec ok(gleam_statement()) -> gleam_statement(). ok(Value) -> {variant_val, <<"Ok"/utf8>>, [Value]}. -spec error(gleam_statement()) -> gleam_statement(). error(Error) -> {variant_val, <<"Error"/utf8>>, [Error]}. -spec int(integer()) -> gleam_statement(). int(Value) -> {int_val, Value}. -spec list(list(gleam_statement())) -> gleam_statement(). list(Values) -> {list_val, Values}. -spec variant(binary(), list(gleam_statement())) -> gleam_statement(). variant(Name, Field_values) -> {variant_val, Name, Field_values}. -spec variable(binary()) -> gleam_statement(). variable(Name) -> {var_primitive, Name}. -spec compare(gleam_statement(), comparison_operator(), gleam_statement()) -> gleam_statement(). compare(Stmt1, Comp_op, Stmt2) -> {comparison, Stmt1, Comp_op, Stmt2}. -spec case_stmt(list(gleam_statement()), list(clause())) -> gleam_statement(). case_stmt(Guards, Clauses) -> {case_statement, Guards, Clauses}. -spec clause(list(pattern()), gleam_statement()) -> clause(). clause(Patterns, Stmt) -> {clause, Patterns, Stmt}. -spec underscore() -> pattern(). underscore() -> {anything, none}. -spec unused_var(binary()) -> pattern(). unused_var(Name) -> {anything, {some, Name}}. -spec literal(binary()) -> pattern(). literal(Lit) -> {constant_pattern, Lit}. -spec var_pattern(binary()) -> pattern(). var_pattern(Var) -> {variable, Var}. -spec function(binary(), list(argument()), list(gleam_statement())) -> gleam_statement(). function(Name, Arguments, Statements) -> {function, Name, Arguments, Statements}. -spec arg_untyped(binary()) -> argument(). arg_untyped(Name) -> {argument, Name, none}. -spec arg_typed(binary(), internal@codegen@types:gleam_type()) -> argument(). arg_typed(Name, Arg_type) -> {argument, Name, {some, Arg_type}}. -spec call(binary(), list(gleam_statement())) -> gleam_statement(). call(Name, Arguments) -> {function_call, Name, begin _pipe = Arguments, gleam@list:map(_pipe, fun(Field@0) -> {use_arg, Field@0} end) end}. -spec use_arg(argument()) -> gleam_statement(). use_arg(Arg) -> {var_primitive, erlang:element(2, Arg)}. -spec name_of_var(gleam_statement()) -> binary(). name_of_var(Var) -> {var_primitive, Name} = case Var of {var_primitive, _} -> Var; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"internal/codegen/statements"/utf8>>, function => <<"name_of_var"/utf8>>, line => 154}) end, Name. -spec let_var(pattern(), gleam_statement()) -> gleam_statement(). let_var(Pattern, Statement) -> {let_var, Pattern, Statement}. -spec let_array(list(pattern()), gleam_statement()) -> gleam_statement(). let_array(Patterns, Array) -> {let_array, Patterns, Array}. -spec let_tuple(list(pattern()), gleam_statement()) -> gleam_statement(). let_tuple(Patterns, Tuple) -> {let_tuple, Patterns, Tuple}. -spec multiply(list(gleam_statement())) -> gleam_statement(). multiply(Terms) -> {multiply, Terms}. -spec direct(binary()) -> gleam_statement(). direct(String) -> {direct, String}. -spec generate_comparison(comparison_operator()) -> binary(). generate_comparison(Op) -> case Op of lt -> <<"<"/utf8>>; lte -> <<"<="/utf8>>; eq -> <<"=="/utf8>>; neq -> <<"!="/utf8>>; gt -> <<">"/utf8>>; gte -> <<">="/utf8>> end. -spec generate_pattern(pattern()) -> binary(). generate_pattern(Pattern) -> case Pattern of {anything, none} -> <<"_"/utf8>>; {anything, {some, Name}} -> <<"_"/utf8, Name/binary>>; {constant_pattern, Constant} -> Constant; {variable, Name@1} -> Name@1 end. -spec generate_arg(argument()) -> binary(). generate_arg(Arg) -> <<(erlang:element(2, Arg))/binary, (case erlang:element(3, Arg) of {some, T} -> <<": "/utf8, (internal@codegen@types:generate_type(T))/binary>>; _ -> <<""/utf8>> end)/binary>>. -spec generate_clause(clause()) -> binary(). generate_clause(Clause) -> <<<<<<" "/utf8, (begin _pipe = erlang:element(2, Clause), _pipe@1 = gleam@list:map(_pipe, fun generate_pattern/1), gleam@string:join(_pipe@1, <<", "/utf8>>) end)/binary>>/binary, " -> "/utf8>>/binary, (generate(erlang:element(3, Clause)))/binary>>. -spec generate(gleam_statement()) -> binary(). generate(Stmt) -> case Stmt of nil_val -> <<"Nil"/utf8>>; {int_val, Value} -> gleam@int:to_string(Value); {list_val, Items} -> <<<<"["/utf8, (begin _pipe = Items, _pipe@1 = gleam@list:map(_pipe, fun generate/1), gleam@string:join(_pipe@1, <<", "/utf8>>) end)/binary>>/binary, "]"/utf8>>; {string_val, S} -> <<<<"\""/utf8, S/binary>>/binary, "\""/utf8>>; {tuple_val, Items@1} -> <<<<"#("/utf8, (begin _pipe@2 = Items@1, _pipe@3 = gleam@list:map(_pipe@2, fun generate/1), gleam@string:join(_pipe@3, <<", "/utf8>>) end)/binary>>/binary, ")"/utf8>>; {variant_val, Name, []} -> Name; {variant_val, Name@1, Fields} -> <<<<<>/binary, (begin _pipe@4 = Fields, _pipe@5 = gleam@list:map(_pipe@4, fun generate/1), gleam@string:join(_pipe@5, <<", "/utf8>>) end)/binary>>/binary, ")"/utf8>>; {var_primitive, Name@2} -> Name@2; {comparison, Stmt1, Op, Stmt2} -> <<<<<<<<(generate(Stmt1))/binary, " "/utf8>>/binary, (generate_comparison(Op))/binary>>/binary, " "/utf8>>/binary, (generate(Stmt2))/binary>>; {case_statement, Guards, Clauses} -> <<<<<<<<"case "/utf8, (begin _pipe@6 = Guards, _pipe@7 = gleam@list:map( _pipe@6, fun generate/1 ), gleam@string:join(_pipe@7, <<", "/utf8>>) end)/binary>>/binary, " {\n"/utf8>>/binary, (begin _pipe@8 = Clauses, _pipe@9 = gleam@list:map(_pipe@8, fun generate_clause/1), gleam@string:join(_pipe@9, <<"\n"/utf8>>) end)/binary>>/binary, "\n}"/utf8>>; {function, Name@3, Args, Statements} -> <<<<<<<<<<<<"pub fn "/utf8, Name@3/binary>>/binary, "("/utf8>>/binary, (begin _pipe@10 = Args, _pipe@11 = gleam@list:map( _pipe@10, fun generate_arg/1 ), gleam@string:join(_pipe@11, <<", "/utf8>>) end)/binary>>/binary, ") {\n"/utf8>>/binary, (begin _pipe@12 = Statements, _pipe@13 = gleam@list:map(_pipe@12, fun generate/1), gleam@string:join(_pipe@13, <<"\n"/utf8>>) end)/binary>>/binary, "\n}\n"/utf8>>; {function_call, Name@4, Arguments} -> <<<<<>/binary, (begin _pipe@14 = Arguments, _pipe@15 = gleam@list:map(_pipe@14, fun generate/1), gleam@string:join(_pipe@15, <<", "/utf8>>) end)/binary>>/binary, ")"/utf8>>; {use_arg, Arg} -> generate(Arg); {let_var, Pattern, Statement} -> <<<<<<"let "/utf8, (generate_pattern(Pattern))/binary>>/binary, " = "/utf8>>/binary, (generate(Statement))/binary>>; {let_array, Patterns, Array} -> <<<<<<"let ["/utf8, (begin _pipe@16 = Patterns, _pipe@17 = gleam@list:map( _pipe@16, fun generate_pattern/1 ), gleam@string:join(_pipe@17, <<", "/utf8>>) end)/binary>>/binary, "] = "/utf8>>/binary, (generate(Array))/binary>>; {let_tuple, Patterns@1, Array@1} -> <<<<<<"let #("/utf8, (begin _pipe@18 = Patterns@1, _pipe@19 = gleam@list:map( _pipe@18, fun generate_pattern/1 ), gleam@string:join(_pipe@19, <<", "/utf8>>) end)/binary>>/binary, ") = "/utf8>>/binary, (generate(Array@1))/binary>>; {multiply, Terms} -> _pipe@20 = Terms, _pipe@21 = gleam@list:map(_pipe@20, fun generate/1), gleam@string:join(_pipe@21, <<" * "/utf8>>); {direct, String} -> String end.