32 #include <boost/algorithm/string.hpp>
33 #include <boost/filesystem.hpp>
35 #include <muparserx/mpParser.h>
40 namespace import_export {
44 std::string
ms_to_ss(
const mup::string_type& s) {
46 std::wstring_convert<std::codecvt_utf8<wchar_t>,
wchar_t> converter;
47 return converter.to_bytes(s);
53 mup::string_type
ss_to_ms(
const std::string& s) {
55 std::wstring_convert<std::codecvt_utf8<wchar_t>,
wchar_t> converter;
56 return converter.from_bytes(s);
62 #define VALIDATE_ARG_TYPE(arg, t2) \
63 if (args[arg]->GetType() != t2) { \
64 mup::ErrorContext err; \
65 err.Errc = mup::ecINVALID_TYPE; \
66 err.Type1 = args[arg]->GetType(); \
68 err.Ident = GetIdent(); \
69 throw mup::ParserError(err); \
72 #define THROW_INVALID_PARAMETER(arg, what) \
73 mup::ErrorContext err; \
74 err.Errc = mup::ecINVALID_PARAMETER; \
76 err.Ident = GetIdent() + ss_to_ms(" (") + ss_to_ms(what) + ss_to_ms(")"); \
77 throw mup::ParserError(err);
79 #define THROW_INVALID_PARAMETER_COUNT() \
80 mup::ErrorContext err; \
81 err.Errc = mup::ecINVALID_NUMBER_OF_PARAMETERS; \
82 err.Ident = GetIdent(); \
83 throw mup::ParserError(err);
88 const mup::char_type*
GetDesc() const final {
89 return _T(
"return a substring of a string");
92 void Eval(mup::ptr_val_type& ret,
const mup::ptr_val_type*
args,
int argc)
final {
93 if (argc < 2 || argc > 3) {
101 auto const text =
args[0]->GetString();
102 auto const start =
args[1]->GetInteger();
107 if (start > static_cast<int>(text.length())) {
110 *ret = text.substr(start - 1, std::string::npos);
112 auto const count =
args[2]->GetInteger();
115 }
else if ((start - 1) + count > static_cast<int>(text.length())) {
118 *ret = text.substr(start - 1, count);
127 return _T(
"return a regex-matched section of a string");
130 void Eval(mup::ptr_val_type& ret,
const mup::ptr_val_type*
args,
int argc)
final {
137 std::regex regex(pattern, std::regex_constants::extended);
139 std::regex_match(text, match, regex);
140 if (match.size() != 2u) {
141 throw std::runtime_error(
"must have exactly one match");
144 }
catch (std::runtime_error& e) {
154 return _T(
"split a string by a given separator, then return the nth token");
157 void Eval(mup::ptr_val_type& ret,
const mup::ptr_val_type*
args,
int argc)
final {
164 auto n =
args[2]->GetInteger();
166 std::vector<std::string> tokens;
168 size_t start{0u}, end{0u};
169 while (end != std::string::npos) {
170 end = text.find(delimiter, start);
171 tokens.push_back(text.substr(start, end - start));
172 start = end + delimiter.length();
174 if (tokens.size() == 0u) {
175 throw std::runtime_error(
"failed to split");
180 index =
static_cast<int>(tokens.size()) +
n;
185 if (index < 0 || index >= static_cast<int>(tokens.size())) {
186 throw std::runtime_error(
"bad token index");
189 }
catch (std::runtime_error& e) {
198 const mup::char_type*
GetDesc() const final {
return _T(
"cast a value to an int"); };
200 void Eval(mup::ptr_val_type& ret,
const mup::ptr_val_type*
args,
int argc)
final {
202 switch (
args[0]->GetType()) {
204 *ret =
args[0]->GetInteger();
207 *ret =
static_cast<mup::int_type
>(
args[0]->GetFloat());
210 *ret =
static_cast<mup::int_type
>(std::stoll(
ms_to_ss(
args[0]->GetString())));
213 *ret =
args[0]->GetBool() ?
static_cast<mup::int_type
>(1)
214 : static_cast<mup::int_type>(0);
226 const mup::char_type*
GetDesc() const final {
return _T(
"cast a value to a float"); };
228 void Eval(mup::ptr_val_type& ret,
const mup::ptr_val_type*
args,
int argc)
final {
230 switch (
args[0]->GetType()) {
232 *ret =
static_cast<mup::float_type
>(
args[0]->GetInteger());
235 *ret =
args[0]->GetFloat();
238 *ret =
static_cast<mup::float_type
>(std::stod(
ms_to_ss(
args[0]->GetString())));
250 const mup::char_type*
GetDesc() const final {
return _T(
"cast a value to a double"); };
252 void Eval(mup::ptr_val_type& ret,
const mup::ptr_val_type*
args,
int argc)
final {
254 switch (
args[0]->GetType()) {
256 *ret =
static_cast<mup::float_type
>(
args[0]->GetInteger());
259 *ret =
args[0]->GetFloat();
262 *ret =
static_cast<mup::float_type
>(std::stod(
ms_to_ss(
args[0]->GetString())));
274 const mup::char_type*
GetDesc() const final {
return _T(
"cast a value to a string"); };
276 void Eval(mup::ptr_val_type& ret,
const mup::ptr_val_type*
args,
int argc)
final {
278 switch (
args[0]->GetType()) {
281 *ret =
args[0]->ToString();
284 *ret =
args[0]->GetString();
299 const mup::char_type*
GetDesc() const final {
return _T(
"cast a value to a boolean"); };
301 void Eval(mup::ptr_val_type& ret,
const mup::ptr_val_type*
args,
int argc)
final {
303 switch (
args[0]->GetType()) {
305 *ret =
args[0]->GetInteger() != 0;
309 if (s ==
"true" || s ==
"t" || s ==
"1") {
311 }
else if (s ==
"false" || s ==
"f" || s ==
"0") {
318 *ret =
args[0]->GetBool();
330 const mup::char_type*
GetDesc() const final {
return _T(
"bool inversion operator"); }
332 void Eval(mup::ptr_val_type& ret,
const mup::ptr_val_type*
args,
int argc)
final {
335 *ret = !(
args[0]->GetBool());
342 result = parser->Eval();
343 }
catch (mup::ParserError& err) {
344 throw std::runtime_error(
"Parser Error: " +
ms_to_ss(err.GetMsg()));
345 }
catch (std::exception& err) {
346 throw std::runtime_error(
"Unexpected muparserx Error: " + std::string(err.what()));
358 :
parser_{
new mup::ParserX(mup::pckCOMMON | mup::pckUNIT | mup::pckNON_COMPLEX |
361 parser_->DefineFun(
new Function_substr());
362 parser_->DefineFun(
new Function_regex_match());
363 parser_->DefineFun(
new Function_split_part());
364 parser_->DefineFun(
new Function_int());
365 parser_->DefineFun(
new Function_float());
366 parser_->DefineFun(
new Function_double());
367 parser_->DefineFun(
new Function_str());
368 parser_->DefineFun(
new Function_bool());
369 parser_->DefineInfixOprt(
new Operator_not());
373 const std::string& value) {
378 parser_->DefineConst(
ss_to_ms(name), static_cast<mup::int_type>(value));
387 if (
result.GetType() !=
's') {
388 throw std::runtime_error(
"Expression is not a string");
395 if (
result.GetType() !=
'i') {
396 throw std::runtime_error(
"Expression is not an int");
398 return static_cast<int>(
result.GetInteger());
403 if (
result.GetType() !=
'f') {
404 throw std::runtime_error(
"Expression is not a float/double");
406 return static_cast<double>(
result.GetFloat());
411 if (
result.GetType() !=
'b') {
412 throw std::runtime_error(
"Expression is not a boolean");
mup::IToken * Clone() const final
mup::IToken * Clone() const final
void Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *args, int argc) final
const mup::char_type * GetDesc() const final
void operator()(mup::ParserX *parser)
const mup::char_type * GetDesc() const final
void Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *args, int argc) final
void Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *args, int argc) final
mup::IToken * Clone() const final
void Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *args, int argc) final
void Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *args, int argc) final
void Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *args, int argc) final
const mup::char_type * GetDesc() const final
mup::IToken * Clone() const final
void Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *args, int argc) final
const mup::char_type * GetDesc() const final
mup::IToken * Clone() const final
const mup::char_type * GetDesc() const final
mup::IToken * Clone() const final
std::string ms_to_ss(const mup::string_type &s)
#define VALIDATE_ARG_TYPE(arg, t2)
#define THROW_INVALID_PARAMETER_COUNT()
void setIntConstant(const std::string &name, const int value)
const mup::char_type * GetDesc() const final
void Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *args, int argc) final
mup::string_type ss_to_ms(const std::string &s)
const mup::char_type * GetDesc() const final
std::string evalAsString()
std::unique_ptr< mup::ParserX, ParserDeleter > parser_
void setStringConstant(const std::string &name, const std::string &value)
mup::IToken * Clone() const final
#define THROW_INVALID_PARAMETER(arg, what)
mup::Value evaluate(mup::ParserX *parser)
const mup::char_type * GetDesc() const final
const mup::char_type * GetDesc() const final
mup::IToken * Clone() const final
void setExpression(const std::string &expression)
mup::IToken * Clone() const final
void Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *args, int argc) final