Skip to content

Commit

Permalink
Implement crude dynamic linking of the formula evaluation function
Browse files Browse the repository at this point in the history
  • Loading branch information
CelticMinstrel committed Feb 11, 2018
1 parent 5692e60 commit 0c9bc4b
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 15 deletions.
29 changes: 29 additions & 0 deletions src/formula/formula.cpp
Expand Up @@ -16,13 +16,42 @@

#include "formula/callable.hpp"
#include "formula/function.hpp"
#include "formula/string_utils.hpp"
#include "random.hpp"
#include "serialization/string_utils.hpp"
#include "log.hpp"

#include <cassert>
#include <set>
#include <sstream>

// This is here only for the below initialization code.
// If other logging is required in this file, it should use a different logdomain
// (probably "scripting/wfl" or something)
static lg::log_domain log_engine("engine");
#define ERR_NG LOG_STREAM(err, log_engine)

namespace utils {
namespace detail {
std::string evaluate_formula_impl(const std::string& formula) {
try {
const wfl::formula form(formula);
return form.evaluate().string_cast();
} catch(wfl::formula_error& e) {
ERR_NG << "Formula in WML string cannot be evaluated due to "
<< e.type << "\n\t--> \"";
return "";
}
}

struct formula_initer {
formula_initer() {
evaluate_formula = &evaluate_formula_impl;
}
} init;
}
}

namespace wfl
{
using expr_table = std::map<std::string, expression_ptr>;
Expand Down
25 changes: 10 additions & 15 deletions src/formula/string_utils.cpp
Expand Up @@ -19,7 +19,6 @@

#include "config.hpp"
#include "log.hpp"
//#include "formula/formula.hpp"
#include "gettext.hpp"

static lg::log_domain log_engine("engine");
Expand All @@ -30,6 +29,10 @@ static bool two_dots(char a, char b) { return a == '.' && b == '.'; }

namespace utils {

namespace detail {
std::string(* evaluate_formula)(const std::string& formula) = nullptr;
}

template <typename T>
class string_map_variable_set : public variable_set
{
Expand Down Expand Up @@ -110,27 +113,19 @@ static std::string do_interpolation(const std::string &str, const variable_set&
// TODO: support escape sequences when/if they are allowed in FormulaAI strings
}
} while(++var_end != res.end() && paren_nesting_level > 0);
#ifdef WESNOTH_GAME
if(utils::detail::evaluate_formula == nullptr) {
WRN_NG << "Formula substitution ignored (and removed) because WFL engine is not present in the server.\n";
res.replace(var_begin, var_end, "");
continue;
}
if(paren_nesting_level > 0) {
ERR_NG << "Formula in WML string cannot be evaluated due to "
<< "a missing closing parenthesis:\n\t--> \""
<< std::string(var_begin, var_end) << "\"\n";
res.replace(var_begin, var_end, "");
continue;
}
try {
const wfl::formula form(std::string(var_begin+2, var_end-1));
res.replace(var_begin, var_end, form.evaluate().string_cast());
} catch(wfl::formula_error& e) {
ERR_NG << "Formula in WML string cannot be evaluated due to "
<< e.type << "\n\t--> \""
<< e.formula << "\"\n";
res.replace(var_begin, var_end, "");
}
#else
WRN_NG << "Formula substitution ignored (and removed) because WFL engine is not present in the server.\n";
res.replace(var_begin, var_end, "");
#endif
res.replace(var_begin, var_end, utils::detail::evaluate_formula(std::string(var_begin+2, var_end-1)));
continue;
}

Expand Down
4 changes: 4 additions & 0 deletions src/formula/string_utils.hpp
Expand Up @@ -21,6 +21,10 @@ class variable_set;

namespace utils {

namespace detail {
extern std::string(* evaluate_formula)(const std::string& formula);
}

/**
* Determines if a string might contain variables to interpolate.
* This can allow one to skip future interpolations (plural -- if there is only
Expand Down

0 comments on commit 0c9bc4b

Please sign in to comment.