C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html

This commit is contained in:
Arash Partow 2015-04-19 22:44:48 +10:00
parent ba6f782220
commit 2710614e95
2 changed files with 130 additions and 9 deletions

View File

@ -3736,6 +3736,10 @@ namespace exprtk
: v_(*reinterpret_cast<value_t*>(ts.data))
{}
scalar_view(const type_store_t& ts)
: v_(*reinterpret_cast<value_t*>(const_cast<type_store_t&>(ts).data))
{}
value_t& operator()()
{
return v_;
@ -19529,10 +19533,27 @@ namespace exprtk
Sequence<expression_node_ptr,Allocator1> tmp_expression_list;
bool return_node_present = false;
for (std::size_t i = 0; i < (expression_list.size() - 1); ++i)
{
if (is_variable_node(expression_list[i]))
continue;
else if (is_return_node(expression_list[i]))
{
tmp_expression_list.push_back(expression_list[i]);
// Remove all subexpressions after first encountered return node.
for (std::size_t j = i + 1; j < (expression_list.size() - 1); ++j)
{
free_node(node_allocator_,expression_list[j]);
}
return_node_present = true;
break;
}
else if (
is_constant_node(expression_list[i]) ||
is_null_node (expression_list[i]) ||
@ -19546,12 +19567,20 @@ namespace exprtk
tmp_expression_list.push_back(expression_list[i]);
}
tmp_expression_list.push_back(expression_list.back());
expression_list.swap(tmp_expression_list);
if ((expression_list.size() > 1) || side_effect_list.back())
if (
return_node_present ||
side_effect_list.back() ||
(expression_list.size() > 1)
)
state_.side_effect_present = true;
if (!return_node_present)
{
tmp_expression_list.push_back(expression_list.back());
}
expression_list.swap(tmp_expression_list);
if (tmp_expression_list.size() > expression_list.size())
{
exprtk_debug(("simplify() - Reduced subexpressions from %d to %d\n",

View File

@ -6620,6 +6620,21 @@ inline std::string results_to_string(const exprtk::results_context<T>& results)
return res_str;
}
template <typename T>
inline bool result_equal(const exprtk::results_context<T>& results, const T& value)
{
typedef exprtk::results_context<T> results_context_t;
typedef typename results_context_t::type_store_t type_t;
typedef typename type_t::scalar_view scalar_t;
if (1 != results.count())
return false;
else if (type_t::e_scalar != results[0].type)
return false;
else
return (value == scalar_t(results[0])());
}
template <typename T>
inline bool run_test21()
{
@ -6703,7 +6718,7 @@ inline bool run_test21()
std::string pattern = results_to_string<T>(expression.results());
if (result_list[i] != results_to_string<T>(expression.results()))
if (result_list[i] != pattern)
{
printf("run_test21() - Invalid return results [1] Expected %s Got: %s Expression: %s\n",
result_list[i].c_str(),
@ -6711,6 +6726,83 @@ inline bool run_test21()
expression_list[i].c_str());
failure = true;
continue;
}
}
if (failure)
return false;
}
{
static const std::string expression_list[] =
{
"x := 1; x + 1; x + 2; x + 3; x + 5; x + 7; return [x + 1];",
"x := 1; x + 1; x + 2; x + 3; x + 5; return [x + 1]; x := 7;",
"x := 1; x + 1; x + 2; x + 3; return [x + 1]; x + 5; x := 7;",
"x := 1; x + 1; x + 2; return [x + 1]; x + 3; x + 5; x := 7;",
"x := 1; x + 1; return [x + 1]; x + 2; x + 3; x + 5; x := 7;",
"x := 1; return [x + 1]; x + 1; x + 2; x + 3; x + 5; x := 7;",
"return [x + 1]; x := 1; x + 1; x + 2; x + 3; x + 5; x := 7;",
"~{x := 1; x + 1; x + 2; x + 3; x + 5; x + 7; return [x + 1]}",
"~{x := 1; x + 1; x + 2; x + 3; x + 5; return [x + 1]; x := 7}",
"~{x := 1; x + 1; x + 2; x + 3; return [x + 1]; x + 5; x := 7}",
"~{x := 1; x + 1; x + 2; return [x + 1]; x + 3; x + 5; x := 7}",
"~{x := 1; x + 1; return [x + 1]; x + 2; x + 3; x + 5; x := 7}",
"~{x := 1; return [x + 1]; x + 1; x + 2; x + 3; x + 5; x := 7}",
"~{return [x + 1]; x := 1; x + 1; x + 2; x + 3; x + 5; x := 7}"
};
static const std::string result_list[] =
{
"T", "T", "T", "T", "T", "T", "T",
"T", "T", "T", "T", "T", "T", "T",
};
static const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string);
bool failure = false;
for (std::size_t i = 0; i < expression_list_size; ++i)
{
expression_t expression;
expression.register_symbol_table(symbol_table);
parser_t parser;
if (!parser.compile(expression_list[i],expression))
{
printf("run_test21() - Error: %s Expression: %s [2]\n",
parser.error().c_str(),
expression_list[i].c_str());
failure = true;
continue;
}
expression.value();
std::string pattern = results_to_string<T>(expression.results());
if (result_list[i] != pattern)
{
printf("run_test21() - Invalid return results [2] Expected %s Got: %s Expression: %s\n",
result_list[i].c_str(),
pattern.c_str(),
expression_list[i].c_str());
failure = true;
continue;
}
else if (!result_equal(expression.results(), x + T(1)))
{
printf("run_test21() - Invalid return results [2] Expected %s Got: %s Expression: %s\n",
result_list[i].c_str(),
pattern.c_str(),
expression_list[i].c_str());
failure = true;
continue;
}
}