-module(molt@internal@parser). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/molt/internal/parser.gleam"). -export([parse/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. ?MODULEDOC(false). -file("src/molt/internal/parser.gleam", 1324). ?DOC(false). -spec add_kv( molt@internal@parser@core:state(), greenwood:node_(molt@types:toml_kind()) ) -> molt@internal@parser@core:state(). add_kv(State, Kv_node) -> case erlang:element(7, State) of no_table -> {state, erlang:element(2, State), erlang:element(3, State), erlang:element(4, State), erlang:element(5, State), [{node_element, Kv_node} | erlang:element(6, State)], erlang:element(7, State), erlang:element(8, State)}; {building, K, C, T, Tr} -> {state, erlang:element(2, State), erlang:element(3, State), erlang:element(4, State), erlang:element(5, State), erlang:element(6, State), {building, K, [{node_element, Kv_node} | C], T, Tr}, erlang:element(8, State)} end. -file("src/molt/internal/parser.gleam", 1353). ?DOC(false). -spec attach_pending_trivia( greenwood:node_(molt@types:toml_kind()), list(greenwood:token(molt@types:toml_kind())) ) -> greenwood:node_(molt@types:toml_kind()). attach_pending_trivia(Node, Pending_rev) -> case Pending_rev of [] -> Node; _ -> {node, erlang:element(2, Node), erlang:element(3, Node), {trivia, Pending_rev, []}} end. -file("src/molt/internal/parser.gleam", 1342). ?DOC(false). -spec attach_line_trivia( greenwood:node_(molt@types:toml_kind()), list(greenwood:token(molt@types:toml_kind())), list(greenwood:token(molt@types:toml_kind())) ) -> greenwood:node_(molt@types:toml_kind()). attach_line_trivia(Node, Leading, Trailing) -> case {Leading, Trailing} of {[], []} -> Node; {_, _} -> {node, erlang:element(2, Node), erlang:element(3, Node), {trivia, Leading, Trailing}} end. -file("src/molt/internal/parser.gleam", 307). ?DOC(false). -spec all_bare_keys_valid(list(greenwood:element(molt@types:toml_kind()))) -> boolean(). all_bare_keys_valid(Children) -> gleam@list:all(Children, fun(El) -> case El of {token_element, {token, bare_key, Text}} -> molt@internal@utils:is_bare_key(Text); {node_element, Node} when erlang:element(2, Node) =:= key -> all_bare_keys_valid(erlang:element(3, Node)); _ -> true end end). -file("src/molt/internal/parser.gleam", 290). ?DOC(false). -spec do_has_value_after_equals( list(greenwood:element(molt@types:toml_kind())), boolean() ) -> boolean(). do_has_value_after_equals(Children, Past_equals) -> case {Children, Past_equals} of {[], false} -> true; {[], true} -> false; {[{token_element, {token, equals, _}} | Rest], _} -> do_has_value_after_equals(Rest, true); {[{token_element, {token, whitespace, _}} | Rest@1], Pe} -> do_has_value_after_equals(Rest@1, Pe); {[{token_element, {token, newline, _}} | _], true} -> false; {[_ | _], true} -> true; {[_ | Rest@2], false} -> do_has_value_after_equals(Rest@2, false) end. -file("src/molt/internal/parser.gleam", 286). ?DOC(false). -spec has_value_after_equals(list(greenwood:element(molt@types:toml_kind()))) -> boolean(). has_value_after_equals(Children) -> do_has_value_after_equals(Children, false). -file("src/molt/internal/parser.gleam", 277). ?DOC(false). -spec has_equals(list(greenwood:element(molt@types:toml_kind()))) -> boolean(). has_equals(Children) -> gleam@list:any(Children, fun(El) -> case El of {token_element, {token, equals, _}} -> true; _ -> false end end). -file("src/molt/internal/parser.gleam", 269). ?DOC(false). -spec is_valid_kv(greenwood:node_(molt@types:toml_kind())) -> boolean(). is_valid_kv(Node) -> Children = lists:reverse(erlang:element(3, Node)), (has_equals(Children) andalso has_value_after_equals(Children)) andalso all_bare_keys_valid( Children ). -file("src/molt/internal/parser.gleam", 204). ?DOC(false). -spec head_split(molt@internal@parser@core:state()) -> {list(greenwood:token(molt@types:toml_kind())), molt@internal@parser@core:state()}. head_split(State) -> case {erlang:element(7, State), erlang:element(6, State)} of {no_table, []} -> {Root_rev, Node_rev} = molt@internal@parser@core:peel_head_block( erlang:element(3, State) ), {Node_rev, {state, erlang:element(2, State), erlang:element(3, State), Root_rev, erlang:element(5, State), erlang:element(6, State), erlang:element(7, State), erlang:element(8, State)}}; {_, _} -> {erlang:element(3, State), State} end. -file("src/molt/internal/parser.gleam", 1311). ?DOC(false). -spec peel_leading_ws_from_acc( list(greenwood:element(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind())) ) -> {list(greenwood:element(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind()))}. peel_leading_ws_from_acc(Acc, Ws_acc) -> case Acc of [{token_element, {token, whitespace, _}} = El | Rest] -> peel_leading_ws_from_acc(Rest, [El | Ws_acc]); _ -> {Acc, lists:reverse(Ws_acc)} end. -file("src/molt/internal/parser.gleam", 1289). ?DOC(false). -spec take_key_tokens( list(greenwood:element(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind())) ) -> {list(greenwood:element(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind()))}. take_key_tokens(Items, Acc) -> case Items of [{token_element, {token, bare_key, _}} = El | Rest] -> take_key_tokens(Rest, [El | Acc]); [{token_element, {token, dot, _}} = El | Rest] -> take_key_tokens(Rest, [El | Acc]); [{token_element, {token, basic_string, _}} = El | Rest] -> take_key_tokens(Rest, [El | Acc]); [{token_element, {token, literal_string, _}} = El | Rest] -> take_key_tokens(Rest, [El | Acc]); [{token_element, {token, whitespace, _}} = El | Rest] -> take_key_tokens(Rest, [El | Acc]); _ -> {Stripped_acc, Ws_tail} = peel_leading_ws_from_acc(Acc, []), {lists:reverse(Stripped_acc), lists:append(Ws_tail, Items)} end. -file("src/molt/internal/parser.gleam", 1270). ?DOC(false). -spec take_trivia_prefix( list(greenwood:element(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind())) ) -> {list(greenwood:element(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind()))}. take_trivia_prefix(Items, Acc) -> case Items of [{token_element, {token, whitespace, _}} = El | Rest] -> take_trivia_prefix(Rest, [El | Acc]); _ -> {lists:reverse(Acc), Items} end. -file("src/molt/internal/parser.gleam", 1259). ?DOC(false). -spec has_dot_token(list(greenwood:element(molt@types:toml_kind()))) -> boolean(). has_dot_token(Children) -> gleam@list:any(Children, fun(El) -> case El of {token_element, {token, dot, _}} -> true; _ -> false end end). -file("src/molt/internal/parser.gleam", 1248). ?DOC(false). -spec split_at_equals_rev( list(greenwood:element(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind())) ) -> {list(greenwood:element(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind()))}. split_at_equals_rev(Children_rev, Acc) -> case Children_rev of [] -> {lists:reverse(Acc), []}; [{token_element, {token, equals, _}} | _] = Tail -> {lists:reverse(Acc), Tail}; [El | Rest] -> split_at_equals_rev(Rest, [El | Acc]) end. -file("src/molt/internal/parser.gleam", 1223). ?DOC(false). -spec wrap_dotted_key(list(greenwood:element(molt@types:toml_kind()))) -> list(greenwood:element(molt@types:toml_kind())). wrap_dotted_key(Children_rev) -> {After_eq_rev, Eq_and_key_rev} = split_at_equals_rev(Children_rev, []), case Eq_and_key_rev of [] -> Children_rev; [Eq_el | Key_rev] -> case has_dot_token(Key_rev) of false -> Children_rev; true -> {Trailing_ws_rev, After_ws_rev} = take_trivia_prefix( Key_rev, [] ), {Key_inner_rev, Leading_rev} = take_key_tokens( After_ws_rev, [] ), Key_node = greenwood:node(key, Key_inner_rev), lists:append( [After_eq_rev, [Eq_el], Trailing_ws_rev, [{node_element, Key_node}], Leading_rev] ) end end. -file("src/molt/internal/parser.gleam", 789). ?DOC(false). -spec flush_inline_entry( list(greenwood:token(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind())) ) -> list(greenwood:element(molt@types:toml_kind())). flush_inline_entry(Trivia_acc, Entry_acc, Result) -> case Entry_acc of [] -> case Trivia_acc of [] -> Result; _ -> gleam@list:fold( lists:reverse(Trivia_acc), Result, fun(Acc, Tok) -> [{token_element, Tok} | Acc] end ) end; _ -> {Children, Trailing} = molt@internal@parser@core:peel_trailing_comment_rev( Entry_acc ), Trivia = case {Trivia_acc, Trailing} of {[], []} -> bare; {_, _} -> {trivia, Trivia_acc, Trailing} end, Node = {node, key_value, Children, Trivia}, [{node_element, Node} | Result] end. -file("src/molt/internal/parser.gleam", 656). ?DOC(false). -spec take_same_line( list(greenwood:element(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind())) ) -> {list(greenwood:element(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind()))}. take_same_line(Children, Acc) -> case Children of [] -> {Acc, []}; [{token_element, {token, newline, _} = Tok} | Rest] -> {[{token_element, Tok} | Acc], Rest}; [{token_element, {token, whitespace, _}} = El | Rest@1] -> take_same_line(Rest@1, [El | Acc]); [{token_element, {token, comment, _}} = El@1 | Rest@2] -> take_same_line(Rest@2, [El@1 | Acc]); _ -> {Acc, Children} end. -file("src/molt/internal/parser.gleam", 684). ?DOC(false). -spec do_group_inline_forward( list(greenwood:element(molt@types:toml_kind())), list(greenwood:token(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind())) ) -> list(greenwood:element(molt@types:toml_kind())). do_group_inline_forward(Children, Trivia_acc, Entry_acc, Result) -> case Children of [] -> flush_inline_entry(Trivia_acc, Entry_acc, Result); [{token_element, {token, left_brace, _}} | Rest] -> do_group_inline_forward( Rest, Trivia_acc, Entry_acc, [{token_element, {token, left_brace, <<""/utf8>>}} | Result] ); [{token_element, {token, right_brace, _}} | Rest@1] -> Result@1 = flush_inline_entry(Trivia_acc, Entry_acc, Result), do_group_inline_forward( Rest@1, [], [], [{token_element, {token, right_brace, <<""/utf8>>}} | Result@1] ); [{token_element, {token, comma, _} = Tok} | Rest@2] -> Entry_acc@1 = [{token_element, Tok} | Entry_acc], {Entry_acc@2, Rest@3} = take_same_line(Rest@2, Entry_acc@1), Result@2 = flush_inline_entry(Trivia_acc, Entry_acc@2, Result), do_group_inline_forward(Rest@3, [], [], Result@2); [{token_element, {token, comment, _} = Tok@1} | Rest@4] -> case Entry_acc of [] -> do_group_inline_forward( Rest@4, [Tok@1 | Trivia_acc], [], Result ); _ -> do_group_inline_forward( Rest@4, Trivia_acc, [{token_element, Tok@1} | Entry_acc], Result ) end; [{token_element, {token, newline, _} = Tok@2} | Rest@5] -> case Entry_acc of [] -> do_group_inline_forward( Rest@5, [Tok@2 | Trivia_acc], [], Result ); _ -> Entry_acc@3 = [{token_element, Tok@2} | Entry_acc], Result@3 = flush_inline_entry( Trivia_acc, Entry_acc@3, Result ), do_group_inline_forward(Rest@5, [], [], Result@3) end; [{token_element, {token, whitespace, _} = Tok@3} | Rest@6] -> case Entry_acc of [] -> do_group_inline_forward( Rest@6, [Tok@3 | Trivia_acc], [], Result ); _ -> do_group_inline_forward( Rest@6, Trivia_acc, [{token_element, Tok@3} | Entry_acc], Result ) end; [El | Rest@7] -> do_group_inline_forward( Rest@7, Trivia_acc, [El | Entry_acc], Result ) end. -file("src/molt/internal/parser.gleam", 677). ?DOC(false). -spec group_inline_table_entries( list(greenwood:element(molt@types:toml_kind())) ) -> list(greenwood:element(molt@types:toml_kind())). group_inline_table_entries(Children) -> _pipe = lists:reverse(Children), do_group_inline_forward(_pipe, [], [], []). -file("src/molt/internal/parser.gleam", 624). ?DOC(false). -spec flush_element( list(greenwood:token(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind())) ) -> list(greenwood:element(molt@types:toml_kind())). flush_element(Trivia_acc, Element_acc, Result) -> case Element_acc of [] -> case Trivia_acc of [] -> Result; _ -> gleam@list:fold( lists:reverse(Trivia_acc), Result, fun(Acc, Tok) -> [{token_element, Tok} | Acc] end ) end; _ -> {Children, Trailing} = molt@internal@parser@core:peel_trailing_comment_rev( Element_acc ), Trivia = case {Trivia_acc, Trailing} of {[], []} -> bare; {_, _} -> {trivia, Trivia_acc, Trailing} end, Node = {node, array_element, Children, Trivia}, [{node_element, Node} | Result] end. -file("src/molt/internal/parser.gleam", 514). ?DOC(false). -spec do_group_array_forward( list(greenwood:element(molt@types:toml_kind())), list(greenwood:token(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind())) ) -> list(greenwood:element(molt@types:toml_kind())). do_group_array_forward(Children, Trivia_acc, Element_acc, Result) -> case Children of [] -> flush_element(Trivia_acc, Element_acc, Result); [{token_element, {token, left_bracket, _}} | Rest] -> do_group_array_forward( Rest, Trivia_acc, Element_acc, [{token_element, {token, left_bracket, <<""/utf8>>}} | Result] ); [{token_element, {token, right_bracket, _}} | Rest@1] -> Result@1 = flush_element(Trivia_acc, Element_acc, Result), do_group_array_forward( Rest@1, [], [], [{token_element, {token, right_bracket, <<""/utf8>>}} | Result@1] ); [{token_element, {token, comment, _} = Tok} | Rest@2] -> case Element_acc of [] -> do_group_array_forward( Rest@2, [Tok | Trivia_acc], [], Result ); _ -> do_group_array_forward( Rest@2, Trivia_acc, [{token_element, Tok} | Element_acc], Result ) end; [{token_element, {token, newline, _} = Tok@1} | Rest@3] -> case Element_acc of [] -> do_group_array_forward( Rest@3, [Tok@1 | Trivia_acc], [], Result ); _ -> Result@2 = flush_element( Trivia_acc, [{token_element, Tok@1} | Element_acc], Result ), do_group_array_forward(Rest@3, [], [], Result@2) end; [{token_element, {token, whitespace, _} = Tok@2} | Rest@4] -> case Element_acc of [] -> do_group_array_forward( Rest@4, [Tok@2 | Trivia_acc], [], Result ); _ -> do_group_array_forward( Rest@4, Trivia_acc, [{token_element, Tok@2} | Element_acc], Result ) end; [{token_element, {token, comma, _} = Tok@3} | Rest@5] -> Element_acc@1 = [{token_element, Tok@3} | Element_acc], {Element_acc@2, Rest@6} = take_same_line(Rest@5, Element_acc@1), Result@3 = flush_element(Trivia_acc, Element_acc@2, Result), do_group_array_forward(Rest@6, [], [], Result@3); [El | Rest@7] -> do_group_array_forward( Rest@7, Trivia_acc, [El | Element_acc], Result ) end. -file("src/molt/internal/parser.gleam", 501). ?DOC(false). -spec group_array_elements(list(greenwood:element(molt@types:toml_kind()))) -> list(greenwood:element(molt@types:toml_kind())). group_array_elements(Children) -> _pipe = lists:reverse(Children), do_group_array_forward(_pipe, [], [], []). -file("src/molt/internal/parser.gleam", 451). ?DOC(false). -spec try_merge_datetime( list(greenwood:element(molt@types:toml_kind())), binary(), binary(), molt@internal@parser@core:splitters() ) -> {ok, {list(greenwood:element(molt@types:toml_kind())), binary()}} | {error, nil}. try_merge_datetime(Acc, Ws, Rest, Sp) -> case {Ws, Acc} of {<<" "/utf8>>, [{token_element, {token, local_date, Date_text}} | Rest_acc]} -> {Prefix, _, _} = splitter_ffi:split(erlang:element(4, Sp), Rest), gleam@bool:guard( Prefix =:= <<""/utf8>>, {error, nil}, fun() -> Combined = <<<>/binary, Prefix/binary>>, case molt@internal@classifier:match_datetime(Combined) of {some, K} -> New_rest = gleam@string:drop_start( Rest, string:length(Prefix) ), {ok, {[{token_element, {token, K, Combined}} | Rest_acc], New_rest}}; none -> {error, nil} end end ); {_, _} -> {error, nil} end. -file("src/molt/internal/parser.gleam", 436). ?DOC(false). -spec emit_value_prefix( binary(), list(greenwood:element(molt@types:toml_kind())) ) -> list(greenwood:element(molt@types:toml_kind())). emit_value_prefix(Prefix, Acc) -> case Prefix of <<""/utf8>> -> Acc; _ -> [{token_element, molt@internal@parser@core:tokenize_value(Prefix)} | Acc] end. -file("src/molt/internal/parser.gleam", 1181). ?DOC(false). -spec pull_next_line_inline_table( molt@internal@parser@core:splitters(), list(greenwood:element(molt@types:toml_kind())), binary(), binary(), boolean() ) -> {list(greenwood:element(molt@types:toml_kind())), binary(), binary(), binary()}. pull_next_line_inline_table(Sp, Acc, Pending_nl, Source_rest, After_eq) -> Acc@1 = case Pending_nl of <<""/utf8>> -> Acc; _ -> [{token_element, {token, newline, Pending_nl}} | Acc] end, case Source_rest of <<""/utf8>> -> {Acc@1, <<""/utf8>>, <<""/utf8>>, <<""/utf8>>}; _ -> {Next_line, Pending_nl@1, Source_rest@1} = splitter_ffi:split( erlang:element(2, Sp), Source_rest ), do_consume_inline_table( Sp, Next_line, Acc@1, Pending_nl@1, Source_rest@1, After_eq ) end. -file("src/molt/internal/parser.gleam", 984). ?DOC(false). -spec pull_next_line_array( molt@internal@parser@core:splitters(), list(greenwood:element(molt@types:toml_kind())), binary(), binary() ) -> {list(greenwood:element(molt@types:toml_kind())), binary(), binary(), binary()}. pull_next_line_array(Sp, Acc, Pending_nl, Source_rest) -> Acc@1 = case Pending_nl of <<""/utf8>> -> Acc; _ -> [{token_element, {token, newline, Pending_nl}} | Acc] end, case Source_rest of <<""/utf8>> -> {Acc@1, <<""/utf8>>, <<""/utf8>>, <<""/utf8>>}; _ -> {Next_line, Next_nl, More_rest} = splitter_ffi:split( erlang:element(2, Sp), Source_rest ), do_consume_array(Sp, Next_line, Acc@1, Next_nl, More_rest) end. -file("src/molt/internal/parser.gleam", 952). ?DOC(false). -spec consume_array_after_whitespace( molt@internal@parser@core:splitters(), binary(), list(greenwood:element(molt@types:toml_kind())), binary(), binary(), binary() ) -> {list(greenwood:element(molt@types:toml_kind())), binary(), binary(), binary()}. consume_array_after_whitespace(Sp, Input, Acc, Pending_nl, Source_rest, Delim) -> {Ws, Rest} = molt@internal@parser@core:scan_ws(Delim, Input), case try_merge_datetime(Acc, Ws, Rest, Sp) of {ok, {Merged_acc, Rest@1}} -> do_consume_array(Sp, Rest@1, Merged_acc, Pending_nl, Source_rest); {error, nil} -> do_consume_array( Sp, Rest, [{token_element, {token, whitespace, Ws}} | Acc], Pending_nl, Source_rest ) end. -file("src/molt/internal/parser.gleam", 815). ?DOC(false). -spec do_consume_array( molt@internal@parser@core:splitters(), binary(), list(greenwood:element(molt@types:toml_kind())), binary(), binary() ) -> {list(greenwood:element(molt@types:toml_kind())), binary(), binary(), binary()}. do_consume_array(Sp, Input, Acc, Pending_nl, Source_rest) -> case Input of <<""/utf8>> -> pull_next_line_array(Sp, Acc, Pending_nl, Source_rest); _ -> {Prefix, Delim, Rest} = splitter_ffi:split( erlang:element(4, Sp), Input ), Acc@1 = emit_value_prefix(Prefix, Acc), case Delim of <<""/utf8>> -> pull_next_line_array(Sp, Acc@1, Pending_nl, Source_rest); <<"]"/utf8>> -> {[{token_element, {token, right_bracket, <<""/utf8>>}} | Acc@1], Rest, Pending_nl, Source_rest}; <<","/utf8>> -> do_consume_array( Sp, Rest, [{token_element, {token, comma, <<""/utf8>>}} | Acc@1], Pending_nl, Source_rest ); <<" "/utf8>> -> consume_array_after_whitespace( Sp, Rest, Acc@1, Pending_nl, Source_rest, Delim ); <<"\t"/utf8>> -> consume_array_after_whitespace( Sp, Rest, Acc@1, Pending_nl, Source_rest, Delim ); <<"["/utf8>> -> {Nested, Rem, Rem_nl, Rem_rest} = consume_array( Sp, Rest, Pending_nl, Source_rest ), do_consume_array( Sp, Rem, [{node_element, Nested} | Acc@1], Rem_nl, Rem_rest ); <<"{"/utf8>> -> {Nested@1, Rem@1, Rem_nl@1, Rem_rest@1} = consume_inline_table( Sp, Rest, Pending_nl, Source_rest ), do_consume_array( Sp, Rem@1, [{node_element, Nested@1} | Acc@1], Rem_nl@1, Rem_rest@1 ); <<"\""/utf8>> -> {Tok_, Rem@2, Rem_nl@2, Rem_rest@2} = molt@internal@parser@scanners:scan_basic_string( Sp, Rest, Pending_nl, Source_rest ), do_consume_array( Sp, Rem@2, [{token_element, Tok_} | Acc@1], Rem_nl@2, Rem_rest@2 ); <<"'"/utf8>> -> {Tok_@1, Rem@3, Rem_nl@3, Rem_rest@3} = molt@internal@parser@scanners:scan_literal_string( Sp, Rest, Pending_nl, Source_rest ), do_consume_array( Sp, Rem@3, [{token_element, Tok_@1} | Acc@1], Rem_nl@3, Rem_rest@3 ); <<"#"/utf8>> -> Acc@2 = [{token_element, {token, comment, <<"#"/utf8, Rest/binary>>}} | Acc@1], pull_next_line_array(Sp, Acc@2, Pending_nl, Source_rest); <<"="/utf8>> -> do_consume_array( Sp, Rest, [{token_element, {token, invalid_value, <<"="/utf8>>}} | Acc@1], Pending_nl, Source_rest ); _ -> do_consume_array(Sp, Rest, Acc@1, Pending_nl, Source_rest) end end. -file("src/molt/internal/parser.gleam", 478). ?DOC(false). -spec consume_array( molt@internal@parser@core:splitters(), binary(), binary(), binary() ) -> {greenwood:node_(molt@types:toml_kind()), binary(), binary(), binary()}. consume_array(Sp, Input, Pending_nl, Source_rest) -> {Children_rev, Rem, Rem_nl, Rem_rest} = do_consume_array( Sp, Input, [{token_element, {token, left_bracket, <<""/utf8>>}}], Pending_nl, Source_rest ), Children_rev@1 = group_array_elements(Children_rev), Node = greenwood:node(array, Children_rev@1), {Node, Rem, Rem_nl, Rem_rest}. -file("src/molt/internal/parser.gleam", 1036). ?DOC(false). -spec do_consume_inline_table( molt@internal@parser@core:splitters(), binary(), list(greenwood:element(molt@types:toml_kind())), binary(), binary(), boolean() ) -> {list(greenwood:element(molt@types:toml_kind())), binary(), binary(), binary()}. do_consume_inline_table(Sp, Input, Acc, Pending_nl, Source_rest, After_eq) -> case Input of <<""/utf8>> -> pull_next_line_inline_table( Sp, Acc, Pending_nl, Source_rest, After_eq ); _ -> {Prefix, Delim, Rest} = splitter_ffi:split( erlang:element(4, Sp), Input ), Acc@1 = case {Prefix, After_eq} of {<<""/utf8>>, _} -> Acc; {_, true} -> [{token_element, molt@internal@parser@core:tokenize_value(Prefix)} | Acc]; {_, false} -> [{token_element, {token, bare_key, Prefix}} | Acc] end, case Delim of <<""/utf8>> -> pull_next_line_inline_table( Sp, Acc@1, Pending_nl, Source_rest, After_eq ); <<"}"/utf8>> -> {[{token_element, {token, right_brace, <<""/utf8>>}} | Acc@1], Rest, Pending_nl, Source_rest}; <<","/utf8>> -> do_consume_inline_table( Sp, Rest, [{token_element, {token, comma, <<""/utf8>>}} | Acc@1], Pending_nl, Source_rest, false ); <<" "/utf8>> -> {Ws, Rest_after} = molt@internal@parser@core:scan_ws( Delim, Rest ), do_consume_inline_table( Sp, Rest_after, [{token_element, {token, whitespace, Ws}} | Acc@1], Pending_nl, Source_rest, After_eq ); <<"\t"/utf8>> -> {Ws, Rest_after} = molt@internal@parser@core:scan_ws( Delim, Rest ), do_consume_inline_table( Sp, Rest_after, [{token_element, {token, whitespace, Ws}} | Acc@1], Pending_nl, Source_rest, After_eq ); <<"="/utf8>> -> do_consume_inline_table( Sp, Rest, [{token_element, {token, equals, <<""/utf8>>}} | Acc@1], Pending_nl, Source_rest, true ); <<"["/utf8>> -> {Nested, Input@1, Pending_nl@1, Source_rest@1} = consume_array( Sp, Rest, Pending_nl, Source_rest ), do_consume_inline_table( Sp, Input@1, [{node_element, Nested} | Acc@1], Pending_nl@1, Source_rest@1, After_eq ); <<"{"/utf8>> -> {Nested@1, Input@2, Pending_nl@2, Source_rest@2} = consume_inline_table( Sp, Rest, Pending_nl, Source_rest ), do_consume_inline_table( Sp, Input@2, [{node_element, Nested@1} | Acc@1], Pending_nl@2, Source_rest@2, After_eq ); <<"\""/utf8>> -> {Tok_, Input@3, Pending_nl@3, Source_rest@3} = molt@internal@parser@scanners:scan_basic_string( Sp, Rest, Pending_nl, Source_rest ), do_consume_inline_table( Sp, Input@3, [{token_element, Tok_} | Acc@1], Pending_nl@3, Source_rest@3, After_eq ); <<"'"/utf8>> -> {Tok_@1, Input@4, Pending_nl@4, Source_rest@4} = molt@internal@parser@scanners:scan_literal_string( Sp, Rest, Pending_nl, Source_rest ), do_consume_inline_table( Sp, Input@4, [{token_element, Tok_@1} | Acc@1], Pending_nl@4, Source_rest@4, After_eq ); <<"#"/utf8>> -> Acc@2 = [{token_element, {token, comment, <<"#"/utf8, Rest/binary>>}} | Acc@1], pull_next_line_inline_table( Sp, Acc@2, Pending_nl, Source_rest, After_eq ); _ -> do_consume_inline_table( Sp, Rest, Acc@1, Pending_nl, Source_rest, After_eq ) end end. -file("src/molt/internal/parser.gleam", 1012). ?DOC(false). -spec consume_inline_table( molt@internal@parser@core:splitters(), binary(), binary(), binary() ) -> {greenwood:node_(molt@types:toml_kind()), binary(), binary(), binary()}. consume_inline_table(Sp, Input, Pending_nl, Source_rest) -> {Children_rev, Rem, Rem_nl, Rem_rest} = do_consume_inline_table( Sp, Input, [{token_element, {token, left_brace, <<""/utf8>>}}], Pending_nl, Source_rest, false ), Children_rev@1 = group_inline_table_entries(Children_rev), Node = greenwood:node(inline_table, Children_rev@1), {Node, Rem, Rem_nl, Rem_rest}. -file("src/molt/internal/parser.gleam", 921). ?DOC(false). -spec consume_value_after_whitespace( molt@internal@parser@core:splitters(), binary(), list(greenwood:element(molt@types:toml_kind())), binary(), binary(), binary() ) -> {list(greenwood:element(molt@types:toml_kind())), binary(), binary()}. consume_value_after_whitespace(Sp, Input, Acc, Pending_nl, Source_rest, Delim) -> begin {Ws, Rest} = molt@internal@parser@core:scan_ws(Delim, Input), case try_merge_datetime(Acc, Ws, Rest, Sp) of {ok, {Merged_acc, New_rest}} -> consume_value(Sp, New_rest, Merged_acc, Pending_nl, Source_rest); {error, nil} -> consume_value( Sp, Rest, [{token_element, {token, whitespace, Ws}} | Acc], Pending_nl, Source_rest ) end end. -file("src/molt/internal/parser.gleam", 321). ?DOC(false). -spec consume_value( molt@internal@parser@core:splitters(), binary(), list(greenwood:element(molt@types:toml_kind())), binary(), binary() ) -> {list(greenwood:element(molt@types:toml_kind())), binary(), binary()}. consume_value(Sp, Input, Acc, Pending_nl, Source_rest) -> case Input of <<""/utf8>> -> {Acc, Pending_nl, Source_rest}; _ -> {Prefix, Delim, Rest} = splitter_ffi:split( erlang:element(4, Sp), Input ), Acc@1 = emit_value_prefix(Prefix, Acc), case Delim of <<""/utf8>> -> {Acc@1, Pending_nl, Source_rest}; <<" "/utf8>> -> consume_value_after_whitespace( Sp, Rest, Acc@1, Pending_nl, Source_rest, Delim ); <<"\t"/utf8>> -> consume_value_after_whitespace( Sp, Rest, Acc@1, Pending_nl, Source_rest, Delim ); <<"["/utf8>> -> {Node, Rem, Rem_nl, Rem_rest} = consume_array( Sp, Rest, Pending_nl, Source_rest ), consume_value( Sp, Rem, [{node_element, Node} | Acc@1], Rem_nl, Rem_rest ); <<"{"/utf8>> -> {Node@1, Rem@1, Rem_nl@1, Rem_rest@1} = consume_inline_table( Sp, Rest, Pending_nl, Source_rest ), consume_value( Sp, Rem@1, [{node_element, Node@1} | Acc@1], Rem_nl@1, Rem_rest@1 ); <<"\""/utf8>> -> {Tok_, Rem@2, Rem_nl@2, Rem_rest@2} = molt@internal@parser@scanners:scan_basic_string( Sp, Rest, Pending_nl, Source_rest ), consume_value( Sp, Rem@2, [{token_element, Tok_} | Acc@1], Rem_nl@2, Rem_rest@2 ); <<"'"/utf8>> -> {Tok_@1, Rem@3, Rem_nl@3, Rem_rest@3} = molt@internal@parser@scanners:scan_literal_string( Sp, Rest, Pending_nl, Source_rest ), consume_value( Sp, Rem@3, [{token_element, Tok_@1} | Acc@1], Rem_nl@3, Rem_rest@3 ); <<"#"/utf8>> -> {[{token_element, {token, comment, <<"#"/utf8, Rest/binary>>}} | Acc@1], Pending_nl, Source_rest}; <<","/utf8>> -> consume_value( Sp, Rest, [{token_element, {token, comma, <<""/utf8>>}} | Acc@1], Pending_nl, Source_rest ); <<"]"/utf8>> -> consume_value( Sp, Rest, [{token_element, {token, right_bracket, <<""/utf8>>}} | Acc@1], Pending_nl, Source_rest ); <<"}"/utf8>> -> consume_value( Sp, Rest, [{token_element, {token, right_brace, <<""/utf8>>}} | Acc@1], Pending_nl, Source_rest ); <<"="/utf8>> -> consume_value( Sp, Rest, [{token_element, {token, equals, <<""/utf8>>}} | Acc@1], Pending_nl, Source_rest ); _ -> consume_value(Sp, Rest, Acc@1, Pending_nl, Source_rest) end end. -file("src/molt/internal/parser.gleam", 222). ?DOC(false). -spec handle_kv_line( molt@internal@parser@core:state(), binary(), binary(), binary() ) -> {molt@internal@parser@core:state(), binary()}. handle_kv_line(State, Line, Nl, Source_rest) -> {Children_rev, After_eq} = molt@internal@parser@scanners:consume_key_and_eq( erlang:element(2, State), Line, [] ), {Children_rev@1, Final_nl, Final_rest} = consume_value( erlang:element(2, State), After_eq, Children_rev, Nl, Source_rest ), Children_rev@2 = case Final_nl of <<""/utf8>> -> Children_rev@1; _ -> [{token_element, {token, newline, Final_nl}} | Children_rev@1] end, Children_rev@3 = wrap_dotted_key(Children_rev@2), Full = greenwood:node(key_value, Children_rev@3), {Leading, State@1} = head_split(State), Node = case is_valid_kv(Full) of true -> {Clean_rev, Trailing} = molt@internal@parser@core:peel_trailing_comment_rev( Children_rev@3 ), attach_line_trivia( greenwood:node(key_value, Clean_rev), Leading, Trailing ); false -> _pipe = greenwood:node(error, [{node_element, Full}]), attach_pending_trivia(_pipe, Leading) end, State@2 = {state, erlang:element(2, State@1), [], erlang:element(4, State@1), erlang:element(5, State@1), erlang:element(6, State@1), erlang:element(7, State@1), erlang:element(8, State@1)}, {add_kv(State@2, Node), Final_rest}. -file("src/molt/internal/parser.gleam", 169). ?DOC(false). -spec handle_table_line( molt@internal@parser@core:state(), molt@types:toml_kind(), binary(), binary() ) -> molt@internal@parser@core:state(). handle_table_line(State, Kind, Line, Nl) -> Doc_acc = molt@internal@parser@core:flush_current_table(State), Header = molt@internal@parser@scanners:tokenize_header_line( erlang:element(2, State), Line, [] ), Header@1 = case Nl of <<""/utf8>> -> Header; _ -> [greenwood:token(newline, Nl) | Header] end, {Children, Trailing} = molt@internal@parser@core:peel_trailing_comment_rev( gleam@list:map(Header@1, fun(Field@0) -> {token_element, Field@0} end) ), {Leading, State@1} = head_split(State), {state, erlang:element(2, State@1), [], erlang:element(4, State@1), erlang:element(5, State@1), Doc_acc, {building, Kind, Children, Leading, Trailing}, erlang:element(8, State@1)}. -file("src/molt/internal/parser.gleam", 147). ?DOC(false). -spec handle_comment_line(molt@internal@parser@core:state(), binary(), binary()) -> molt@internal@parser@core:state(). handle_comment_line(State, Line, Nl) -> {Pending, Rest@2} = case molt@internal@parser@core:take_ws(Line) of {<<""/utf8>>, Rest} -> {erlang:element(3, State), Rest}; {Ws, Rest@1} -> {[greenwood:token(whitespace, Ws) | erlang:element(3, State)], Rest@1} end, Pending@1 = [greenwood:token(comment, Rest@2) | Pending], Pending@2 = case Nl of <<""/utf8>> -> Pending@1; _ -> [greenwood:token(newline, Nl) | Pending@1] end, {state, erlang:element(2, State), Pending@2, erlang:element(4, State), erlang:element(5, State), erlang:element(6, State), erlang:element(7, State), erlang:element(8, State)}. -file("src/molt/internal/parser.gleam", 131). ?DOC(false). -spec handle_blank_line(molt@internal@parser@core:state(), binary(), binary()) -> molt@internal@parser@core:state(). handle_blank_line(State, Line, Nl) -> Pending = case Line of <<""/utf8>> -> erlang:element(3, State); _ -> [greenwood:token(whitespace, Line) | erlang:element(3, State)] end, Pending@1 = case Nl of <<""/utf8>> -> Pending; _ -> [greenwood:token(newline, Nl) | Pending] end, {state, erlang:element(2, State), Pending@1, erlang:element(4, State), erlang:element(5, State), erlang:element(6, State), erlang:element(7, State), erlang:element(8, State)}. -file("src/molt/internal/parser.gleam", 110). ?DOC(false). -spec dispatch_line( molt@internal@parser@core:state(), {binary(), binary(), binary()} ) -> {molt@internal@parser@core:state(), binary()}. dispatch_line(State, Split_line) -> {Line, Nl, Rest} = Split_line, case molt@internal@parser@core:peek_first_significant(Line) of <<""/utf8>> -> {handle_blank_line(State, Line, Nl), Rest}; <<"#"/utf8, _/binary>> -> {handle_comment_line(State, Line, Nl), Rest}; <<"[["/utf8, _/binary>> -> {handle_table_line(State, array_of_tables, Line, Nl), Rest}; <<"["/utf8, _/binary>> -> {handle_table_line(State, table, Line, Nl), Rest}; _ -> handle_kv_line(State, Line, Nl, Rest) end. -file("src/molt/internal/parser.gleam", 106). ?DOC(false). -spec process_line(molt@internal@parser@core:state(), binary()) -> {molt@internal@parser@core:state(), binary()}. process_line(State, Input) -> dispatch_line( State, splitter_ffi:split(erlang:element(2, erlang:element(2, State)), Input) ). -file("src/molt/internal/parser.gleam", 94). ?DOC(false). -spec do_parse(molt@internal@parser@core:state(), binary()) -> {ok, greenwood:node_(molt@types:toml_kind())} | {error, molt@error:molt_error()}. do_parse(State, Input) -> gleam@result:'try'( erlang:element(8, State), fun(_use0) -> nil = _use0, case Input of <<""/utf8>> -> molt@internal@parser@core:finalize(State); _ -> {State@1, Remaining} = process_line(State, Input), do_parse(State@1, Remaining) end end ). -file("src/molt/internal/parser.gleam", 73). ?DOC(false). -spec do_scan_control(splitter:splitter(), binary(), integer()) -> {ok, nil} | {error, molt@error:molt_error()}. do_scan_control(Controls, Input, Offset) -> {Prefix, Delim, Input@1} = splitter_ffi:split(Controls, Input), Here = Offset + erlang:byte_size(Prefix), case Delim of <<""/utf8>> -> {ok, nil}; <<"\x{FEFF}"/utf8>> -> {error, {parse_error, <<"BOM not at start of file"/utf8>>, Here}}; <<"\x{0000}"/utf8>> -> {error, {parse_error, <<"Null byte in input"/utf8>>, Here}}; <<"\r"/utf8>> -> case Input@1 of <<"\n"/utf8, More/binary>> -> do_scan_control(Controls, More, Here + 2); _ -> {error, {parse_error, <<"Bare carriage return"/utf8>>, Here}} end; _ -> {error, {parse_error, <<"Forbidden control character"/utf8>>, Here}} end. -file("src/molt/internal/parser.gleam", 61). ?DOC(false). -spec scan_control(binary()) -> {ok, nil} | {error, molt@error:molt_error()}. scan_control(Source) -> _pipe = splitter:new( [<<"\x{0000}"/utf8>>, <<"\x{0001}"/utf8>>, <<"\x{0002}"/utf8>>, <<"\x{0003}"/utf8>>, <<"\x{0004}"/utf8>>, <<"\x{0005}"/utf8>>, <<"\x{0006}"/utf8>>, <<"\x{0007}"/utf8>>, <<"\x{0008}"/utf8>>, <<"\x{000B}"/utf8>>, <<"\x{000C}"/utf8>>, <<"\x{000E}"/utf8>>, <<"\x{000F}"/utf8>>, <<"\x{0010}"/utf8>>, <<"\x{0011}"/utf8>>, <<"\x{0012}"/utf8>>, <<"\x{0013}"/utf8>>, <<"\x{0014}"/utf8>>, <<"\x{0015}"/utf8>>, <<"\x{0016}"/utf8>>, <<"\x{0017}"/utf8>>, <<"\x{0018}"/utf8>>, <<"\x{0019}"/utf8>>, <<"\x{001A}"/utf8>>, <<"\x{001B}"/utf8>>, <<"\x{001C}"/utf8>>, <<"\x{001D}"/utf8>>, <<"\x{001E}"/utf8>>, <<"\x{001F}"/utf8>>, <<"\x{007F}"/utf8>>, <<"\x{FEFF}"/utf8>>, <<"\r"/utf8>>] ), do_scan_control(_pipe, Source, 0). -file("src/molt/internal/parser.gleam", 47). ?DOC(false). -spec parse(binary()) -> {ok, greenwood:node_(molt@types:toml_kind())} | {error, molt@error:molt_error()}. parse(Source) -> {Bom, Source@1} = case Source of <<"\x{FEFF}"/utf8, Rest/binary>> -> {<<"\x{FEFF}"/utf8>>, Rest}; _ -> {<<""/utf8>>, Source} end, gleam@result:'try'( scan_control(Source@1), fun(_) -> _pipe = molt@internal@parser@core:new_state(Bom), do_parse(_pipe, Source@1) end ).