-module(caffeine_lang@parsing_utils). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/caffeine_lang/parsing_utils.gleam"). -export([split_at_top_level_comma/1, extract_paren_content/1, paren_innerds_trimmed/1, paren_innerds_split_and_trimmed/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -file("src/caffeine_lang/parsing_utils.gleam", 76). -spec do_split_at_top_level_comma( list(binary()), integer(), integer(), integer(), list(binary()), list(binary()) ) -> list(binary()). do_split_at_top_level_comma( Chars, Paren_depth, Brace_depth, Bracket_depth, Current, Acc ) -> case Chars of [] -> Trimmed = gleam@string:trim( erlang:list_to_binary(lists:reverse(Current)) ), case Trimmed of <<""/utf8>> -> lists:reverse(Acc); _ -> lists:reverse([Trimmed | Acc]) end; [<<"("/utf8>> | Rest] -> do_split_at_top_level_comma( Rest, Paren_depth + 1, Brace_depth, Bracket_depth, [<<"("/utf8>> | Current], Acc ); [<<")"/utf8>> | Rest@1] -> do_split_at_top_level_comma( Rest@1, Paren_depth - 1, Brace_depth, Bracket_depth, [<<")"/utf8>> | Current], Acc ); [<<"{"/utf8>> | Rest@2] -> do_split_at_top_level_comma( Rest@2, Paren_depth, Brace_depth + 1, Bracket_depth, [<<"{"/utf8>> | Current], Acc ); [<<"}"/utf8>> | Rest@3] -> do_split_at_top_level_comma( Rest@3, Paren_depth, Brace_depth - 1, Bracket_depth, [<<"}"/utf8>> | Current], Acc ); [<<"["/utf8>> | Rest@4] -> do_split_at_top_level_comma( Rest@4, Paren_depth, Brace_depth, Bracket_depth + 1, [<<"["/utf8>> | Current], Acc ); [<<"]"/utf8>> | Rest@5] -> do_split_at_top_level_comma( Rest@5, Paren_depth, Brace_depth, Bracket_depth - 1, [<<"]"/utf8>> | Current], Acc ); [<<","/utf8>> | Rest@6] when ((Paren_depth =:= 0) andalso (Brace_depth =:= 0)) andalso (Bracket_depth =:= 0) -> Trimmed@1 = gleam@string:trim( erlang:list_to_binary(lists:reverse(Current)) ), do_split_at_top_level_comma( Rest@6, Paren_depth, Brace_depth, Bracket_depth, [], [Trimmed@1 | Acc] ); [Char | Rest@7] -> do_split_at_top_level_comma( Rest@7, Paren_depth, Brace_depth, Bracket_depth, [Char | Current], Acc ) end. -file("src/caffeine_lang/parsing_utils.gleam", 8). ?DOC(false). -spec split_at_top_level_comma(binary()) -> list(binary()). split_at_top_level_comma(S) -> Chars = gleam@string:to_graphemes(S), do_split_at_top_level_comma(Chars, 0, 0, 0, [], []). -file("src/caffeine_lang/parsing_utils.gleam", 37). ?DOC( " Finds the matching closing parenthesis, tracking nesting depth.\n" " Returns the content before the matching close and the rest after it.\n" ). -spec find_matching_close_paren(binary(), integer(), list(binary())) -> {ok, {binary(), binary()}} | {error, nil}. find_matching_close_paren(S, Depth, Acc) -> case gleam_stdlib:string_pop_grapheme(S) of {error, _} -> {error, nil}; {ok, {<<"("/utf8>>, Rest}} -> find_matching_close_paren(Rest, Depth + 1, [<<"("/utf8>> | Acc]); {ok, {<<")"/utf8>>, Rest@1}} -> case Depth of 1 -> {ok, {erlang:list_to_binary(lists:reverse(Acc)), Rest@1}}; _ -> find_matching_close_paren( Rest@1, Depth - 1, [<<")"/utf8>> | Acc] ) end; {ok, {Char, Rest@2}} -> find_matching_close_paren(Rest@2, Depth, [Char | Acc]) end. -file("src/caffeine_lang/parsing_utils.gleam", 17). ?DOC(false). -spec extract_paren_content(binary()) -> {ok, binary()} | {error, nil}. extract_paren_content(Raw) -> case gleam@string:split_once(Raw, <<"("/utf8>>) of {error, _} -> {error, nil}; {ok, {_, After_open}} -> gleam@result:'try'( find_matching_close_paren(After_open, 1, []), fun(_use0) -> {Content, Rest} = _use0, case gleam@string:trim(Rest) of <<""/utf8>> -> {ok, gleam@string:trim(Content)}; _ -> {error, nil} end end ) end. -file("src/caffeine_lang/parsing_utils.gleam", 58). ?DOC(false). -spec paren_innerds_trimmed(binary()) -> binary(). paren_innerds_trimmed(Raw) -> case extract_paren_content(Raw) of {ok, Content} -> Content; {error, _} -> gleam@string:trim(Raw) end. -file("src/caffeine_lang/parsing_utils.gleam", 69). ?DOC(false). -spec paren_innerds_split_and_trimmed(binary()) -> list(binary()). paren_innerds_split_and_trimmed(Raw) -> case extract_paren_content(Raw) of {ok, Content} -> split_at_top_level_comma(Content); {error, _} -> [] end.