| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- //
- // 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 <fstream>
- #include <iostream>
- #include <map>
- #include <regex>
- 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_os(std::pair<const std::string, std::string> const & pair,
- std::ostream & os) {
- os << pair.first;
- if (pair.second == "") os << " is not defined\n";
- else os << " := " << pair.second << "\n";
- }
- void print_binding(std::pair<const std::string, std::string> const & pair) {
- print_binding_os(pair, std::cout);
- }
- class evaluator {
- public:
- evaluator(std::string const & path = "") {
- if (!path.empty()) { load(path); }
- }
- void operator()(std::string const & str);
-
- private:
- using binding_t = std::map<std::string, std::string>;
-
- 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_os, _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 argc, const char * argv[]) {
- std::string line;
- std::cout << "> ";
- evaluator eval(argc > 1 ? argv[1] : "");
- while (std::getline(std::cin, line)) {
- eval(line);
- std::cout << "> ";
- }
- return 0;
- }
|