C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
6b98239580
commit
ba6f782220
182
exprtk.hpp
182
exprtk.hpp
|
@ -2118,6 +2118,13 @@ namespace exprtk
|
|||
}
|
||||
}
|
||||
|
||||
inline std::string substr(const std::size_t& begin, const std::size_t& end)
|
||||
{
|
||||
const char* begin_itr = ((base_itr_ + begin) < s_end_) ? (base_itr_ + begin) : s_end_;
|
||||
const char* end_itr = ((base_itr_ + end) < s_end_) ? (base_itr_ + end) : s_end_;
|
||||
return std::string(begin_itr,end_itr);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
inline bool is_end(const char* itr)
|
||||
|
@ -16584,6 +16591,7 @@ namespace exprtk
|
|||
: parsing_return_stmt(false),
|
||||
parsing_break_stmt (false),
|
||||
return_stmt_present(false),
|
||||
side_effect_present(false),
|
||||
scope_depth(0)
|
||||
{}
|
||||
|
||||
|
@ -16592,12 +16600,14 @@ namespace exprtk
|
|||
parsing_return_stmt = false;
|
||||
parsing_break_stmt = false;
|
||||
return_stmt_present = false;
|
||||
side_effect_present = false;
|
||||
scope_depth = 0;
|
||||
}
|
||||
|
||||
bool parsing_return_stmt;
|
||||
bool parsing_break_stmt;
|
||||
bool return_stmt_present;
|
||||
bool side_effect_present;
|
||||
std::size_t scope_depth;
|
||||
};
|
||||
|
||||
|
@ -17547,12 +17557,21 @@ namespace exprtk
|
|||
inline expression_node_ptr parse_corpus()
|
||||
{
|
||||
std::vector<expression_node_ptr> arg_list;
|
||||
std::vector<bool> side_effect_list;
|
||||
|
||||
expression_node_ptr result = error_node();
|
||||
|
||||
scoped_vec_delete<expression_node_t> sdd(*this,arg_list);
|
||||
|
||||
lexer::token begin_token;
|
||||
lexer::token end_token;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
state_.side_effect_present = false;
|
||||
|
||||
begin_token = current_token();
|
||||
|
||||
expression_node_ptr arg = parse_expression();
|
||||
|
||||
if (0 == arg)
|
||||
|
@ -17568,8 +17587,26 @@ namespace exprtk
|
|||
return error_node();
|
||||
}
|
||||
else
|
||||
{
|
||||
arg_list.push_back(arg);
|
||||
|
||||
side_effect_list.push_back(state_.side_effect_present);
|
||||
|
||||
end_token = current_token();
|
||||
|
||||
std::string sub_expr = construct_subexpr(begin_token,end_token);
|
||||
|
||||
exprtk_debug(("parse_corpus(%02d) Subexpr: %s\n",
|
||||
static_cast<int>(arg_list.size() - 1),
|
||||
sub_expr.c_str()));
|
||||
|
||||
exprtk_debug(("parse_corpus(%02d) - Side effect present: %s\n",
|
||||
static_cast<int>(arg_list.size() - 1),
|
||||
state_.side_effect_present ? "true" : "false"));
|
||||
|
||||
exprtk_debug(("-------------------------------------------------\n"));
|
||||
}
|
||||
|
||||
if (lexer_.finished())
|
||||
break;
|
||||
else if (token_is(token_t::e_eof,false))
|
||||
|
@ -17581,13 +17618,25 @@ namespace exprtk
|
|||
}
|
||||
}
|
||||
|
||||
result = simplify(arg_list);
|
||||
result = simplify(arg_list,side_effect_list);
|
||||
|
||||
sdd.delete_ptr = (0 == result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string construct_subexpr(lexer::token& begin_token, lexer::token& end_token)
|
||||
{
|
||||
std::string result = lexer_.substr(begin_token.position,end_token.position);
|
||||
|
||||
for (std::size_t i = 0; i < result.size(); ++i)
|
||||
{
|
||||
if (details::is_whitespace(result[i])) result[i] = ' ';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const precedence_level default_precedence = e_level00;
|
||||
|
||||
struct state_t
|
||||
|
@ -17978,6 +18027,22 @@ namespace exprtk
|
|||
bool& b;
|
||||
};
|
||||
|
||||
struct scoped_bool_or_restorer
|
||||
{
|
||||
scoped_bool_or_restorer(bool& bb)
|
||||
: b(bb),
|
||||
original_value_(bb)
|
||||
{}
|
||||
|
||||
~scoped_bool_or_restorer()
|
||||
{
|
||||
b = b || original_value_;
|
||||
}
|
||||
|
||||
bool& b;
|
||||
bool original_value_;
|
||||
};
|
||||
|
||||
inline expression_node_ptr parse_function_invocation(ifunction<T>* function, const std::string& function_name)
|
||||
{
|
||||
expression_node_ptr func_node = reinterpret_cast<expression_node_ptr>(0);
|
||||
|
@ -18106,7 +18171,11 @@ namespace exprtk
|
|||
inline expression_node_ptr parse_function_call_0(ifunction<T>* function, const std::string& function_name)
|
||||
{
|
||||
expression_node_ptr result = expression_generator_.function(function);
|
||||
|
||||
state_.side_effect_present = function->has_side_effects;
|
||||
|
||||
next_token();
|
||||
|
||||
if (
|
||||
token_is(token_t::e_lbracket) &&
|
||||
!token_is(token_t::e_rbracket)
|
||||
|
@ -18699,6 +18768,8 @@ namespace exprtk
|
|||
next_token();
|
||||
|
||||
std::vector<expression_node_ptr> arg_list;
|
||||
std::vector<bool> side_effect_list;
|
||||
|
||||
scoped_vec_delete<expression_node_t> sdd(*this,arg_list);
|
||||
|
||||
brkcnt_list_.push_front(false);
|
||||
|
@ -18714,14 +18785,21 @@ namespace exprtk
|
|||
|
||||
scope_handler sh(*this);
|
||||
|
||||
scoped_bool_or_restorer sbr(state_.side_effect_present);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
state_.side_effect_present = false;
|
||||
|
||||
expression_node_ptr arg = parse_expression();
|
||||
|
||||
if (0 == arg)
|
||||
return error_node();
|
||||
else
|
||||
{
|
||||
arg_list.push_back(arg);
|
||||
side_effect_list.push_back(state_.side_effect_present);
|
||||
}
|
||||
|
||||
if (details::imatch(current_token_.value,"until"))
|
||||
{
|
||||
|
@ -18749,7 +18827,7 @@ namespace exprtk
|
|||
}
|
||||
}
|
||||
|
||||
branch = simplify(arg_list);
|
||||
branch = simplify(arg_list,side_effect_list);
|
||||
|
||||
if ((sdd.delete_ptr = (0 == branch)))
|
||||
{
|
||||
|
@ -18929,7 +19007,11 @@ namespace exprtk
|
|||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
exprtk_debug(("parse_for_loop() - INFO - Added new local variable: %s\n",nse.name.c_str()));
|
||||
|
||||
state_.side_effect_present = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19434,16 +19516,18 @@ namespace exprtk
|
|||
}
|
||||
}
|
||||
|
||||
template <typename Allocator,
|
||||
template <typename Allocator1,
|
||||
typename Allocator2,
|
||||
template <typename,typename> class Sequence>
|
||||
inline expression_node_ptr simplify(Sequence<expression_node_ptr,Allocator>& expression_list)
|
||||
inline expression_node_ptr simplify(Sequence<expression_node_ptr,Allocator1>& expression_list,
|
||||
Sequence<bool,Allocator2>& side_effect_list)
|
||||
{
|
||||
if (expression_list.empty())
|
||||
return error_node();
|
||||
else if (1 == expression_list.size())
|
||||
return expression_list[0];
|
||||
|
||||
Sequence<expression_node_ptr,Allocator> tmp_expression_list;
|
||||
Sequence<expression_node_ptr,Allocator1> tmp_expression_list;
|
||||
|
||||
for (std::size_t i = 0; i < (expression_list.size() - 1); ++i)
|
||||
{
|
||||
|
@ -19451,7 +19535,8 @@ namespace exprtk
|
|||
continue;
|
||||
else if (
|
||||
is_constant_node(expression_list[i]) ||
|
||||
is_null_node (expression_list[i])
|
||||
is_null_node (expression_list[i]) ||
|
||||
!side_effect_list[i]
|
||||
)
|
||||
{
|
||||
free_node(node_allocator_,expression_list[i]);
|
||||
|
@ -19464,6 +19549,16 @@ namespace exprtk
|
|||
tmp_expression_list.push_back(expression_list.back());
|
||||
expression_list.swap(tmp_expression_list);
|
||||
|
||||
if ((expression_list.size() > 1) || side_effect_list.back())
|
||||
state_.side_effect_present = true;
|
||||
|
||||
if (tmp_expression_list.size() > expression_list.size())
|
||||
{
|
||||
exprtk_debug(("simplify() - Reduced subexpressions from %d to %d\n",
|
||||
static_cast<int>(tmp_expression_list.size()),
|
||||
static_cast<int>(expression_list .size())));
|
||||
}
|
||||
|
||||
if (1 == expression_list.size())
|
||||
return expression_list[0];
|
||||
else
|
||||
|
@ -19499,20 +19594,29 @@ namespace exprtk
|
|||
}
|
||||
|
||||
std::vector<expression_node_ptr> arg_list;
|
||||
std::vector<bool> side_effect_list;
|
||||
|
||||
expression_node_ptr result = error_node();
|
||||
|
||||
scoped_vec_delete<expression_node_t> sdd(*this,arg_list);
|
||||
|
||||
scope_handler sh(*this);
|
||||
|
||||
scoped_bool_or_restorer sbr(state_.side_effect_present);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
state_.side_effect_present = false;
|
||||
|
||||
expression_node_ptr arg = parse_expression();
|
||||
|
||||
if (0 == arg)
|
||||
return error_node();
|
||||
else
|
||||
{
|
||||
arg_list.push_back(arg);
|
||||
side_effect_list.push_back(state_.side_effect_present);
|
||||
}
|
||||
|
||||
if (token_is(close_bracket))
|
||||
break;
|
||||
|
@ -19533,7 +19637,7 @@ namespace exprtk
|
|||
break;
|
||||
}
|
||||
|
||||
result = simplify(arg_list);
|
||||
result = simplify(arg_list,side_effect_list);
|
||||
|
||||
sdd.delete_ptr = (0 == result);
|
||||
return result;
|
||||
|
@ -20715,6 +20819,8 @@ namespace exprtk
|
|||
exprtk_debug(("parse_define_vector_statement() - INFO - Added new local vector: %s[%d]\n",
|
||||
nse.name.c_str(),
|
||||
static_cast<int>(nse.size)));
|
||||
|
||||
state_.side_effect_present = true;
|
||||
}
|
||||
|
||||
lodge_symbol(vec_name,e_st_local_vector);
|
||||
|
@ -20789,6 +20895,8 @@ namespace exprtk
|
|||
str_node = nse.str_node;
|
||||
|
||||
exprtk_debug(("parse_define_string_statement() - INFO - Added new local string variable: %s\n",nse.name.c_str()));
|
||||
|
||||
state_.side_effect_present = true;
|
||||
}
|
||||
|
||||
lodge_symbol(str_name,e_st_local_string);
|
||||
|
@ -20973,6 +21081,8 @@ namespace exprtk
|
|||
var_node = nse.var_node;
|
||||
|
||||
exprtk_debug(("parse_define_var_statement() - INFO - Added new local variable: %s\n",nse.name.c_str()));
|
||||
|
||||
state_.side_effect_present = true;
|
||||
}
|
||||
|
||||
lodge_symbol(var_name,e_st_local_variable);
|
||||
|
@ -21057,6 +21167,8 @@ namespace exprtk
|
|||
}
|
||||
|
||||
exprtk_debug(("parse_uninitialised_var_statement() - INFO - Added new local variable: %s\n",nse.name.c_str()));
|
||||
|
||||
state_.side_effect_present = true;
|
||||
}
|
||||
|
||||
lodge_symbol(var_name,e_st_local_variable);
|
||||
|
@ -21259,12 +21371,14 @@ namespace exprtk
|
|||
variable_node_ptr v0 = variable_node_ptr(0);
|
||||
variable_node_ptr v1 = variable_node_ptr(0);
|
||||
|
||||
expression_node_ptr result = error_node();
|
||||
|
||||
if (
|
||||
(0 != (v0 = dynamic_cast<variable_node_ptr>(variable0))) &&
|
||||
(0 != (v1 = dynamic_cast<variable_node_ptr>(variable1)))
|
||||
)
|
||||
{
|
||||
expression_node_ptr result = node_allocator_.allocate<details::swap_node<T> >(v0,v1);
|
||||
result = node_allocator_.allocate<details::swap_node<T> >(v0,v1);
|
||||
|
||||
if (variable0_generated)
|
||||
{
|
||||
|
@ -21275,11 +21389,13 @@ namespace exprtk
|
|||
{
|
||||
free_node(node_allocator_,variable1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
return node_allocator_.allocate<details::swap_generic_node<T> >(variable0,variable1);
|
||||
result = node_allocator_.allocate<details::swap_generic_node<T> >(variable0,variable1);
|
||||
|
||||
state_.side_effect_present = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline expression_node_ptr parse_return_statement()
|
||||
|
@ -23635,6 +23751,8 @@ namespace exprtk
|
|||
result = node_allocator_->allocate<literal_node_t>(v);
|
||||
}
|
||||
|
||||
parser_->state_.side_effect_present = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -23674,7 +23792,10 @@ namespace exprtk
|
|||
return node_allocator_->allocate<literal_node_t>(v);
|
||||
}
|
||||
else if (genfunc_node_ptr->init_branches())
|
||||
{
|
||||
parser_->state_.side_effect_present = true;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
details::free_node(*node_allocator_,result);
|
||||
|
@ -23719,7 +23840,10 @@ namespace exprtk
|
|||
return node_allocator_->allocate<literal_node_t>(v);
|
||||
}
|
||||
else if (strfunc_node_ptr->init_branches())
|
||||
{
|
||||
parser_->state_.side_effect_present = true;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
details::free_node(*node_allocator_,result);
|
||||
|
@ -23744,7 +23868,10 @@ namespace exprtk
|
|||
alloc_type* return_node_ptr = static_cast<alloc_type*>(result);
|
||||
|
||||
if (return_node_ptr->init_branches())
|
||||
{
|
||||
parser_->state_.side_effect_present = true;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
details::free_node(*node_allocator_,result);
|
||||
|
@ -23798,11 +23925,12 @@ namespace exprtk
|
|||
|
||||
result = error_node();
|
||||
}
|
||||
else
|
||||
{
|
||||
exprtk_debug(("vector_element() - INFO - Added new local vector element: %s\n",nse.name.c_str()));
|
||||
result = nse.var_node;
|
||||
}
|
||||
|
||||
exprtk_debug(("vector_element() - INFO - Added new local vector element: %s\n",nse.name.c_str()));
|
||||
|
||||
parser_->state_.side_effect_present = true;
|
||||
|
||||
result = nse.var_node;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -23845,6 +23973,8 @@ namespace exprtk
|
|||
|
||||
void lodge_assignment(symbol_type cst, expression_node_ptr node)
|
||||
{
|
||||
parser_->state_.side_effect_present = true;
|
||||
|
||||
if (!parser_->dec_.collect_assignments())
|
||||
return;
|
||||
|
||||
|
@ -24167,6 +24297,8 @@ namespace exprtk
|
|||
const bool v1_is_str = details::is_generally_string_node(branch[1]);
|
||||
#endif
|
||||
|
||||
expression_node_ptr result = error_node();
|
||||
|
||||
if (v0_is_ivar && v1_is_ivar)
|
||||
{
|
||||
typedef details::variable_node<T>* variable_node_ptr;
|
||||
|
@ -24179,19 +24311,19 @@ namespace exprtk
|
|||
(0 != (v1 = dynamic_cast<variable_node_ptr>(branch[1])))
|
||||
)
|
||||
{
|
||||
return node_allocator_->allocate<details::swap_node<T> >(v0,v1);
|
||||
result = node_allocator_->allocate<details::swap_node<T> >(v0,v1);
|
||||
}
|
||||
else
|
||||
return node_allocator_->allocate<details::swap_generic_node<T> >(branch[0],branch[1]);
|
||||
result = node_allocator_->allocate<details::swap_generic_node<T> >(branch[0],branch[1]);
|
||||
}
|
||||
else if (v0_is_ivec && v1_is_ivec)
|
||||
{
|
||||
return node_allocator_->allocate<details::swap_vecvec_node<T> >(branch[0],branch[1]);
|
||||
result = node_allocator_->allocate<details::swap_vecvec_node<T> >(branch[0],branch[1]);
|
||||
}
|
||||
#ifndef exprtk_disable_string_capabilities
|
||||
else if (v0_is_str && v1_is_str)
|
||||
{
|
||||
return node_allocator_->allocate<details::swap_string_node<T> >(branch[0],branch[1]);
|
||||
result = node_allocator_->allocate<details::swap_string_node<T> >(branch[0],branch[1]);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
|
@ -24200,6 +24332,10 @@ namespace exprtk
|
|||
|
||||
return error_node();
|
||||
}
|
||||
|
||||
parser_->state_.side_effect_present = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef exprtk_disable_sc_andor
|
||||
|
@ -30173,8 +30309,10 @@ namespace exprtk
|
|||
|
||||
return node_allocator_->allocate<literal_node_t>(v);
|
||||
}
|
||||
else
|
||||
return expression_point;
|
||||
|
||||
parser_->state_.side_effect_present = true;
|
||||
|
||||
return expression_point;
|
||||
}
|
||||
|
||||
bool strength_reduction_enabled_;
|
||||
|
|
|
@ -44,7 +44,8 @@ arithmetic operations, functions and processes:
|
|||
(09) String
|
||||
processing: in, like, ilike, concatenation
|
||||
|
||||
(10) Optimisations: constant-folding and simple strength reduction
|
||||
(10) Optimisations: constant-folding, simple strength reduction and
|
||||
dead code elimination
|
||||
|
||||
(11) Calculus: numerical integration and differentiation
|
||||
|
||||
|
|
Loading…
Reference in New Issue