C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html
This commit is contained in:
parent
e39ec67df9
commit
85c094a1aa
351
exprtk.hpp
351
exprtk.hpp
|
@ -37,6 +37,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <complex>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
@ -656,6 +657,7 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
struct unknown_type_tag {};
|
struct unknown_type_tag {};
|
||||||
struct real_type_tag {};
|
struct real_type_tag {};
|
||||||
|
struct complex_type_tag {};
|
||||||
struct int_type_tag {};
|
struct int_type_tag {};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -664,6 +666,10 @@ namespace exprtk
|
||||||
#define exprtk_register_real_type_tag(T) \
|
#define exprtk_register_real_type_tag(T) \
|
||||||
template<> struct number_type<T> { typedef real_type_tag type; }; \
|
template<> struct number_type<T> { typedef real_type_tag type; }; \
|
||||||
|
|
||||||
|
#define exprtk_register_complex_type_tag(T) \
|
||||||
|
template<> struct number_type<std::complex<T> > \
|
||||||
|
{ typedef complex_type_tag type; }; \
|
||||||
|
|
||||||
#define exprtk_register_int_type_tag(T) \
|
#define exprtk_register_int_type_tag(T) \
|
||||||
template<> struct number_type<T> { typedef int_type_tag type; }; \
|
template<> struct number_type<T> { typedef int_type_tag type; }; \
|
||||||
|
|
||||||
|
@ -671,6 +677,10 @@ namespace exprtk
|
||||||
exprtk_register_real_type_tag(long double)
|
exprtk_register_real_type_tag(long double)
|
||||||
exprtk_register_real_type_tag(float )
|
exprtk_register_real_type_tag(float )
|
||||||
|
|
||||||
|
exprtk_register_complex_type_tag(double )
|
||||||
|
exprtk_register_complex_type_tag(long double)
|
||||||
|
exprtk_register_complex_type_tag(float )
|
||||||
|
|
||||||
exprtk_register_int_type_tag(short )
|
exprtk_register_int_type_tag(short )
|
||||||
exprtk_register_int_type_tag(int )
|
exprtk_register_int_type_tag(int )
|
||||||
exprtk_register_int_type_tag(long long int )
|
exprtk_register_int_type_tag(long long int )
|
||||||
|
@ -797,14 +807,16 @@ namespace exprtk
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T nequal_impl(const T v0, const T v1, real_type_tag)
|
inline T nequal_impl(const T v0, const T v1, real_type_tag)
|
||||||
{
|
{
|
||||||
|
typedef real_type_tag rtg;
|
||||||
const T epsilon = epsilon_type<T>::value();
|
const T epsilon = epsilon_type<T>::value();
|
||||||
return (abs_impl(v0 - v1,real_type_tag()) > (std::max(T(1),std::max(abs_impl(v0,real_type_tag()),abs_impl(v1,real_type_tag()))) * epsilon)) ? T(1) : T(0);
|
return (abs_impl(v0 - v1,rtg()) > (std::max(T(1),std::max(abs_impl(v0,rtg()),abs_impl(v1,rtg()))) * epsilon)) ? T(1) : T(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float nequal_impl(const float v0, const float v1, real_type_tag)
|
inline float nequal_impl(const float v0, const float v1, real_type_tag)
|
||||||
{
|
{
|
||||||
|
typedef real_type_tag rtg;
|
||||||
const float epsilon = epsilon_type<float>::value();
|
const float epsilon = epsilon_type<float>::value();
|
||||||
return (abs_impl(v0 - v1,real_type_tag()) > (std::max(1.0f,std::max(abs_impl(v0,real_type_tag()),abs_impl(v1,real_type_tag()))) * epsilon)) ? 1.0f : 0.0f;
|
return (abs_impl(v0 - v1,rtg()) > (std::max(1.0f,std::max(abs_impl(v0,rtg()),abs_impl(v1,rtg()))) * epsilon)) ? 1.0f : 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -4282,6 +4294,12 @@ namespace exprtk
|
||||||
return std::not_equal_to<float>()(0.0f,v);
|
return std::not_equal_to<float>()(0.0f,v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool is_true(const std::complex<T>& v)
|
||||||
|
{
|
||||||
|
return std::not_equal_to<std::complex<T> >()(std::complex<T>(0),v);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool is_true(const expression_node<T>* node)
|
inline bool is_true(const expression_node<T>* node)
|
||||||
{
|
{
|
||||||
|
@ -10290,10 +10308,9 @@ namespace exprtk
|
||||||
typedef expression_node<T>* expression_ptr;
|
typedef expression_node<T>* expression_ptr;
|
||||||
typedef results_context<T> results_context_t;
|
typedef results_context<T> results_context_t;
|
||||||
|
|
||||||
return_envelope_node(expression_ptr body,
|
return_envelope_node(expression_ptr body, results_context_t& rc)
|
||||||
results_context_t& rc, bool& rtrn_invoked)
|
|
||||||
: results_context_(&rc),
|
: results_context_(&rc),
|
||||||
return_invoked_ (rtrn_invoked),
|
return_invoked_ (false),
|
||||||
body_ (body),
|
body_ (body),
|
||||||
body_deletable_ (branch_deletable(body_))
|
body_deletable_ (branch_deletable(body_))
|
||||||
{}
|
{}
|
||||||
|
@ -10327,10 +10344,15 @@ namespace exprtk
|
||||||
return expression_node<T>::e_retenv;
|
return expression_node<T>::e_retenv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool* retinvk_ptr()
|
||||||
|
{
|
||||||
|
return &return_invoked_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
results_context_t* results_context_;
|
results_context_t* results_context_;
|
||||||
bool& return_invoked_;
|
mutable bool return_invoked_;
|
||||||
expression_ptr body_;
|
expression_ptr body_;
|
||||||
bool body_deletable_;
|
bool body_deletable_;
|
||||||
};
|
};
|
||||||
|
@ -13603,13 +13625,6 @@ namespace exprtk
|
||||||
return new node_type(t1,t2);
|
return new node_type(t1,t2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename node_type,
|
|
||||||
typename T1, typename T2, typename T3>
|
|
||||||
inline expression_node<typename node_type::value_type>* allocate_crr(const T1& t1, T2& t2, T3& t3) const
|
|
||||||
{
|
|
||||||
return new node_type(t1,t2,t3);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename node_type,
|
template <typename node_type,
|
||||||
typename T1, typename T2>
|
typename T1, typename T2>
|
||||||
inline expression_node<typename node_type::value_type>* allocate_rc(T1& t1, const T2& t2) const
|
inline expression_node<typename node_type::value_type>* allocate_rc(T1& t1, const T2& t2) const
|
||||||
|
@ -15425,14 +15440,16 @@ namespace exprtk
|
||||||
: ref_count(0),
|
: ref_count(0),
|
||||||
expr (0),
|
expr (0),
|
||||||
results (0),
|
results (0),
|
||||||
return_invoked(false)
|
retinv_null(false),
|
||||||
|
return_invoked(&retinv_null)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
expression_holder(expression_ptr e)
|
expression_holder(expression_ptr e)
|
||||||
: ref_count(1),
|
: ref_count(1),
|
||||||
expr (e),
|
expr (e),
|
||||||
results (0),
|
results (0),
|
||||||
return_invoked(false)
|
retinv_null(false),
|
||||||
|
return_invoked(&retinv_null)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
~expression_holder()
|
~expression_holder()
|
||||||
|
@ -15478,7 +15495,8 @@ namespace exprtk
|
||||||
expression_ptr expr;
|
expression_ptr expr;
|
||||||
local_data_list_t local_data_list;
|
local_data_list_t local_data_list;
|
||||||
results_context_t* results;
|
results_context_t* results;
|
||||||
bool return_invoked;
|
bool retinv_null;
|
||||||
|
bool* return_invoked;
|
||||||
|
|
||||||
friend class function_compositor<T>;
|
friend class function_compositor<T>;
|
||||||
};
|
};
|
||||||
|
@ -15609,7 +15627,7 @@ namespace exprtk
|
||||||
|
|
||||||
inline bool return_invoked() const
|
inline bool return_invoked() const
|
||||||
{
|
{
|
||||||
return (expression_holder_->return_invoked);
|
return (*expression_holder_->return_invoked);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -15703,15 +15721,18 @@ namespace exprtk
|
||||||
|
|
||||||
inline void register_return_results(results_context_t* rc)
|
inline void register_return_results(results_context_t* rc)
|
||||||
{
|
{
|
||||||
if (rc)
|
if (expression_holder_ && rc)
|
||||||
{
|
{
|
||||||
expression_holder_->results = rc;
|
expression_holder_->results = rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool& rtrn_invk_ref()
|
inline void set_retinvk(bool* retinvk_ptr)
|
||||||
{
|
{
|
||||||
return expression_holder_->return_invoked;
|
if (expression_holder_)
|
||||||
|
{
|
||||||
|
expression_holder_->return_invoked = retinvk_ptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expression_holder* expression_holder_;
|
expression_holder* expression_holder_;
|
||||||
|
@ -16109,12 +16130,14 @@ namespace exprtk
|
||||||
inline scope_element& get_element(const std::string& var_name,
|
inline scope_element& get_element(const std::string& var_name,
|
||||||
const std::size_t index = std::numeric_limits<std::size_t>::max())
|
const std::size_t index = std::numeric_limits<std::size_t>::max())
|
||||||
{
|
{
|
||||||
|
const std::size_t current_depth = parser_.state_.scope_depth;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < element_.size(); ++i)
|
for (std::size_t i = 0; i < element_.size(); ++i)
|
||||||
{
|
{
|
||||||
scope_element& se = element_[i];
|
scope_element& se = element_[i];
|
||||||
|
|
||||||
if (se.depth > parser_.state_.scope_depth)
|
if (se.depth > current_depth)
|
||||||
return null_element_;
|
continue;
|
||||||
else if (
|
else if (
|
||||||
(se.name == var_name) &&
|
(se.name == var_name) &&
|
||||||
(se.index == index)
|
(se.index == index)
|
||||||
|
@ -16128,15 +16151,17 @@ namespace exprtk
|
||||||
inline scope_element& get_active_element(const std::string& var_name,
|
inline scope_element& get_active_element(const std::string& var_name,
|
||||||
const std::size_t index = std::numeric_limits<std::size_t>::max())
|
const std::size_t index = std::numeric_limits<std::size_t>::max())
|
||||||
{
|
{
|
||||||
|
const std::size_t current_depth = parser_.state_.scope_depth;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < element_.size(); ++i)
|
for (std::size_t i = 0; i < element_.size(); ++i)
|
||||||
{
|
{
|
||||||
scope_element& se = element_[i];
|
scope_element& se = element_[i];
|
||||||
|
|
||||||
if (se.depth > parser_.state_.scope_depth)
|
if (se.depth > current_depth)
|
||||||
return null_element_;
|
continue;
|
||||||
else if (
|
else if (
|
||||||
(se.name == var_name) &&
|
(se.name == var_name) &&
|
||||||
(se.index == index) &&
|
(se.index == index) &&
|
||||||
(se.active)
|
(se.active)
|
||||||
)
|
)
|
||||||
return se;
|
return se;
|
||||||
|
@ -17398,15 +17423,19 @@ namespace exprtk
|
||||||
|
|
||||||
if ((0 != e) && (token_t::e_eof == current_token().type))
|
if ((0 != e) && (token_t::e_eof == current_token().type))
|
||||||
{
|
{
|
||||||
|
bool* retinvk_ptr = 0;
|
||||||
|
|
||||||
if (state_.return_stmt_present)
|
if (state_.return_stmt_present)
|
||||||
{
|
{
|
||||||
dec_.return_present_ = true;
|
dec_.return_present_ = true;
|
||||||
|
|
||||||
e = expression_generator_
|
e = expression_generator_
|
||||||
.return_envelope(e,results_context_,expr.rtrn_invk_ref());
|
.return_envelope(e,results_context_,retinvk_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr.set_expression(e);
|
expr.set_expression(e);
|
||||||
|
expr.set_retinvk(retinvk_ptr);
|
||||||
|
|
||||||
register_local_vars(expr);
|
register_local_vars(expr);
|
||||||
register_return_results(expr);
|
register_return_results(expr);
|
||||||
|
|
||||||
|
@ -24166,11 +24195,16 @@ namespace exprtk
|
||||||
|
|
||||||
inline expression_node_ptr return_envelope(expression_node_ptr body,
|
inline expression_node_ptr return_envelope(expression_node_ptr body,
|
||||||
results_context_t* rc,
|
results_context_t* rc,
|
||||||
bool& return_invoked)
|
bool*& return_invoked)
|
||||||
{
|
{
|
||||||
typedef details::return_envelope_node<Type> alloc_type;
|
typedef details::return_envelope_node<Type> alloc_type;
|
||||||
|
|
||||||
return node_allocator_->allocate_crr<alloc_type>(body,(*rc),return_invoked);
|
expression_node_ptr result = node_allocator_->
|
||||||
|
allocate_cr<alloc_type>(body,(*rc));
|
||||||
|
|
||||||
|
return_invoked = static_cast<alloc_type*>(result)->retinvk_ptr();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline expression_node_ptr vector_element(const std::string& symbol,
|
inline expression_node_ptr vector_element(const std::string& symbol,
|
||||||
|
@ -31465,6 +31499,52 @@ namespace exprtk
|
||||||
: name_(n)
|
: name_(n)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
function(const std::string& name,
|
||||||
|
const std::string& expression)
|
||||||
|
: name_(name),
|
||||||
|
expression_(expression)
|
||||||
|
{}
|
||||||
|
|
||||||
|
function(const std::string& name,
|
||||||
|
const std::string& expression,
|
||||||
|
const std::string& v0)
|
||||||
|
: name_(name),
|
||||||
|
expression_(expression)
|
||||||
|
{
|
||||||
|
v_.push_back(v0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function(const std::string& name,
|
||||||
|
const std::string& expression,
|
||||||
|
const std::string& v0, const std::string& v1)
|
||||||
|
: name_(name),
|
||||||
|
expression_(expression)
|
||||||
|
{
|
||||||
|
v_.push_back(v0); v_.push_back(v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function(const std::string& name,
|
||||||
|
const std::string& expression,
|
||||||
|
const std::string& v0, const std::string& v1,
|
||||||
|
const std::string& v2)
|
||||||
|
: name_(name),
|
||||||
|
expression_(expression)
|
||||||
|
{
|
||||||
|
v_.push_back(v0); v_.push_back(v1);
|
||||||
|
v_.push_back(v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function(const std::string& name,
|
||||||
|
const std::string& expression,
|
||||||
|
const std::string& v0, const std::string& v1,
|
||||||
|
const std::string& v2, const std::string& v3)
|
||||||
|
: name_(name),
|
||||||
|
expression_(expression)
|
||||||
|
{
|
||||||
|
v_.push_back(v0); v_.push_back(v1);
|
||||||
|
v_.push_back(v2); v_.push_back(v3);
|
||||||
|
}
|
||||||
|
|
||||||
inline function& name(const std::string& n)
|
inline function& name(const std::string& n)
|
||||||
{
|
{
|
||||||
name_ = n;
|
name_ = n;
|
||||||
|
@ -31685,6 +31765,11 @@ namespace exprtk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline virtual T value(expression_t& e)
|
||||||
|
{
|
||||||
|
return e.value();
|
||||||
|
}
|
||||||
|
|
||||||
expression_t expression;
|
expression_t expression;
|
||||||
varref_t v;
|
varref_t v;
|
||||||
lvr_vec_t lv;
|
lvr_vec_t lv;
|
||||||
|
@ -31702,7 +31787,7 @@ namespace exprtk
|
||||||
|
|
||||||
inline T operator()()
|
inline T operator()()
|
||||||
{
|
{
|
||||||
return base_func::expression.value();
|
return this->value(base_func::expression);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31716,7 +31801,7 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
base_func::pre();
|
base_func::pre();
|
||||||
base_func::update(v0);
|
base_func::update(v0);
|
||||||
T result = base_func::expression.value();
|
T result = this->value(base_func::expression);
|
||||||
base_func::post();
|
base_func::post();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -31730,7 +31815,7 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
base_func::pre();
|
base_func::pre();
|
||||||
base_func::update(v0,v1);
|
base_func::update(v0,v1);
|
||||||
T result = base_func::expression.value();
|
T result = this->value(base_func::expression);
|
||||||
base_func::post();
|
base_func::post();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -31744,7 +31829,7 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
base_func::pre();
|
base_func::pre();
|
||||||
base_func::update(v0,v1,v2);
|
base_func::update(v0,v1,v2);
|
||||||
T result = base_func::expression.value();
|
T result = this->value(base_func::expression);
|
||||||
base_func::post();
|
base_func::post();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -31758,7 +31843,7 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
base_func::pre();
|
base_func::pre();
|
||||||
base_func::update(v0,v1,v2,v3);
|
base_func::update(v0,v1,v2,v3);
|
||||||
T result = base_func::expression.value();
|
T result = this->value(base_func::expression);
|
||||||
base_func::post();
|
base_func::post();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -31772,7 +31857,7 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
base_func::pre();
|
base_func::pre();
|
||||||
base_func::update(v0,v1,v2,v3,v4);
|
base_func::update(v0,v1,v2,v3,v4);
|
||||||
T result = base_func::expression.value();
|
T result = this->value(base_func::expression);
|
||||||
base_func::post();
|
base_func::post();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -31786,12 +31871,49 @@ namespace exprtk
|
||||||
{
|
{
|
||||||
base_func::pre();
|
base_func::pre();
|
||||||
base_func::update(v0,v1,v2,v3,v4,v5);
|
base_func::update(v0,v1,v2,v3,v4,v5);
|
||||||
T result = base_func::expression.value();
|
T result = this->value(base_func::expression);
|
||||||
base_func::post();
|
base_func::post();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static T return_value(expression_t& e)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
T result = e.value();
|
||||||
|
|
||||||
|
if (
|
||||||
|
e.return_invoked() &&
|
||||||
|
(e.results().count() >= 1) &&
|
||||||
|
(type_t::e_scalar == e.results()[0].type)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
result = scalar_t(e.results()[0])();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define def_fp_retval(N) \
|
||||||
|
struct func_##N##param_retval : public func_##N##param \
|
||||||
|
{ \
|
||||||
|
inline T value(expression_t& e) \
|
||||||
|
{ \
|
||||||
|
return return_value(e); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
|
||||||
|
def_fp_retval(0)
|
||||||
|
def_fp_retval(1)
|
||||||
|
def_fp_retval(2)
|
||||||
|
def_fp_retval(3)
|
||||||
|
def_fp_retval(4)
|
||||||
|
def_fp_retval(5)
|
||||||
|
def_fp_retval(6)
|
||||||
|
|
||||||
template <typename Allocator,
|
template <typename Allocator,
|
||||||
template <typename,typename> class Sequence>
|
template <typename,typename> class Sequence>
|
||||||
inline bool add(const std::string& name,
|
inline bool add(const std::string& name,
|
||||||
|
@ -31857,89 +31979,14 @@ namespace exprtk
|
||||||
return add(f.name_,f.expression_,f.v_);
|
return add(f.name_,f.expression_,f.v_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool add(const std::string& name,
|
|
||||||
const std::string& expression)
|
|
||||||
{
|
|
||||||
const std::size_t n = 0;
|
|
||||||
std::vector<std::string> v(n);
|
|
||||||
return add(name,expression,v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool add(const std::string& name,
|
|
||||||
const std::string& expression,
|
|
||||||
const std::string& v0)
|
|
||||||
{
|
|
||||||
const std::size_t n = 1;
|
|
||||||
std::vector<std::string> v(n);
|
|
||||||
v[0] = v0;
|
|
||||||
return add(name,expression,v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool add(const std::string& name,
|
|
||||||
const std::string& expression,
|
|
||||||
const std::string& v0, const std::string& v1)
|
|
||||||
{
|
|
||||||
const std::size_t n = 2;
|
|
||||||
std::vector<std::string> v(n);
|
|
||||||
v[0] = v0; v[1] = v1;
|
|
||||||
return add(name,expression,v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool add(const std::string& name,
|
|
||||||
const std::string& expression,
|
|
||||||
const std::string& v0, const std::string& v1, const std::string& v2)
|
|
||||||
{
|
|
||||||
const std::size_t n = 3;
|
|
||||||
std::vector<std::string> v(n);
|
|
||||||
v[0] = v0; v[1] = v1; v[2] = v2;
|
|
||||||
return add(name,expression,v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool add(const std::string& name,
|
|
||||||
const std::string& expression,
|
|
||||||
const std::string& v0, const std::string& v1, const std::string& v2,
|
|
||||||
const std::string& v3)
|
|
||||||
{
|
|
||||||
const std::size_t n = 4;
|
|
||||||
std::vector<std::string> v(n);
|
|
||||||
v[0] = v0; v[1] = v1;
|
|
||||||
v[2] = v2; v[3] = v3;
|
|
||||||
return add(name,expression,v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool add(const std::string& name,
|
|
||||||
const std::string& expression,
|
|
||||||
const std::string& v0, const std::string& v1, const std::string& v2,
|
|
||||||
const std::string& v3, const std::string& v4)
|
|
||||||
{
|
|
||||||
const std::size_t n = 5;
|
|
||||||
std::vector<std::string> v(n);
|
|
||||||
v[0] = v0; v[1] = v1;
|
|
||||||
v[2] = v2; v[3] = v3;
|
|
||||||
v[4] = v4;
|
|
||||||
return add(name,expression,v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool add(const std::string& name,
|
|
||||||
const std::string& expression,
|
|
||||||
const std::string& v0, const std::string& v1, const std::string& v2,
|
|
||||||
const std::string& v3, const std::string& v4, const std::string& v5)
|
|
||||||
{
|
|
||||||
const std::size_t n = 5;
|
|
||||||
std::vector<std::string> v(n);
|
|
||||||
v[0] = v0; v[1] = v1;
|
|
||||||
v[2] = v2; v[3] = v3;
|
|
||||||
v[4] = v4; v[5] = v5;
|
|
||||||
return add(name,expression,v);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template <typename Allocator,
|
template <typename Allocator,
|
||||||
template <typename,typename> class Sequence>
|
template <typename,typename> class Sequence>
|
||||||
bool compile_expression(const std::string& name,
|
bool compile_expression(const std::string& name,
|
||||||
const std::string& expression,
|
const std::string& expression,
|
||||||
const Sequence<std::string,Allocator>& input_var_list)
|
const Sequence<std::string,Allocator>& input_var_list,
|
||||||
|
bool return_present = false)
|
||||||
{
|
{
|
||||||
expression_t compiled_expression;
|
expression_t compiled_expression;
|
||||||
symbol_table_t local_symbol_table;
|
symbol_table_t local_symbol_table;
|
||||||
|
@ -31947,7 +31994,13 @@ namespace exprtk
|
||||||
local_symbol_table.load_from(symbol_table_);
|
local_symbol_table.load_from(symbol_table_);
|
||||||
local_symbol_table.add_constants();
|
local_symbol_table.add_constants();
|
||||||
|
|
||||||
if (!forward(name,input_var_list.size(),local_symbol_table))
|
if (!valid(name,input_var_list.size()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!forward(name,
|
||||||
|
input_var_list.size(),
|
||||||
|
local_symbol_table,
|
||||||
|
return_present))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
compiled_expression.register_symbol_table(local_symbol_table);
|
compiled_expression.register_symbol_table(local_symbol_table);
|
||||||
|
@ -31974,6 +32027,13 @@ namespace exprtk
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!return_present && parser_.dec().return_present())
|
||||||
|
{
|
||||||
|
remove(name,input_var_list.size());
|
||||||
|
|
||||||
|
return compile_expression(name,expression,input_var_list,true);
|
||||||
|
}
|
||||||
|
|
||||||
expr_map_[name] = compiled_expression;
|
expr_map_[name] = compiled_expression;
|
||||||
|
|
||||||
exprtk::ifunction<T>& ifunc = (*(fp_map_[input_var_list.size()])[name]);
|
exprtk::ifunction<T>& ifunc = (*(fp_map_[input_var_list.size()])[name]);
|
||||||
|
@ -31981,7 +32041,7 @@ namespace exprtk
|
||||||
return symbol_table_.add_function(name,ifunc);
|
return symbol_table_.add_function(name,ifunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool symbol_used(const std::string& symbol)
|
inline bool symbol_used(const std::string& symbol) const
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
symbol_table_.is_variable (symbol) ||
|
symbol_table_.is_variable (symbol) ||
|
||||||
|
@ -31992,46 +32052,42 @@ namespace exprtk
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool forward(const std::string& name, const std::size_t& arg_count, symbol_table_t& sym_table)
|
inline bool valid(const std::string& name,
|
||||||
|
const std::size_t& arg_count) const
|
||||||
{
|
{
|
||||||
if (arg_count > 6)
|
if (arg_count > 6)
|
||||||
return false;
|
return false;
|
||||||
else if (symbol_used(name))
|
else if (symbol_used(name))
|
||||||
return false;
|
return false;
|
||||||
else
|
else if (fp_map_[arg_count].end() != fp_map_[arg_count].find(name))
|
||||||
{
|
return false;
|
||||||
if (fp_map_[arg_count].end() != fp_map_[arg_count].find(name))
|
return true;
|
||||||
return false;
|
|
||||||
|
|
||||||
switch (arg_count)
|
|
||||||
{
|
|
||||||
case 0 : (fp_map_[arg_count])[name] = new func_0param(); break;
|
|
||||||
case 1 : (fp_map_[arg_count])[name] = new func_1param(); break;
|
|
||||||
case 2 : (fp_map_[arg_count])[name] = new func_2param(); break;
|
|
||||||
case 3 : (fp_map_[arg_count])[name] = new func_3param(); break;
|
|
||||||
case 4 : (fp_map_[arg_count])[name] = new func_4param(); break;
|
|
||||||
case 5 : (fp_map_[arg_count])[name] = new func_5param(); break;
|
|
||||||
case 6 : (fp_map_[arg_count])[name] = new func_6param(); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
exprtk::ifunction<T>& ifunc = (*(fp_map_[arg_count])[name]);
|
|
||||||
|
|
||||||
return sym_table.add_function(name,ifunc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Allocator,
|
inline bool forward(const std::string& name,
|
||||||
template <typename,typename> class Sequence>
|
const std::size_t& arg_count,
|
||||||
inline void remove(const std::string& name, const Sequence<std::string,Allocator>& v)
|
symbol_table_t& sym_table,
|
||||||
|
const bool ret_present = false)
|
||||||
{
|
{
|
||||||
symbol_table_.remove_function(name);
|
switch (arg_count)
|
||||||
|
|
||||||
for (std::size_t i = 0; i < v.size(); ++i)
|
|
||||||
{
|
{
|
||||||
symbol_table_.remove_variable(v[i]);
|
#define case_stmt(N) \
|
||||||
|
case N : (fp_map_[arg_count])[name] = \
|
||||||
|
(!ret_present) ? static_cast<base_func*> \
|
||||||
|
(new func_##N##param) : \
|
||||||
|
static_cast<base_func*> \
|
||||||
|
(new func_##N##param_retval) ; \
|
||||||
|
break; \
|
||||||
|
|
||||||
|
case_stmt(0) case_stmt(1) case_stmt(2)
|
||||||
|
case_stmt(3) case_stmt(4) case_stmt(5)
|
||||||
|
case_stmt(6)
|
||||||
|
#undef case_stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(name,v.size());
|
exprtk::ifunction<T>& ifunc = (*(fp_map_[arg_count])[name]);
|
||||||
|
|
||||||
|
return sym_table.add_function(name,ifunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void remove(const std::string& name, const std::size_t& arg_count)
|
inline void remove(const std::string& name, const std::size_t& arg_count)
|
||||||
|
@ -32049,11 +32105,12 @@ namespace exprtk
|
||||||
typename funcparam_t::iterator fp_itr = fp_map_[arg_count].find(name);
|
typename funcparam_t::iterator fp_itr = fp_map_[arg_count].find(name);
|
||||||
|
|
||||||
if (fp_map_[arg_count].end() != fp_itr)
|
if (fp_map_[arg_count].end() != fp_itr)
|
||||||
return;
|
{
|
||||||
else
|
|
||||||
delete fp_itr->second;
|
delete fp_itr->second;
|
||||||
|
fp_map_[arg_count].erase(fp_itr);
|
||||||
|
}
|
||||||
|
|
||||||
fp_map_[arg_count].erase(fp_itr);
|
symbol_table_.remove_function(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -28,11 +28,14 @@ void fibonacci()
|
||||||
typedef exprtk::expression<T> expression_t;
|
typedef exprtk::expression<T> expression_t;
|
||||||
typedef exprtk::parser<T> parser_t;
|
typedef exprtk::parser<T> parser_t;
|
||||||
typedef exprtk::function_compositor<T> compositor_t;
|
typedef exprtk::function_compositor<T> compositor_t;
|
||||||
|
typedef typename compositor_t::function function_t;
|
||||||
|
|
||||||
compositor_t compositor;
|
compositor_t compositor;
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("fibonacci",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"fibonacci",
|
||||||
" var w := 0; "
|
" var w := 0; "
|
||||||
" var y := 0; "
|
" var y := 0; "
|
||||||
" var z := 1; "
|
" var z := 1; "
|
||||||
|
@ -49,7 +52,7 @@ void fibonacci()
|
||||||
" z "
|
" z "
|
||||||
" }; "
|
" }; "
|
||||||
" } ",
|
" } ",
|
||||||
"x");
|
"x"));
|
||||||
|
|
||||||
T x = T(0);
|
T x = T(0);
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ void composite()
|
||||||
typedef exprtk::parser<T> parser_t;
|
typedef exprtk::parser<T> parser_t;
|
||||||
typedef exprtk::parser_error::type error_t;
|
typedef exprtk::parser_error::type error_t;
|
||||||
typedef exprtk::function_compositor<T> compositor_t;
|
typedef exprtk::function_compositor<T> compositor_t;
|
||||||
|
typedef typename compositor_t::function function_t;
|
||||||
|
|
||||||
compositor_t compositor;
|
compositor_t compositor;
|
||||||
|
|
||||||
|
@ -40,8 +41,13 @@ void composite()
|
||||||
symbol_table.add_variable("x",x);
|
symbol_table.add_variable("x",x);
|
||||||
symbol_table.add_variable("y",y);
|
symbol_table.add_variable("y",y);
|
||||||
|
|
||||||
compositor.add("f","sin(x / pi)","x"); // f(x) = sin(x / pi)
|
compositor
|
||||||
compositor.add("g","3*[f(x) + f(y)]","x","y"); // g(x,y) = 3[f(x) + f(y)]
|
.add(
|
||||||
|
function_t("f","sin(x / pi)","x")); // f(x) = sin(x / pi)
|
||||||
|
|
||||||
|
compositor
|
||||||
|
.add(
|
||||||
|
function_t("g","3*[f(x) + f(y)]","x","y")); // g(x,y) = 3[f(x) + f(y)]
|
||||||
|
|
||||||
std::string expression_string = "g(1 + f(x),f(y) / 2)";
|
std::string expression_string = "g(1 + f(x),f(y) / 2)";
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ void primes()
|
||||||
typedef exprtk::expression<T> expression_t;
|
typedef exprtk::expression<T> expression_t;
|
||||||
typedef exprtk::parser<T> parser_t;
|
typedef exprtk::parser<T> parser_t;
|
||||||
typedef exprtk::function_compositor<T> compositor_t;
|
typedef exprtk::function_compositor<T> compositor_t;
|
||||||
|
typedef typename compositor_t::function function_t;
|
||||||
|
|
||||||
T x = T(0);
|
T x = T(0);
|
||||||
|
|
||||||
|
@ -40,43 +41,53 @@ void primes()
|
||||||
|
|
||||||
//Mode 1 - if statement based
|
//Mode 1 - if statement based
|
||||||
compositor
|
compositor
|
||||||
.add("is_prime_impl1",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"is_prime_impl1",
|
||||||
"if(y == 1,true, "
|
"if(y == 1,true, "
|
||||||
" if(0 == (x % y),false, "
|
" if(0 == (x % y),false, "
|
||||||
" is_prime_impl1(x,y - 1)))",
|
" is_prime_impl1(x,y - 1)))",
|
||||||
"x","y");
|
"x","y"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("is_prime1",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"is_prime1",
|
||||||
"if(frac(x) != 0, false, "
|
"if(frac(x) != 0, false, "
|
||||||
" if(x <= 0, false, "
|
" if(x <= 0, false, "
|
||||||
" is_prime_impl1(x,min(x - 1,trunc(sqrt(x)) + 1))))",
|
" is_prime_impl1(x,min(x - 1,trunc(sqrt(x)) + 1))))",
|
||||||
"x");
|
"x"));
|
||||||
|
|
||||||
//Mode 2 - switch statement based
|
//Mode 2 - switch statement based
|
||||||
compositor
|
compositor
|
||||||
.add("is_prime_impl2",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"is_prime_impl2",
|
||||||
"switch "
|
"switch "
|
||||||
"{ "
|
"{ "
|
||||||
" case y == 1 : true; "
|
" case y == 1 : true; "
|
||||||
" case (x % y) == 0 : false; "
|
" case (x % y) == 0 : false; "
|
||||||
" default : is_prime_impl2(x,y - 1);"
|
" default : is_prime_impl2(x,y - 1);"
|
||||||
"} ",
|
"} ",
|
||||||
"x","y");
|
"x","y"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("is_prime2",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"is_prime2",
|
||||||
"switch "
|
"switch "
|
||||||
"{ "
|
"{ "
|
||||||
" case x <= 0 : false; "
|
" case x <= 0 : false; "
|
||||||
" case frac(x) != 0 : false; "
|
" case frac(x) != 0 : false; "
|
||||||
" default : is_prime_impl2(x,min(x - 1,trunc(sqrt(x)) + 1));"
|
" default : is_prime_impl2(x,min(x - 1,trunc(sqrt(x)) + 1));"
|
||||||
"} ",
|
"} ",
|
||||||
"x");
|
"x"));
|
||||||
|
|
||||||
//Mode 3 - switch statement and while-loop based
|
//Mode 3 - switch statement and while-loop based
|
||||||
compositor
|
compositor
|
||||||
.add("is_prime_impl3",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"is_prime_impl3",
|
||||||
"while (y > 0) "
|
"while (y > 0) "
|
||||||
"{ "
|
"{ "
|
||||||
" switch "
|
" switch "
|
||||||
|
@ -86,17 +97,19 @@ void primes()
|
||||||
" default : y := y - 1; "
|
" default : y := y - 1; "
|
||||||
" } "
|
" } "
|
||||||
"} ",
|
"} ",
|
||||||
"x","y");
|
"x","y"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("is_prime3",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"is_prime3",
|
||||||
"switch "
|
"switch "
|
||||||
"{ "
|
"{ "
|
||||||
" case x <= 0 : false; "
|
" case x <= 0 : false; "
|
||||||
" case frac(x) != 0 : false; "
|
" case frac(x) != 0 : false; "
|
||||||
" default : is_prime_impl3(x,min(x - 1,trunc(sqrt(x)) + 1));"
|
" default : is_prime_impl3(x,min(x - 1,trunc(sqrt(x)) + 1));"
|
||||||
"} ",
|
"} ",
|
||||||
"x");
|
"x"));
|
||||||
|
|
||||||
std::string expression_str1 = "is_prime1(x)";
|
std::string expression_str1 = "is_prime1(x)";
|
||||||
std::string expression_str2 = "is_prime2(x)";
|
std::string expression_str2 = "is_prime2(x)";
|
||||||
|
|
|
@ -29,6 +29,7 @@ void newton_sqrt()
|
||||||
typedef exprtk::expression<T> expression_t;
|
typedef exprtk::expression<T> expression_t;
|
||||||
typedef exprtk::parser<T> parser_t;
|
typedef exprtk::parser<T> parser_t;
|
||||||
typedef exprtk::function_compositor<T> compositor_t;
|
typedef exprtk::function_compositor<T> compositor_t;
|
||||||
|
typedef typename compositor_t::function function_t;
|
||||||
|
|
||||||
T x = T(0);
|
T x = T(0);
|
||||||
|
|
||||||
|
@ -40,7 +41,9 @@ void newton_sqrt()
|
||||||
compositor_t compositor(symbol_table);
|
compositor_t compositor(symbol_table);
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("newton_sqrt",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"newton_sqrt",
|
||||||
" switch "
|
" switch "
|
||||||
" { "
|
" { "
|
||||||
" case x < 0 : -inf; "
|
" case x < 0 : -inf; "
|
||||||
|
@ -57,7 +60,7 @@ void newton_sqrt()
|
||||||
" until ((z -= 1) <= 0); "
|
" until ((z -= 1) <= 0); "
|
||||||
" }; "
|
" }; "
|
||||||
" } ",
|
" } ",
|
||||||
"x");
|
"x"));
|
||||||
|
|
||||||
std::string expression_str = "newton_sqrt(x)";
|
std::string expression_str = "newton_sqrt(x)";
|
||||||
|
|
||||||
|
|
173
exprtk_test.cpp
173
exprtk_test.cpp
|
@ -5719,28 +5719,28 @@ inline bool run_test19()
|
||||||
compositor_t compositor;
|
compositor_t compositor;
|
||||||
|
|
||||||
// f(x) = x + 2
|
// f(x) = x + 2
|
||||||
compositor.add("f","x + 2","x");
|
compositor.add(function_t("f","x + 2","x"));
|
||||||
|
|
||||||
// g(x) = x^2-3
|
// g(x) = x^2-3
|
||||||
compositor.add("g","x^2 - 3","x");
|
compositor.add(function_t("g","x^2 - 3","x"));
|
||||||
|
|
||||||
// fof(x) = f(f(x))
|
// fof(x) = f(f(x))
|
||||||
compositor.add("fof","f(f(x))","x");
|
compositor.add(function_t("fof","f(f(x))","x"));
|
||||||
|
|
||||||
// gog(x) = g(g(x))
|
// gog(x) = g(g(x))
|
||||||
compositor.add("gog","g(g(x))","x");
|
compositor.add(function_t("gog","g(g(x))","x"));
|
||||||
|
|
||||||
// fog(x) = f(g(x))
|
// fog(x) = f(g(x))
|
||||||
compositor.add("fog","f(g(x))","x");
|
compositor.add(function_t("fog","f(g(x))","x"));
|
||||||
|
|
||||||
// gof(x) = g(f(x))
|
// gof(x) = g(f(x))
|
||||||
compositor.add("gof","g(f(x))","x");
|
compositor.add(function_t("gof","g(f(x))","x"));
|
||||||
|
|
||||||
// fogof(x) = f(g(f(x)))
|
// fogof(x) = f(g(f(x)))
|
||||||
compositor.add("fogof","f(g(f(x)))","x");
|
compositor.add(function_t("fogof","f(g(f(x)))","x"));
|
||||||
|
|
||||||
// gofog(x) = g(f(g(x)))
|
// gofog(x) = g(f(g(x)))
|
||||||
compositor.add("gofog","g(f(g(x)))","x");
|
compositor.add(function_t("gofog","g(f(g(x)))","x"));
|
||||||
|
|
||||||
symbol_table_t& symbol_table = compositor.symbol_table();
|
symbol_table_t& symbol_table = compositor.symbol_table();
|
||||||
symbol_table.add_constants();
|
symbol_table.add_constants();
|
||||||
|
@ -5798,6 +5798,7 @@ inline bool run_test19()
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::size_t rounds = 100;
|
const std::size_t rounds = 100;
|
||||||
|
|
||||||
for (std::size_t r = 0; r < rounds; ++r)
|
for (std::size_t r = 0; r < rounds; ++r)
|
||||||
{
|
{
|
||||||
T x = T(1);
|
T x = T(1);
|
||||||
|
@ -5811,29 +5812,44 @@ inline bool run_test19()
|
||||||
|
|
||||||
// f0() = 6
|
// f0() = 6
|
||||||
compositor
|
compositor
|
||||||
.add("f0"," 3 * 2");
|
.add(
|
||||||
|
function_t("f0")
|
||||||
|
.expression("3 * 2"));
|
||||||
|
|
||||||
// f1(x) = 5 * (f0 + x)
|
// f1(x) = 5 * (f0 + x)
|
||||||
compositor
|
compositor
|
||||||
.add("f1","5 * (f0 + x)","x");
|
.add(
|
||||||
|
function_t("f1")
|
||||||
|
.var("x")
|
||||||
|
.expression("5 * (f0 + x)"));
|
||||||
|
|
||||||
// f2(x,y) = 7 * (f1(x) + f1(y))
|
// f2(x,y) = 7 * (f1(x) + f1(y))
|
||||||
compositor
|
compositor
|
||||||
.add("f2","7 * (f1(x) + f1(y))","x","y");
|
.add(
|
||||||
|
function_t("f2")
|
||||||
|
.var("x").var("y")
|
||||||
|
.expression("7 * (f1(x) + f1(y))"));
|
||||||
|
|
||||||
// f3(x,y,z) = 9 * (f2(x,y) + f2(y,z) + f2(x,z))
|
// f3(x,y,z) = 9 * (f2(x,y) + f2(y,z) + f2(x,z))
|
||||||
compositor
|
compositor
|
||||||
.add("f3","9 * (f2(x,y) + f2(y,z) + f2(x,z))","x","y","z");
|
.add(
|
||||||
|
function_t("f3")
|
||||||
|
.var("x").var("y").var("z")
|
||||||
|
.expression("9 * (f2(x,y) + f2(y,z) + f2(x,z))"));
|
||||||
|
|
||||||
// f4(x,y,z,w) = 11 * (f3(x,y,z) + f3(y,z,w) + f3(z,w,z))
|
// f4(x,y,z,w) = 11 * (f3(x,y,z) + f3(y,z,w) + f3(z,w,z))
|
||||||
compositor
|
compositor
|
||||||
.add("f4","11 * (f3(x,y,z) + f3(y,z,w) + f3(z,w,x))","x","y","z","w");
|
.add(
|
||||||
|
function_t("f4")
|
||||||
|
.var("x").var("y").var("z").var("w")
|
||||||
|
.expression("11 * (f3(x,y,z) + f3(y,z,w) + f3(z,w,x))"));
|
||||||
|
|
||||||
// f5(x,y,z,w,u) = 13 * (f4(x,y,z,w) + f4(y,z,w,u) + f4(z,w,u,x) + f4(w,u,x,y))
|
// f5(x,y,z,w,u) = 13 * (f4(x,y,z,w) + f4(y,z,w,u) + f4(z,w,u,x) + f4(w,u,x,y))
|
||||||
compositor
|
compositor
|
||||||
.add("f5",
|
.add(
|
||||||
"13 * (f4(x,y,z,w) + f4(y,z,w,u) + f4(z,w,u,x) + f4(w,u,x,y))",
|
function_t("f5")
|
||||||
"x","y","z","w","u");
|
.var("x").var("y").var("z").var("w").var("u")
|
||||||
|
.expression("13 * (f4(x,y,z,w) + f4(y,z,w,u) + f4(z,w,u,x) + f4(w,u,x,y))"));
|
||||||
|
|
||||||
// f6(x,y,z,w,u,v) = 17 * (f5(x,y,z,w,u) + f5(y,z,w,u,v) + f5(z,w,u,v,x) + f5(w,u,v,x,y))
|
// f6(x,y,z,w,u,v) = 17 * (f5(x,y,z,w,u) + f5(y,z,w,u,v) + f5(z,w,u,v,x) + f5(w,u,v,x,y))
|
||||||
compositor
|
compositor
|
||||||
|
@ -5887,6 +5903,8 @@ inline bool run_test19()
|
||||||
T(2122700580)
|
T(2122700580)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool failure = true;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < expr_str_list_size; ++i)
|
for (std::size_t i = 0; i < expr_str_list_size; ++i)
|
||||||
{
|
{
|
||||||
expression_t expression;
|
expression_t expression;
|
||||||
|
@ -5898,7 +5916,8 @@ inline bool run_test19()
|
||||||
parser.error().c_str(),
|
parser.error().c_str(),
|
||||||
expr_str_list[i].c_str());
|
expr_str_list[i].c_str());
|
||||||
|
|
||||||
return false;
|
failure = true;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
T result = expression.value();
|
T result = expression.value();
|
||||||
|
@ -5910,9 +5929,13 @@ inline bool run_test19()
|
||||||
result_list[i],
|
result_list[i],
|
||||||
result);
|
result);
|
||||||
|
|
||||||
return false;
|
failure = true;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!failure)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -5921,41 +5944,51 @@ inline bool run_test19()
|
||||||
compositor_t compositor;
|
compositor_t compositor;
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("is_prime_impl1",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"is_prime_impl1",
|
||||||
"if (y == 1,true, "
|
"if (y == 1,true, "
|
||||||
" if (0 == (x % y),false, "
|
" if (0 == (x % y),false, "
|
||||||
" is_prime_impl1(x,y - 1))) ",
|
" is_prime_impl1(x,y - 1))) ",
|
||||||
"x","y");
|
"x","y"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("is_prime1",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"is_prime1",
|
||||||
"if (frac(x) != 0, false, "
|
"if (frac(x) != 0, false, "
|
||||||
" if (x <= 0, false, "
|
" if (x <= 0, false, "
|
||||||
" is_prime_impl1(x,min(x - 1,trunc(sqrt(x)) + 1)))) ",
|
" is_prime_impl1(x,min(x - 1,trunc(sqrt(x)) + 1)))) ",
|
||||||
"x");
|
"x"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("is_prime_impl2",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"is_prime_impl2",
|
||||||
"switch "
|
"switch "
|
||||||
"{ "
|
"{ "
|
||||||
" case y == 1 : true; "
|
" case y == 1 : true; "
|
||||||
" case (x % y) == 0 : false; "
|
" case (x % y) == 0 : false; "
|
||||||
" default : is_prime_impl2(x,y - 1);"
|
" default : is_prime_impl2(x,y - 1);"
|
||||||
"} ",
|
"} ",
|
||||||
"x","y");
|
"x","y"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("is_prime2",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"is_prime2",
|
||||||
"switch "
|
"switch "
|
||||||
"{ "
|
"{ "
|
||||||
" case x <= 0 : false; "
|
" case x <= 0 : false; "
|
||||||
" case frac(x) != 0 : false; "
|
" case frac(x) != 0 : false; "
|
||||||
" default : is_prime_impl2(x,min(x - 1,trunc(sqrt(x)) + 1));"
|
" default : is_prime_impl2(x,min(x - 1,trunc(sqrt(x)) + 1));"
|
||||||
"} ",
|
"} ",
|
||||||
"x");
|
"x"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("is_prime_impl3",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"is_prime_impl3",
|
||||||
"while (y > 0) "
|
"while (y > 0) "
|
||||||
"{ "
|
"{ "
|
||||||
" switch "
|
" switch "
|
||||||
|
@ -5965,20 +5998,24 @@ inline bool run_test19()
|
||||||
" default : y := y - 1; "
|
" default : y := y - 1; "
|
||||||
" } "
|
" } "
|
||||||
"} ",
|
"} ",
|
||||||
"x","y");
|
"x","y"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("is_prime3",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"is_prime3",
|
||||||
"switch "
|
"switch "
|
||||||
"{ "
|
"{ "
|
||||||
" case x <= 0 : false; "
|
" case x <= 0 : false; "
|
||||||
" case frac(x) != 0 : false; "
|
" case frac(x) != 0 : false; "
|
||||||
" default : is_prime_impl3(x,min(x - 1,trunc(sqrt(x)) + 1));"
|
" default : is_prime_impl3(x,min(x - 1,trunc(sqrt(x)) + 1));"
|
||||||
"} ",
|
"} ",
|
||||||
"x");
|
"x"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("is_prime_impl4",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"is_prime_impl4",
|
||||||
"switch "
|
"switch "
|
||||||
"{ "
|
"{ "
|
||||||
" case 1 == x : false; "
|
" case 1 == x : false; "
|
||||||
|
@ -5998,17 +6035,19 @@ inline bool run_test19()
|
||||||
" } "
|
" } "
|
||||||
" }; "
|
" }; "
|
||||||
"} ",
|
"} ",
|
||||||
"x","y");
|
"x","y"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("is_prime4",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"is_prime4",
|
||||||
"switch "
|
"switch "
|
||||||
"{ "
|
"{ "
|
||||||
" case x <= 0 : false; "
|
" case x <= 0 : false; "
|
||||||
" case frac(x) != 0 : false; "
|
" case frac(x) != 0 : false; "
|
||||||
" default : is_prime_impl4(x,min(x - 1,trunc(sqrt(x)) + 1));"
|
" default : is_prime_impl4(x,min(x - 1,trunc(sqrt(x)) + 1));"
|
||||||
"} ",
|
"} ",
|
||||||
"x");
|
"x"));
|
||||||
|
|
||||||
symbol_table_t& symbol_table = compositor.symbol_table();
|
symbol_table_t& symbol_table = compositor.symbol_table();
|
||||||
symbol_table.add_constants();
|
symbol_table.add_constants();
|
||||||
|
@ -6126,24 +6165,30 @@ inline bool run_test19()
|
||||||
compositor_t compositor;
|
compositor_t compositor;
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("fibonacci1",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"fibonacci1",
|
||||||
"if (x == 0,0, "
|
"if (x == 0,0, "
|
||||||
" if (x == 1,1, "
|
" if (x == 1,1, "
|
||||||
" fibonacci1(x - 1) + fibonacci1(x - 2)))",
|
" fibonacci1(x - 1) + fibonacci1(x - 2)))",
|
||||||
"x");
|
"x"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("fibonacci2",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"fibonacci2",
|
||||||
"switch "
|
"switch "
|
||||||
"{ "
|
"{ "
|
||||||
" case x == 0 : 0; "
|
" case x == 0 : 0; "
|
||||||
" case x == 1 : 1; "
|
" case x == 1 : 1; "
|
||||||
" default : fibonacci2(x - 1) + fibonacci2(x - 2);"
|
" default : fibonacci2(x - 1) + fibonacci2(x - 2);"
|
||||||
"} ",
|
"} ",
|
||||||
"x");
|
"x"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("fibonacci_impl3",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"fibonacci_impl3",
|
||||||
"switch "
|
"switch "
|
||||||
"{ "
|
"{ "
|
||||||
" case x == 0 : 0; "
|
" case x == 0 : 0; "
|
||||||
|
@ -6157,15 +6202,19 @@ inline bool run_test19()
|
||||||
" z "
|
" z "
|
||||||
" }; "
|
" }; "
|
||||||
"} ",
|
"} ",
|
||||||
"x","y","z","w");
|
"x","y","z","w"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("fibonacci3",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"fibonacci3",
|
||||||
"fibonacci_impl3(x,0,1,0)",
|
"fibonacci_impl3(x,0,1,0)",
|
||||||
"x");
|
"x"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("fibonacci_impl4",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"fibonacci_impl4",
|
||||||
"switch "
|
"switch "
|
||||||
"{ "
|
"{ "
|
||||||
" case x == 0 : 0; "
|
" case x == 0 : 0; "
|
||||||
|
@ -6179,20 +6228,24 @@ inline bool run_test19()
|
||||||
" z "
|
" z "
|
||||||
" until (x <= 1); "
|
" until (x <= 1); "
|
||||||
"} ",
|
"} ",
|
||||||
"x","y","z","w");
|
"x","y","z","w"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("fibonacci4",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"fibonacci4",
|
||||||
"fibonacci_impl4(x,0,1,0)",
|
"fibonacci_impl4(x,0,1,0)",
|
||||||
"x");
|
"x"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("fibonacci5",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"fibonacci5",
|
||||||
"if ((x == 0) or (x == 1)) "
|
"if ((x == 0) or (x == 1)) "
|
||||||
" x; "
|
" x; "
|
||||||
"else "
|
"else "
|
||||||
" fibonacci5(x - 1) + fibonacci5(x - 2); ",
|
" fibonacci5(x - 1) + fibonacci5(x - 2); ",
|
||||||
"x");
|
"x"));
|
||||||
|
|
||||||
symbol_table_t& symbol_table = compositor.symbol_table();
|
symbol_table_t& symbol_table = compositor.symbol_table();
|
||||||
symbol_table.add_constants();
|
symbol_table.add_constants();
|
||||||
|
@ -6309,7 +6362,9 @@ inline bool run_test19()
|
||||||
compositor_t compositor(symbol_table);
|
compositor_t compositor(symbol_table);
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("newton_sqrt_impl",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"newton_sqrt_impl",
|
||||||
"switch "
|
"switch "
|
||||||
"{ "
|
"{ "
|
||||||
" case x < 0 : -inf; "
|
" case x < 0 : -inf; "
|
||||||
|
@ -6326,11 +6381,13 @@ inline bool run_test19()
|
||||||
" until ((z -= 1) <= 0); "
|
" until ((z -= 1) <= 0); "
|
||||||
" }; "
|
" }; "
|
||||||
"} ",
|
"} ",
|
||||||
"x","y","z");
|
"x","y","z"));
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("newton_sqrt",
|
.add(
|
||||||
"newton_sqrt_impl(x,0,0)","x");
|
function_t(
|
||||||
|
"newton_sqrt",
|
||||||
|
"newton_sqrt_impl(x,0,0)","x"));
|
||||||
|
|
||||||
std::string expression_str = "newton_sqrt(x)";
|
std::string expression_str = "newton_sqrt(x)";
|
||||||
|
|
||||||
|
@ -6380,7 +6437,9 @@ inline bool run_test19()
|
||||||
compositor_t compositor(symbol_table);
|
compositor_t compositor(symbol_table);
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("mandelbrot",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"mandelbrot",
|
||||||
" var width := 118; "
|
" var width := 118; "
|
||||||
" var height := 41; "
|
" var height := 41; "
|
||||||
" var imag_max := +1; "
|
" var imag_max := +1; "
|
||||||
|
@ -6412,7 +6471,7 @@ inline bool run_test19()
|
||||||
" break; "
|
" break; "
|
||||||
" }; "
|
" }; "
|
||||||
" }; "
|
" }; "
|
||||||
" } ");
|
" } "));
|
||||||
|
|
||||||
std::string expression_str = "mandelbrot()";
|
std::string expression_str = "mandelbrot()";
|
||||||
|
|
||||||
|
@ -6447,13 +6506,15 @@ inline bool run_test19()
|
||||||
compositor_t compositor(symbol_table);
|
compositor_t compositor(symbol_table);
|
||||||
|
|
||||||
compositor
|
compositor
|
||||||
.add("fooboo",
|
.add(
|
||||||
|
function_t(
|
||||||
|
"fooboo",
|
||||||
" var x := input; "
|
" var x := input; "
|
||||||
" if (x > 0) "
|
" if (x > 0) "
|
||||||
" fooboo(x - 1) + x; "
|
" fooboo(x - 1) + x; "
|
||||||
" else "
|
" else "
|
||||||
" 0; ",
|
" 0; ",
|
||||||
"input");
|
"input"));
|
||||||
|
|
||||||
std::string expression_str = "fOoBoO(x)";
|
std::string expression_str = "fOoBoO(x)";
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue