-module(gleamx@parser). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/gleamx/parser.gleam"). -export([error_to_string/1, parse/1]). -export_type([parsed/1]). -type parsed(FSL) :: {parsed, binary(), FSL}. -file("src/gleamx/parser.gleam", 215). -spec parse_until_scan(binary(), list(binary())) -> binary(). parse_until_scan(Code, Syms) -> case gleam@string:first(Code) of {ok, Sym} -> case gleam@list:contains(Syms, Sym) of true -> Code; false -> parse_until_scan( begin _pipe = Code, gleam@string:drop_start(_pipe, 1) end, Syms ) end; _ -> Code end. -file("src/gleamx/parser.gleam", 210). -spec parse_until(binary(), list(binary())) -> parsed(binary()). parse_until(Code, Syms) -> New_code = parse_until_scan(Code, Syms), {parsed, New_code, gleam@string:slice( Code, 0, string:length(Code) - string:length(New_code) )}. -file("src/gleamx/parser.gleam", 237). -spec syntax_error(binary(), gleamx@lineinfo:code_meta(), binary()) -> gleamx@ast:syntax_error(). syntax_error(Code, Meta, Msg) -> {syntax_error, gleamx@lineinfo:line_info(Code, Meta), Msg}. -file("src/gleamx/parser.gleam", 191). -spec parse_block_scan( binary(), gleamx@lineinfo:code_meta(), binary(), binary(), integer() ) -> {ok, binary()} | {error, gleamx@ast:syntax_error()}. parse_block_scan(Code, Meta, Open, Close, Depth) -> Rest = gleam@string:drop_start(Code, 1), case gleam@string:first(Code) of {error, _} -> {error, syntax_error( Rest, Meta, <<"unexpected EOF before closing the block"/utf8>> )}; {ok, X} when X =:= Open -> parse_block_scan(Rest, Meta, Open, Close, Depth + 1); {ok, X@1} when (X@1 =:= Close) andalso (Depth > 1) -> parse_block_scan(Rest, Meta, Open, Close, Depth - 1); {ok, X@2} when X@2 =:= Close -> {ok, Rest}; _ -> parse_block_scan(Rest, Meta, Open, Close, Depth) end. -file("src/gleamx/parser.gleam", 178). -spec parse_block(binary(), gleamx@lineinfo:code_meta(), binary(), binary()) -> {ok, parsed(binary())} | {error, gleamx@ast:syntax_error()}. parse_block(Code, Meta, Open, Close) -> gleam@result:'try'( parse_block_scan(Code, Meta, Open, Close, 0), fun(New_code) -> {ok, {parsed, New_code, gleam@string:slice( Code, 0, string:length(Code) - string:length(New_code) )}} end ). -file("src/gleamx/parser.gleam", 241). -spec error_to_string(gleamx@ast:syntax_error()) -> binary(). error_to_string(Error) -> erlang:element(3, Error). -file("src/gleamx/parser.gleam", 246). -spec map_parse_result( {ok, parsed(FTL)} | {error, gleamx@ast:syntax_error()}, fun((FTL) -> FTP) ) -> {ok, parsed(FTP)} | {error, gleamx@ast:syntax_error()}. map_parse_result(Res, F) -> case Res of {ok, {parsed, Code, Value}} -> {ok, {parsed, Code, F(Value)}}; {error, E} -> {error, E} end. -file("src/gleamx/parser.gleam", 226). -spec skip_spaces(binary()) -> binary(). skip_spaces(Code) -> case gleam@string:first(Code) of {ok, Sym} -> case gleam@list:contains( [<<" "/utf8>>, <<"\t"/utf8>>, <<"\n"/utf8>>, <<"\r"/utf8>>], Sym ) of true -> skip_spaces( begin _pipe = Code, gleam@string:drop_start(_pipe, 1) end ); false -> Code end; _ -> Code end. -file("src/gleamx/parser.gleam", 140). -spec parse_args(binary(), gleamx@lineinfo:code_meta()) -> {ok, parsed(list(gleamx@ast:arg()))} | {error, gleamx@ast:syntax_error()}. parse_args(Code, Meta) -> Code@1 = skip_spaces(Code), case gleam@string:first(Code@1) of {ok, <<">"/utf8>>} -> {ok, {parsed, Code@1, []}}; {ok, <<"/"/utf8>>} -> {ok, {parsed, Code@1, []}}; _ -> {parsed, Code@2, Name} = parse_until( Code@1, [<<"="/utf8>>, <<"/"/utf8>>, <<">"/utf8>> | [<<" "/utf8>>, <<"\t"/utf8>>, <<"\n"/utf8>>, <<"\r"/utf8>>]] ), Code@3 = skip_spaces(Code@2), case Code@3 of <<"="/utf8, Code@4/binary>> -> Code@5 = skip_spaces(Code@4), case Code@5 of <<"\""/utf8, Code@6/binary>> -> {parsed, Code@7, Value} = parse_until( Code@6, [<<"\""/utf8>>] ), _pipe = parse_args(Code@7, Meta), map_parse_result( _pipe, fun(Args) -> [{lit_arg, gleamx@lineinfo:line_info( Code@7, Meta ), Name, Value} | Args] end ); <<"{"/utf8, _/binary>> -> gleam@result:'try'( parse_block( Code@5, Meta, <<"{"/utf8>>, <<"}"/utf8>> ), fun(_use0) -> {parsed, Code@8, Value@1} = _use0, _pipe@1 = parse_args(Code@8, Meta), map_parse_result( _pipe@1, fun(Args@1) -> [{expr_arg, gleamx@lineinfo:line_info( Code@8, Meta ), Name, Value@1} | Args@1] end ) end ); _ -> {error, syntax_error( Code@5, Meta, <<"invalid argument value"/utf8>> )} end; _ -> parse_args(Code@3, Meta) end end. -file("src/gleamx/parser.gleam", 112). -spec parse_children(binary(), binary(), gleamx@lineinfo:code_meta()) -> {ok, parsed(list(gleamx@ast:ast()))} | {error, gleamx@ast:syntax_error()}. parse_children(Code, Parent_tag, Meta) -> Code@1 = skip_spaces(Code), case Code@1 of <<"> -> Code@3 = skip_spaces(Code@2), {parsed, Code@4, Tag} = parse_until(Code@3, [<<">"/utf8>>]), case Tag =:= Parent_tag of false -> {error, syntax_error( Code@4, Meta, <<"closing tag doesn't match opened tag"/utf8>> )}; true -> {ok, {parsed, gleam@string:drop_start(Code@4, 1), []}} end; _ -> gleam@result:'try'( parse_element(Code@1, Meta), fun(_use0) -> {parsed, Code@5, Element} = _use0, gleam@result:'try'( parse_children(Code@5, Parent_tag, Meta), fun(_use0@1) -> {parsed, Code@6, Rest} = _use0@1, {ok, {parsed, Code@6, [Element | Rest]}} end ) end ) end. -file("src/gleamx/parser.gleam", 37). -spec parse_element(binary(), gleamx@lineinfo:code_meta()) -> {ok, parsed(gleamx@ast:ast())} | {error, gleamx@ast:syntax_error()}. parse_element(Code, Meta) -> Code@1 = skip_spaces(Code), case Code@1 of <<""/utf8>> -> {error, syntax_error(Code@1, Meta, <<"unexpected EOF"/utf8>>)}; <<"<"/utf8, Code@2/binary>> -> Code@3 = skip_spaces(Code@2), Pos = gleamx@lineinfo:line_info(Code@3, Meta), {parsed, Code@4, Tag} = parse_until( Code@3, [<<"/"/utf8>>, <<">"/utf8>> | [<<" "/utf8>>, <<"\t"/utf8>>, <<"\n"/utf8>>, <<"\r"/utf8>>]] ), gleam@result:'try'( parse_args(Code@4, Meta), fun(_use0) -> {parsed, Code@5, Args} = _use0, Code@6 = skip_spaces(Code@5), case Code@6 of <<"/>"/utf8, Code@7/binary>> -> {ok, {parsed, Code@7, {container_element, Pos, Tag, Args, []}}}; <<">"/utf8, Code@8/binary>> -> case gleam@list:contains( [<<"area"/utf8>>, <<"base"/utf8>>, <<"br"/utf8>>, <<"col"/utf8>>, <<"embed"/utf8>>, <<"hr"/utf8>>, <<"img"/utf8>>, <<"input"/utf8>>, <<"link"/utf8>>, <<"meta"/utf8>>, <<"param"/utf8>>, <<"source"/utf8>>, <<"track"/utf8>>, <<"wbr"/utf8>>], Tag ) of true -> {ok, {parsed, Code@8, {void_element, Pos, Tag, Args}}}; false -> _pipe = parse_children(Code@8, Tag, Meta), map_parse_result( _pipe, fun(Children) -> {container_element, gleamx@lineinfo:line_info( Code@8, Meta ), Tag, Args, Children} end ) end; _ -> {error, syntax_error( Code@6, Meta, <<"expected '>' or '/>'"/utf8>> )} end end ); <<".."/utf8, Code@9/binary>> -> _pipe@1 = parse_element(Code@9, Meta), map_parse_result( _pipe@1, fun(Children@1) -> {spread, gleamx@lineinfo:line_info(Code@9, Meta), Children@1} end ); <<"{"/utf8, _/binary>> -> _pipe@2 = parse_block(Code@1, Meta, <<"{"/utf8>>, <<"}"/utf8>>), map_parse_result( _pipe@2, fun(Gleam_code) -> {code_block, gleamx@lineinfo:line_info(Code@1, Meta), Gleam_code} end ); _ -> {parsed, Code@10, Name} = parse_until( Code@1, [<<"("/utf8>> | [<<" "/utf8>>, <<"\t"/utf8>>, <<"\n"/utf8>>, <<"\r"/utf8>>]] ), case Code@10 of <<"("/utf8, _/binary>> -> _pipe@3 = parse_block( Code@10, Meta, <<"("/utf8>>, <<")"/utf8>> ), map_parse_result( _pipe@3, fun(Params) -> {code_block, gleamx@lineinfo:line_info(Code@10, Meta), <>} end ); _ -> {ok, {parsed, Code@10, {code_block, gleamx@lineinfo:line_info(Code@10, Meta), Name}}} end end. -file("src/gleamx/parser.gleam", 17). -spec parse_loop(binary(), gleamx@lineinfo:code_meta()) -> {ok, list(gleamx@ast:chunk())} | {error, gleamx@ast:syntax_error()}. parse_loop(Code, Meta) -> Pos = gleamx@lineinfo:line_info(Code, Meta), Rest = gleam_stdlib:crop_string(Code, <<"$"/utf8>>), case string:length(Rest) =:= string:length(Code) of true -> {ok, [{gleam_code, Pos, Code}]}; false -> Gleam_code = gleam@string:slice( Code, 0, string:length(Code) - string:length(Rest) ), gleam@result:'try'( begin _pipe = Rest, _pipe@1 = gleam@string:drop_start(_pipe, 1), parse_element(_pipe@1, Meta) end, fun(_use0) -> {parsed, Code@1, Glx_ast} = _use0, gleam@result:'try'( parse_loop(Code@1, Meta), fun(Rest@1) -> {ok, [{gleam_code, Pos, Gleam_code}, {glx_code, Glx_ast} | Rest@1]} end ) end ) end. -file("src/gleamx/parser.gleam", 13). -spec parse(binary()) -> {ok, list(gleamx@ast:chunk())} | {error, gleamx@ast:syntax_error()}. parse(Code) -> parse_loop(Code, gleamx@lineinfo:analyze_code(Code)).