-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.