-module(molt@internal@parser@core). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/molt/internal/parser/core.gleam"). -export([new_state/1, peek_first_significant/1, take_ws/1, scan_ws/2, tokenize_value/1, flush_current_table/1, finalize/1, peel_head_block/1, peel_trailing_comment_rev/1]). -export_type([splitters/0, current_table/0, state/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 splitters() :: {splitters, splitter:splitter(), splitter:splitter(), splitter:splitter(), splitter:splitter(), splitter:splitter(), splitter:splitter(), splitter:splitter()}. -type current_table() :: no_table | {building, molt@types:toml_kind(), list(greenwood:element(molt@types:toml_kind())), list(greenwood:token(molt@types:toml_kind())), list(greenwood:token(molt@types:toml_kind()))}. -type state() :: {state, splitters(), list(greenwood:token(molt@types:toml_kind())), list(greenwood:token(molt@types:toml_kind())), list(greenwood:token(molt@types:toml_kind())), list(greenwood:element(molt@types:toml_kind())), current_table(), {ok, nil} | {error, molt@error:molt_error()}}. -file("src/molt/internal/parser/core.gleam", 335). ?DOC(false). -spec new_splitters() -> splitters(). new_splitters() -> {splitters, splitter:new([<<"\r\n"/utf8>>, <<"\n"/utf8>>, <<"\r"/utf8>>]), splitter:new( [<<"="/utf8>>, <<"."/utf8>>, <<" "/utf8>>, <<"\t"/utf8>>, <<"\""/utf8>>, <<"'"/utf8>>, <<"["/utf8>>, <<"]"/utf8>>, <<"#"/utf8>>] ), splitter:new( [<<","/utf8>>, <<"["/utf8>>, <<"]"/utf8>>, <<"{"/utf8>>, <<"}"/utf8>>, <<"\""/utf8>>, <<"'"/utf8>>, <<"#"/utf8>>, <<" "/utf8>>, <<"\t"/utf8>>, <<"="/utf8>>] ), splitter:new([<<"\\"/utf8>>, <<"\""/utf8>>]), splitter:new([<<"'"/utf8>>]), splitter:new([<<"\"\"\""/utf8>>, <<"\\"/utf8>>]), splitter:new([<<"'''"/utf8>>])}. -file("src/molt/internal/parser/core.gleam", 60). ?DOC(false). -spec new_state(binary()) -> state(). new_state(Bom) -> Bom@1 = case Bom of <<"\x{FEFF}"/utf8>> -> [greenwood:token(bom, <<"\x{FEFF}"/utf8>>)]; _ -> [] end, {state, new_splitters(), [], [], Bom@1, [], no_table, {ok, nil}}. -file("src/molt/internal/parser/core.gleam", 77). ?DOC(false). -spec peek_first_significant(binary()) -> binary(). peek_first_significant(Line) -> case Line of <<" "/utf8, R/binary>> -> peek_first_significant(R); <<"\t"/utf8, R/binary>> -> peek_first_significant(R); _ -> Line end. -file("src/molt/internal/parser/core.gleam", 310). ?DOC(false). -spec do_scan_ws(binary(), list(binary())) -> {binary(), binary()}. do_scan_ws(Input, Acc) -> case {Input, Acc} of {<<" "/utf8, Rest/binary>>, _} -> do_scan_ws(Rest, [<<" "/utf8>> | Acc]); {<<"\t"/utf8, Rest@1/binary>>, _} -> do_scan_ws(Rest@1, [<<"\t"/utf8>> | Acc]); {_, []} -> {<<""/utf8>>, Input}; {_, _} -> {molt@internal@utils:reverse_concat(Acc), Input} end. -file("src/molt/internal/parser/core.gleam", 86). ?DOC(false). -spec take_ws(binary()) -> {binary(), binary()}. take_ws(Input) -> do_scan_ws(Input, []). -file("src/molt/internal/parser/core.gleam", 93). ?DOC(false). -spec scan_ws(binary(), binary()) -> {binary(), binary()}. scan_ws(First, Rest) -> do_scan_ws(Rest, [First]). -file("src/molt/internal/parser/core.gleam", 99). ?DOC(false). -spec tokenize_value(binary()) -> greenwood:token(molt@types:toml_kind()). tokenize_value(Text) -> _pipe = molt@internal@classifier:match_type(Text), _pipe@1 = gleam@option:map( _pipe, fun(_capture) -> greenwood:token(_capture, Text) end ), gleam@option:lazy_unwrap( _pipe@1, fun() -> greenwood:token(invalid_value, Text) end ). -file("src/molt/internal/parser/core.gleam", 145). ?DOC(false). -spec prepend_bom( greenwood:node_(molt@types:toml_kind()), list(greenwood:token(molt@types:toml_kind())) ) -> greenwood:node_(molt@types:toml_kind()). prepend_bom(Node, Bom) -> case Bom of [] -> Node; _ -> {Leading@1, Trailing@1} = case erlang:element(4, Node) of bare -> {[], []}; {trivia, Leading, Trailing} -> {Leading, Trailing} end, {node, erlang:element(2, Node), erlang:element(3, Node), {trivia, lists:append(Bom, Leading@1), Trailing@1}} end. -file("src/molt/internal/parser/core.gleam", 303). ?DOC(false). -spec reverse_element(greenwood:element(molt@types:toml_kind())) -> greenwood:element(molt@types:toml_kind()). reverse_element(El) -> case El of {token_element, _} -> El; {node_element, N} -> {node_element, reverse_tree(N)} end. -file("src/molt/internal/parser/core.gleam", 289). ?DOC(false). -spec reverse_tree(greenwood:node_(molt@types:toml_kind())) -> greenwood:node_(molt@types:toml_kind()). reverse_tree(Node) -> Children = begin _pipe = erlang:element(3, Node), _pipe@1 = lists:reverse(_pipe), gleam@list:map(_pipe@1, fun reverse_element/1) end, Trivia = case erlang:element(4, Node) of bare -> bare; {trivia, L, T} -> {trivia, lists:reverse(L), lists:reverse(T)} end, {node, erlang:element(2, Node), Children, Trivia}. -file("src/molt/internal/parser/core.gleam", 166). ?DOC(false). -spec root_node( list(greenwood:element(molt@types:toml_kind())), list(greenwood:token(molt@types:toml_kind())) ) -> greenwood:node_(molt@types:toml_kind()). root_node(Children, Leading) -> case Leading of [] -> greenwood:node(root, Children); _ -> greenwood:node_with_trivia(root, Children, {trivia, Leading, []}) end. -file("src/molt/internal/parser/core.gleam", 319). ?DOC(false). -spec flush_current_table(state()) -> list(greenwood:element(molt@types:toml_kind())). flush_current_table(State) -> case erlang:element(7, State) of no_table -> erlang:element(6, State); {building, Kind, Children, Leading, Trailing} -> Trivia = case {Leading, Trailing} of {[], []} -> bare; {_, _} -> {trivia, Leading, Trailing} end, [{node_element, greenwood:node_with_trivia(Kind, Children, Trivia)} | erlang:element(6, State)] end. -file("src/molt/internal/parser/core.gleam", 105). ?DOC(false). -spec finalize(state()) -> {ok, greenwood:node_(molt@types:toml_kind())} | {error, any()}. finalize(State) -> Doc = flush_current_table(State), Node = case {Doc, erlang:element(3, State)} of {_, []} -> root_node(Doc, erlang:element(4, State)); {[], Pending} -> root_node([], Pending); {_, Pending@1} -> Postscript = greenwood:node_with_trivia( post_script, [], {trivia, Pending@1, []} ), root_node( [{node_element, Postscript} | Doc], erlang:element(4, State) ) end, _pipe = Node, _pipe@1 = reverse_tree(_pipe), _pipe@2 = prepend_bom(_pipe@1, erlang:element(5, State)), {ok, _pipe@2}. -file("src/molt/internal/parser/core.gleam", 248). ?DOC(false). -spec is_comment_line(list(greenwood:token(molt@types:toml_kind()))) -> boolean(). is_comment_line(Line) -> gleam@list:any(Line, fun(T) -> erlang:element(2, T) =:= comment end). -file("src/molt/internal/parser/core.gleam", 239). ?DOC(false). -spec split_off_node_block(list(list(greenwood:token(molt@types:toml_kind())))) -> {list(list(greenwood:token(molt@types:toml_kind()))), list(list(greenwood:token(molt@types:toml_kind())))}. split_off_node_block(Lines) -> Rev = lists:reverse(Lines), Node_rev = gleam@list:take_while(Rev, fun is_comment_line/1), Root_rev = gleam@list:drop(Rev, erlang:length(Node_rev)), {lists:reverse(Root_rev), lists:reverse(Node_rev)}. -file("src/molt/internal/parser/core.gleam", 211). ?DOC(false). -spec do_group_lines( list(greenwood:token(molt@types:toml_kind())), list(greenwood:token(molt@types:toml_kind())), list(list(greenwood:token(molt@types:toml_kind()))) ) -> list(list(greenwood:token(molt@types:toml_kind()))). do_group_lines(Tokens, Current_rev, Acc_rev) -> case Tokens of [] -> case Current_rev of [] -> lists:reverse(Acc_rev); _ -> lists:reverse([lists:reverse(Current_rev) | Acc_rev]) end; [T | Rest] -> Current_rev@1 = [T | Current_rev], case erlang:element(2, T) of newline -> do_group_lines( Rest, [], [lists:reverse(Current_rev@1) | Acc_rev] ); _ -> do_group_lines(Rest, Current_rev@1, Acc_rev) end end. -file("src/molt/internal/parser/core.gleam", 207). ?DOC(false). -spec group_lines(list(greenwood:token(molt@types:toml_kind()))) -> list(list(greenwood:token(molt@types:toml_kind()))). group_lines(Tokens) -> do_group_lines(Tokens, [], []). -file("src/molt/internal/parser/core.gleam", 191). ?DOC(false). -spec peel_head_block(list(greenwood:token(molt@types:toml_kind()))) -> {list(greenwood:token(molt@types:toml_kind())), list(greenwood:token(molt@types:toml_kind()))}. peel_head_block(Pending_rev) -> Lines = group_lines(lists:reverse(Pending_rev)), {Root_lines, Node_lines} = split_off_node_block(Lines), case gleam@list:any(Root_lines, fun is_comment_line/1) of false -> {[], Pending_rev}; true -> {lists:reverse(lists:append(Root_lines)), lists:reverse(lists:append(Node_lines))} end. -file("src/molt/internal/parser/core.gleam", 261). ?DOC(false). -spec peel_trailing_comment_rev(list(greenwood:element(molt@types:toml_kind()))) -> {list(greenwood:element(molt@types:toml_kind())), list(greenwood:token(molt@types:toml_kind()))}. peel_trailing_comment_rev(Children_rev) -> case Children_rev of [{token_element, {token, newline, _}} = Nl, {token_element, {token, comment, _} = Comment}, {token_element, {token, whitespace, _} = Ws} | Rest] -> {[Nl | Rest], [Comment, Ws]}; [{token_element, {token, newline, _}} = Nl@1, {token_element, {token, comment, _} = Comment@1} | Rest@1] -> {[Nl@1 | Rest@1], [Comment@1]}; [{token_element, {token, comment, _} = Comment@2}, {token_element, {token, whitespace, _} = Ws@1} | Rest@2] -> {Rest@2, [Comment@2, Ws@1]}; [{token_element, {token, comment, _} = Comment@3} | Rest@3] -> {Rest@3, [Comment@3]}; _ -> {Children_rev, []} end.