// // main.cpp // stateful_dice // // Created by Sam Jaffe on 12/18/18. // Copyright © 2018 Sam Jaffe. All rights reserved. // #include "exception.h" #include "terminal_helper.h" #include #include #include #include void usage() { std::cout << "'help' : Print this message\n"; std::cout << "'A := Dice' : Create a substitution pattern\n"; std::cout << "'1d6+$Dex' : Roll 1d6 plus whatever value subs for 'Dex'\n"; } void print_binding(std::pair const & pair, std::ostream & os = std::cout) { os << pair.first; if (pair.second == "") os << " is not defined\n"; else os << " := " << pair.second << "\n"; } class evaluator { public: void operator()(std::string const & str); private: using binding_t = std::map; bool regex_search(char const * regex) { return std::regex_match(curr, match, std::regex(regex)); } binding_t::value_type find_or(std::string const & key) const { auto it = bindings.find(key); return it == bindings.cend() ? binding_t::value_type(key, "") : *it; } void save(std::string const & file) const { using namespace std::placeholders; std::ofstream out(file); std::for_each(bindings.begin(), bindings.end(), std::bind(&print_binding, _1, std::ref(out))); } void load(std::string const & file) { std::ifstream in(file); while (std::getline(in, curr)) { if (regex_search(R"(^(\w+)\s*:=\s*(.*)$)")) { bindings[match[1]] = match[2]; } } } private: std::string curr; std::smatch match; binding_t bindings; }; void evaluator::operator()(std::string const & str) { curr = str; try { if (regex_search(R"(help|\?)")) { usage(); } else if (regex_search(R"(^(\w+)\s*:=\s*(.*)$)")) { bindings[match[1]] = match[2]; } else if (regex_search(R"(^show (\*|all))")) { std::for_each(bindings.begin(), bindings.end(), &print_binding); } else if (regex_search(R"(^show (\w+))")) { print_binding(find_or(match[1])); } else if (regex_search(R"(^unset (\*|all))")) { bindings.clear(); } else if (regex_search(R"(^unset (\w+))")) { bindings.erase(match[1]); } else if (regex_search(R"(^save (.+))")) { save(match[1]); } else if (regex_search(R"(^load new (.+))")) { bindings.clear(); load(match[1]); } else if (regex_search(R"(^load (.+))")) { load(match[1]); } else { while (regex_search(R"(.*(\$\w+).*)")) { curr.replace(match[1].first, match[1].second, find_or(match[1].str().substr(1)).second); } terminal::process_dice_string(curr); } } catch (dice::unexpected_token const & ut) { terminal::print_error_message(curr, ut); } } int main(int, const char **) { std::string line; std::cout << "> "; evaluator eval; while (std::getline(std::cin, line)) { eval(line); std::cout << "> "; } return 0; }