-module(chomp). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([run/2, return/1, succeed/1, throw/1, fail/1, lazy/1, backtrackable/1, do/2, then/2, map/2, replace/2, map_error/2, or_error/2, replace_error/2, get_pos/0, is_at_end/0, token/1, 'end'/0, one_of/1, 'or'/2, optional/1, loop/2, until_end/1, sequence/2, many/1, many1/1, take_if/1, any/0, take_map/1, until/2, in/2, do_in/3, inspect/2]). -export_type([parser/4, step/4, state/2, committed/0, error/2, loop/2]). -opaque parser(GUW, GUX, GUY, GUZ) :: {parser, fun((state(GUY, GUZ)) -> step(GUW, GUX, GUY, GUZ))}. -type step(GVA, GVB, GVC, GVD) :: {cont, committed(), GVA, state(GVC, GVD)} | {fail, committed(), error(GVB, GVC), chomp@span:span(), list({chomp@span:span(), GVD})}. -type state(GVE, GVF) :: {state, gleam@dict:dict(integer(), chomp@lexer:token(GVE)), integer(), chomp@span:span(), list({chomp@span:span(), GVF})}. -type committed() :: {committed, boolean()}. -type error(GVG, GVH) :: {custom, GVG} | end_of_input | {expected, GVH, GVH} | {unexpected, GVH} | {bad_parser, binary()}. -type loop(GVI, GVJ) :: {continue, GVJ} | {break, GVI}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 131). -spec runwrap(state(GVZ, GWA), parser(GWD, GWE, GVZ, GWA)) -> step(GWD, GWE, GVZ, GWA). runwrap(State, Parser) -> {parser, Parse} = Parser, Parse(State). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 115). -spec run(list(chomp@lexer:token(GVK)), parser(GVN, GVO, GVK, GVP)) -> {ok, GVN} | {error, {error(GVO, GVK), chomp@span:span(), list({chomp@span:span(), GVP})}}. run(Src, Parser) -> Src@1 = gleam@list:index_fold( Src, gleam@dict:new(), fun(Dict, Tok, Idx) -> gleam@dict:insert(Dict, Idx, Tok) end ), Init = {state, Src@1, 0, {span, 1, 1, 1, 1}, []}, case runwrap(Init, Parser) of {cont, _, A, _} -> {ok, A}; {fail, _, Problem, Pos, Ctx} -> {error, {Problem, Pos, Ctx}} end. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 139). -spec next(state(GWN, GWO)) -> {gleam@option:option(GWN), state(GWN, GWO)}. next(State) -> case gleam@dict:get(erlang:element(2, State), erlang:element(3, State)) of {error, _} -> {none, State}; {ok, {token, Span, _, Tok}} -> {{some, Tok}, erlang:setelement( 4, erlang:setelement(3, State, erlang:element(3, State) + 1), Span )} end. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 180). -spec return(GWU) -> parser(GWU, any(), any(), any()). return(Value) -> {parser, fun(State) -> {cont, {committed, false}, Value, State} end}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 190). -spec succeed(GXC) -> parser(GXC, any(), any(), any()). succeed(Value) -> return(Value). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 197). -spec throw(GXK) -> parser(any(), GXK, any(), any()). throw(Error) -> {parser, fun(State) -> Error@1 = {custom, Error}, {fail, {committed, false}, Error@1, erlang:element(4, State), erlang:element(5, State)} end}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 207). -spec fail(GXS) -> parser(any(), GXS, any(), any()). fail(Error) -> throw(Error). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 214). -spec lazy(fun(() -> parser(GYA, GYB, GYC, GYD))) -> parser(GYA, GYB, GYC, GYD). lazy(Parser) -> {parser, fun(State) -> runwrap(State, Parser()) end}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 239). -spec backtrackable(parser(GYM, GYN, GYO, GYP)) -> parser(GYM, GYN, GYO, GYP). backtrackable(Parser) -> {parser, fun(State) -> case runwrap(State, Parser) of {cont, _, A, State@1} -> {cont, {committed, false}, A, State@1}; {fail, _, Problem, Pos, Ctx} -> {fail, {committed, false}, Problem, Pos, Ctx} end end}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 248). -spec should_commit(committed(), committed()) -> committed(). should_commit(A, B) -> {committed, A@1} = A, {committed, B@1} = B, {committed, A@1 orelse B@1}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 279). -spec do(parser(GYY, GYZ, GZA, GZB), fun((GYY) -> parser(GZG, GYZ, GZA, GZB))) -> parser(GZG, GYZ, GZA, GZB). do(Parser, F) -> {parser, fun(State) -> case runwrap(State, Parser) of {cont, To_a, A, State@1} -> case runwrap(State@1, F(A)) of {cont, To_b, B, State@2} -> {cont, should_commit(To_a, To_b), B, State@2}; {fail, To_b@1, Problem, Pos, Ctx} -> {fail, should_commit(To_a, To_b@1), Problem, Pos, Ctx} end; {fail, Committed, Problem@1, Pos@1, Ctx@1} -> {fail, Committed, Problem@1, Pos@1, Ctx@1} end end}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 309). -spec then(parser(HAG, HAH, HAI, HAJ), fun((HAG) -> parser(HAO, HAH, HAI, HAJ))) -> parser(HAO, HAH, HAI, HAJ). then(Parser, F) -> do(Parser, F). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 318). -spec map(parser(HAX, HAY, HAZ, HBA), fun((HAX) -> HBF)) -> parser(HBF, HAY, HAZ, HBA). map(Parser, F) -> do(Parser, fun(A) -> return(F(A)) end). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 329). -spec replace(parser(any(), HBL, HBM, HBN), HBS) -> parser(HBS, HBL, HBM, HBN). replace(Parser, B) -> map(Parser, fun(_) -> B end). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 400). -spec map_error( parser(HCJ, HCK, HCL, HCM), fun((error(HCK, HCL)) -> error(HCK, HCL)) ) -> parser(HCJ, HCK, HCL, HCM). map_error(Parser, Map) -> {parser, fun(State) -> case runwrap(State, Parser) of {fail, _, end_of_input, _, _} = Fail -> Fail; {fail, {committed, false}, Error, Pos, Ctx} -> {fail, {committed, false}, Map(Error), Pos, Ctx}; Result -> Result end end}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 358). -spec or_error(parser(HBX, HBY, HBZ, HCA), HBY) -> parser(HBX, HBY, HBZ, HCA). or_error(Parser, Error) -> map_error(Parser, fun(_) -> {custom, Error} end). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 443). -spec replace_error(parser(HCZ, HDA, HDB, HDC), HDA) -> parser(HCZ, HDA, HDB, HDC). replace_error(Parser, Error) -> {parser, fun(State) -> case runwrap(State, Parser) of {fail, Committed, _, Pos, Ctx} -> {fail, Committed, {custom, Error}, Pos, Ctx}; Result -> Result end end}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 459). -spec get_pos() -> parser(chomp@span:span(), any(), any(), any()). get_pos() -> {parser, fun(State) -> {cont, {committed, false}, erlang:element(4, State), State} end}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 467). -spec is_at_end() -> parser(boolean(), any(), any(), any()). is_at_end() -> {parser, fun(State) -> case next(State) of {{some, _}, _} -> {cont, {committed, false}, false, State}; {none, _} -> {cont, {committed, false}, true, State} end end}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 492). -spec token(HEG) -> parser(chomp@span:span(), any(), HEG, any()). token(Tok) -> {parser, fun(State) -> case next(State) of {{some, T}, State@1} when Tok =:= T -> {cont, {committed, true}, erlang:element(4, State@1), State@1}; {{some, T@1}, State@2} -> {fail, {committed, false}, {expected, Tok, T@1}, erlang:element(4, State@2), erlang:element(5, State@2)}; {none, State@3} -> {fail, {committed, false}, end_of_input, erlang:element(4, State@3), erlang:element(5, State@3)} end end}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 507). -spec 'end'() -> parser(nil, any(), any(), any()). 'end'() -> {parser, fun(State) -> case next(State) of {{some, Tok}, State@1} -> {fail, {committed, false}, {unexpected, Tok}, erlang:element(4, State@1), erlang:element(5, State@1)}; {none, _} -> {cont, {committed, false}, nil, State} end end}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 523). -spec one_of(list(parser(HEU, HEV, HEW, HEX))) -> parser(HEU, HEV, HEW, HEX). one_of(Parsers) -> {parser, fun(State) -> case Parsers of [] -> {fail, {committed, false}, {bad_parser, <<"one_of requires at least one parser"/utf8>>}, erlang:element(4, State), erlang:element(5, State)}; [Parser] -> runwrap(State, Parser); [Parser@1 | Rest] -> case runwrap(State, Parser@1) of {cont, _, _, _} = Result -> Result; {fail, {committed, true}, _, _, _} = Result@1 -> Result@1; {fail, _, _, _, _} -> runwrap(State, one_of(Rest)) end end end}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 547). -spec 'or'(parser(HFH, HFI, HFJ, HFK), HFH) -> parser(HFH, HFI, HFJ, HFK). 'or'(Parser, Default) -> one_of([Parser, return(Default)]). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 555). -spec optional(parser(HFT, HFU, HFV, HFW)) -> parser(gleam@option:option(HFT), HFU, HFV, HFW). optional(Parser) -> one_of([map(Parser, fun(Field@0) -> {some, Field@0} end), return(none)]). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 687). -spec loop_help( fun((IDA) -> parser(loop(IDM, IDA), IDF, IDG, IDH)), committed(), IDA, state(IDG, IDH) ) -> step(IDM, IDF, IDG, IDH). loop_help(F, Commit, Loop_state, State) -> case runwrap(State, F(Loop_state)) of {cont, Can_backtrack, {continue, Next_loop_state}, Next_state} -> loop_help( F, should_commit(Commit, Can_backtrack), Next_loop_state, Next_state ); {cont, Can_backtrack@1, {break, Result}, Next_state@1} -> {cont, should_commit(Commit, Can_backtrack@1), Result, Next_state@1}; {fail, Can_backtrack@2, Problem, Pos, Ctx} -> {fail, should_commit(Commit, Can_backtrack@2), Problem, Pos, Ctx} end. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 678). -spec loop(HJQ, fun((HJQ) -> parser(loop(HJR, HJQ), HJU, HJV, HJW))) -> parser(HJR, HJU, HJV, HJW). loop(Init, Step) -> {parser, fun(State) -> loop_help(Step, {committed, false}, Init, State) end}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 610). -spec until_end(parser(HHY, HHZ, HIA, HIB)) -> parser(list(HHY), HHZ, HIA, HIB). until_end(Parser) -> loop([], fun(Xs) -> do(is_at_end(), fun(Is_at_end) -> case Is_at_end of true -> return({break, lists:reverse(Xs)}); false -> do( Parser, fun(X) -> return({continue, [X | Xs]}) end ) end end) end). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 647). -spec more(HIY, parser(HIY, HIZ, HJA, HJB), parser(any(), HIZ, HJA, HJB)) -> parser(list(HIY), HIZ, HJA, HJB). more(X, Parser, Separator) -> loop( [X], fun(Xs) -> Break = fun() -> return({break, lists:reverse(Xs)}) end, Continue = (do( Separator, fun(_) -> do(Parser, fun(X@1) -> return({continue, [X@1 | Xs]}) end) end )), one_of([Continue, lazy(Break)]) end ). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 563). -spec sequence(parser(HGG, HGH, HGI, HGJ), parser(any(), HGH, HGI, HGJ)) -> parser(list(HGG), HGH, HGI, HGJ). sequence(Parser, Sep) -> one_of( [begin _pipe = Parser, then(_pipe, fun(_capture) -> more(_capture, Parser, Sep) end) end, return([])] ). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 576). -spec many(parser(HGY, HGZ, HHA, HHB)) -> parser(list(HGY), HGZ, HHA, HHB). many(Parser) -> sequence(Parser, return(nil)). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 585). -spec many1(parser(HHL, HHM, HHN, HHO)) -> parser(list(HHL), HHM, HHN, HHO). many1(Parser) -> do(Parser, fun(X) -> do(many(Parser), fun(Xs) -> return([X | Xs]) end) end). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 707). -spec take_if(fun((HKK) -> boolean())) -> parser(HKK, any(), HKK, any()). take_if(Predicate) -> {parser, fun(State) -> {Tok, State@1} = next(State), case {Tok, gleam@option:map(Tok, Predicate)} of {{some, Tok@1}, {some, true}} -> {cont, {committed, true}, Tok@1, State@1}; {{some, Tok@2}, {some, false}} -> {fail, {committed, false}, {unexpected, Tok@2}, erlang:element(4, State@1), erlang:element(5, State@1)}; {_, _} -> {fail, {committed, false}, end_of_input, erlang:element(4, State@1), erlang:element(5, State@1)} end end}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 480). -spec any() -> parser(HDZ, any(), HDZ, any()). any() -> take_if(fun(_) -> true end). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 723). -spec take_map(fun((HKR) -> gleam@option:option(HKS))) -> parser(HKS, any(), HKR, any()). take_map(F) -> {parser, fun(State) -> {Tok, State@1} = next(State), case {Tok, gleam@option:then(Tok, F)} of {none, _} -> {fail, {committed, false}, end_of_input, erlang:element(4, State@1), erlang:element(5, State@1)}; {{some, Tok@1}, none} -> {fail, {committed, false}, {unexpected, Tok@1}, erlang:element(4, State@1), erlang:element(5, State@1)}; {_, {some, A}} -> {cont, {committed, true}, A, State@1} end end}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 625). -spec until(parser(HIL, HIM, HIN, HIO), HIN) -> parser(list(HIL), HIM, HIN, HIO). until(Parser, Tok) -> loop( [], fun(Xs) -> Break = take_map(fun(T) -> case T =:= Tok of true -> {some, {break, lists:reverse(Xs)}}; false -> none end end), Continue = (do(Parser, fun(X) -> return({continue, [X | Xs]}) end)), one_of([Break, Continue]) end ). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 769). -spec push_context(state(HLM, HLN), HLN) -> state(HLM, HLN). push_context(State, Context) -> erlang:setelement( 5, State, [{erlang:element(4, State), Context} | erlang:element(5, State)] ). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 773). -spec pop_context(state(HLS, HLT)) -> state(HLS, HLT). pop_context(State) -> case erlang:element(5, State) of [] -> State; [_ | Context] -> erlang:setelement(5, State, Context) end. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 757). -spec in(parser(HLA, HLB, HLC, HLD), HLD) -> parser(HLA, HLB, HLC, HLD). in(Parser, Context) -> {parser, fun(State) -> case runwrap(push_context(State, Context), Parser) of {cont, Committed, A, State@1} -> {cont, Committed, A, pop_context(State@1)}; {fail, Committed@1, Problem, Pos, Ctx} -> {fail, Committed@1, Problem, Pos, Ctx} end end}. -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 298). -spec do_in( GZP, parser(GZQ, GZR, GZS, GZP), fun((GZQ) -> parser(GZX, GZR, GZS, GZP)) ) -> parser(GZX, GZR, GZS, GZP). do_in(Context, Parser, F) -> _pipe = do(Parser, F), in(_pipe, Context). -file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 781). -spec inspect(parser(HLY, HLZ, HMA, HMB), binary()) -> parser(HLY, HLZ, HMA, HMB). inspect(Parser, Message) -> {parser, fun(State) -> gleam@io:println(<>), _pipe = runwrap(State, Parser), gleam@io:debug(_pipe) end}.