#ifndef MACHINES_H_INCLUDED_ #define MACHINES_H_INCLUDED_ #include "interpolate.h" #include "kblib/kblib.h" #include namespace fsm { // TODO(killerbee13): Change state machines to do arbitrary string prefix // matching instead of using char32_t // see: https://conlang.lianamir.com/2019/11/the-dailies-november-5-2019/ // TODO(killerbee13): Add template-states for state machines. class state { public: auto step(char32_t c) const -> std::pair; auto suf() const -> const std::string& { return end; } private: struct action_t { std::string format; const state* dest; }; vmap cmap; struct set_action_t { small_vector matches; action_t action; }; std::vector set; struct map_action_t { small_vector in_set; small_vector out_set; const state* dest; }; std::vector map; struct match_action_t { small_vector matches; const state* dest; }; std::vector match; std::optional def; const state* ret; std::string end; public: std::string_view name; friend auto toState(const YAML::Node&) -> std::optional; friend auto set_dests(std::map& states, std::string name, const YAML::Node& data) -> bool; }; class state_machine { public: enum dir_override : unsigned char { none = 0, r_in = 1, r_out = 2, r_both = 3, }; // be a valid string_transformer auto operator()(Word, channelID) const -> word_data_t; private: // using std::map for reference stability std::map states; dir_override dir; friend struct YAML::convert; }; } // namespace fsm namespace YAML { template <> struct convert { static auto decode(const Node& node, fsm::state_machine& sm) -> bool; }; template <> struct convert { static auto decode(const Node& node, fsm::state& s) -> bool; }; } // namespace YAML #endif // MACHINES_H_INCLUDED_