-module(rexen@nfa@machine). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/rexen/nfa/machine.gleam"). -export([new/0, set_initial_state/2, set_ending_states/2, add_state/2, declare_states/2, add_transition/4, evaluate/2]). -export_type([n_f_a/0, node_/0]). -type n_f_a() :: {n_f_a, gleam@dict:dict(binary(), rexen@nfa@state:state()), binary(), list(binary())}. -type node_() :: {node, integer(), rexen@nfa@state:state()}. -file("src/rexen/nfa/machine.gleam", 15). -spec new() -> n_f_a(). new() -> {n_f_a, maps:new(), <<""/utf8>>, []}. -file("src/rexen/nfa/machine.gleam", 19). -spec set_initial_state(n_f_a(), binary()) -> n_f_a(). set_initial_state(Nfa, State) -> {n_f_a, erlang:element(2, Nfa), State, erlang:element(4, Nfa)}. -file("src/rexen/nfa/machine.gleam", 27). -spec set_ending_states(n_f_a(), list(binary())) -> n_f_a(). set_ending_states(Nfa, Values) -> {n_f_a, erlang:element(2, Nfa), erlang:element(3, Nfa), Values}. -file("src/rexen/nfa/machine.gleam", 35). -spec add_state(n_f_a(), binary()) -> n_f_a(). add_state(Nfa, Name) -> {n_f_a, gleam@dict:insert( erlang:element(2, Nfa), Name, rexen@nfa@state:new(Name) ), erlang:element(3, Nfa), erlang:element(4, Nfa)}. -file("src/rexen/nfa/machine.gleam", 43). -spec declare_states(n_f_a(), list(binary())) -> n_f_a(). declare_states(Nfa, Names) -> case Names of [] -> Nfa; [Name | Rest] -> declare_states(add_state(Nfa, Name), Rest) end. -file("src/rexen/nfa/machine.gleam", 50). -spec add_transition(n_f_a(), binary(), binary(), rexen@nfa@state:matcher()) -> n_f_a(). add_transition(Nfa, From, To, Matcher) -> From_state@1 = case gleam_stdlib:map_get(erlang:element(2, Nfa), From) of {ok, From_state} -> From_state; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"rexen/nfa/machine"/utf8>>, function => <<"add_transition"/utf8>>, line => 56, value => _assert_fail, start => 1127, 'end' => 1181, pattern_start => 1138, pattern_end => 1152}) end, case gleam_stdlib:map_get(erlang:element(2, Nfa), To) of {ok, _} -> nil; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"rexen/nfa/machine"/utf8>>, function => <<"add_transition"/utf8>>, line => 57, value => _assert_fail@1, start => 1184, 'end' => 1227, pattern_start => 1195, pattern_end => 1200}) end, Transitions = rexen@nfa@state:add_transition( erlang:element(3, From_state@1), {Matcher, To} ), New_state = {state, erlang:element(2, From_state@1), Transitions}, {n_f_a, gleam@dict:insert(erlang:element(2, Nfa), From, New_state), erlang:element(3, Nfa), erlang:element(4, Nfa)}. -file("src/rexen/nfa/machine.gleam", 132). -spec process_transitions( n_f_a(), list({rexen@nfa@state:matcher(), binary()}), integer(), gleam@set:set(node_()), list(node_()), binary() ) -> list(node_()). process_transitions(Nfa, Transitions, Index, Visited_nodes, Pending_nodes, Char) -> case Transitions of [] -> Pending_nodes; [{Matcher, Name} | Rest] -> case rexen@nfa@state:matches(Matcher, Char) of false -> process_transitions( Nfa, Rest, Index, Visited_nodes, Pending_nodes, Char ); true -> To@1 = case gleam_stdlib:map_get( erlang:element(2, Nfa), Name ) of {ok, To} -> To; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"rexen/nfa/machine"/utf8>>, function => <<"process_transitions"/utf8>>, line => 155, value => _assert_fail, start => 3629, 'end' => 3675, pattern_start => 3640, pattern_end => 3646}) end, New_node = case rexen@nfa@state:is_epsilon(Matcher) of true -> {node, Index, To@1}; false -> {node, Index + 1, To@1} end, Nodes = case gleam@set:contains(Visited_nodes, New_node) of true -> Pending_nodes; false -> lists:append(Pending_nodes, [New_node]) end, process_transitions( Nfa, Rest, Index, Visited_nodes, Nodes, Char ) end end. -file("src/rexen/nfa/machine.gleam", 82). -spec evaluate_loop(n_f_a(), binary(), list(node_()), gleam@set:set(node_())) -> boolean(). evaluate_loop(Nfa, Input, Nodes, Visited_nodes) -> case Nodes of [] -> false; [Node | Rest] -> Visited_nodes@1 = gleam@set:insert( Visited_nodes, {node, erlang:element(2, Node), erlang:element(3, Node)} ), case gleam@list:contains( erlang:element(4, Nfa), erlang:element(2, erlang:element(3, Node)) ) of true -> case string:length(Input) =:= erlang:element(2, Node) of true -> true; false -> Char = gleam@string:slice( Input, erlang:element(2, Node), 1 ), Updated_nodes = process_transitions( Nfa, erlang:element(3, erlang:element(3, Node)), erlang:element(2, Node), Visited_nodes@1, Rest, Char ), evaluate_loop( Nfa, Input, Updated_nodes, Visited_nodes@1 ) end; false -> Char@1 = gleam@string:slice( Input, erlang:element(2, Node), 1 ), Updated_nodes@1 = process_transitions( Nfa, erlang:element(3, erlang:element(3, Node)), erlang:element(2, Node), Visited_nodes@1, Rest, Char@1 ), evaluate_loop(Nfa, Input, Updated_nodes@1, Visited_nodes@1) end end. -file("src/rexen/nfa/machine.gleam", 73). -spec evaluate(n_f_a(), binary()) -> boolean(). evaluate(Nfa, Input) -> S@1 = case gleam_stdlib:map_get( erlang:element(2, Nfa), erlang:element(3, Nfa) ) of {ok, S} -> S; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"rexen/nfa/machine"/utf8>>, function => <<"evaluate"/utf8>>, line => 74, value => _assert_fail, start => 1645, 'end' => 1703, pattern_start => 1656, pattern_end => 1661}) end, Nodes = [{node, 0, S@1}], Visited_nodes = gleam@set:new(), evaluate_loop(Nfa, Input, Nodes, Visited_nodes).