diff --git a/server/src/exprtk.hpp b/server/src/exprtk.hpp index eebadb5..b4530ba 100644 --- a/server/src/exprtk.hpp +++ b/server/src/exprtk.hpp @@ -2,7 +2,7 @@ ****************************************************************** * C++ Mathematical Expression Toolkit Library * * * - * Author: Arash Partow (1999-2022) * + * Author: Arash Partow (1999-2023) * * URL: https://www.partow.net/programming/exprtk/index.html * * * * Copyright notice: * @@ -38,7 +38,6 @@ #include <cassert> #include <cctype> #include <cmath> -#include <complex> #include <cstdio> #include <cstdlib> #include <cstring> @@ -298,7 +297,6 @@ namespace exprtk std::reverse(result.begin(), result.end()); - return result; } @@ -401,7 +399,7 @@ namespace exprtk { public: - build_string(const std::size_t& initial_size = 64) + explicit build_string(const std::size_t& initial_size = 64) { data_.reserve(initial_size); } @@ -597,15 +595,13 @@ namespace exprtk } }; - template <typename Compare, - typename Iterator, - typename ValueType = typename std::iterator_traits<Iterator>::value_type> + template <typename Iterator, typename Compare> inline bool match_impl(const Iterator pattern_begin, const Iterator pattern_end , const Iterator data_begin , const Iterator data_end , - const ValueType zero_or_more, - const ValueType exactly_one ) + const typename std::iterator_traits<Iterator>::value_type& zero_or_more, + const typename std::iterator_traits<Iterator>::value_type& exactly_one ) { typedef typename std::iterator_traits<Iterator>::value_type type; @@ -665,7 +661,7 @@ namespace exprtk inline bool wc_match(const std::string& wild_card, const std::string& str) { - return match_impl<cs_match>( + return match_impl<char_cptr,cs_match>( wild_card.data(), wild_card.data() + wild_card.size(), str.data(), @@ -676,7 +672,7 @@ namespace exprtk inline bool wc_imatch(const std::string& wild_card, const std::string& str) { - return match_impl<cis_match>( + return match_impl<char_cptr,cis_match>( wild_card.data(), wild_card.data() + wild_card.size(), str.data(), @@ -784,7 +780,6 @@ namespace exprtk { struct unknown_type_tag { unknown_type_tag() {} }; struct real_type_tag { real_type_tag () {} }; - struct complex_type_tag { complex_type_tag() {} }; struct int_type_tag { int_type_tag () {} }; template <typename T> @@ -798,10 +793,6 @@ namespace exprtk template <> struct number_type<T> \ { typedef real_type_tag type; number_type() {} }; \ - #define exprtk_register_complex_type_tag(T) \ - template <> struct number_type<std::complex<T> > \ - { typedef complex_type_tag type; number_type() {} }; \ - #define exprtk_register_int_type_tag(T) \ template <> struct number_type<T> \ { typedef int_type_tag type; number_type() {} }; \ @@ -810,10 +801,6 @@ namespace exprtk exprtk_register_real_type_tag(long double) 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(int ) exprtk_register_int_type_tag(_int64_t ) @@ -2073,6 +2060,11 @@ namespace exprtk details::_uint64_t iteration_count; }; + virtual bool check() + { + return true; + } + virtual void handle_runtime_violation(const violation_context&) { throw std::runtime_error("ExprTk Loop run-time violation."); @@ -3328,7 +3320,7 @@ namespace exprtk ignore_set_.insert(symbol); } - inline int insert(const lexer::token& t0, const lexer::token& t1, lexer::token& new_token) + inline int insert(const lexer::token& t0, const lexer::token& t1, lexer::token& new_token) exprtk_override { bool match = false; new_token.type = lexer::token::e_mul; @@ -3383,7 +3375,7 @@ namespace exprtk : token_joiner(stride) {} - inline bool join(const lexer::token& t0, const lexer::token& t1, lexer::token& t) + inline bool join(const lexer::token& t0, const lexer::token& t1, lexer::token& t) exprtk_override { // ': =' --> ':=' if ((t0.type == lexer::token::e_colon) && (t1.type == lexer::token::e_eq)) @@ -3531,7 +3523,7 @@ namespace exprtk inline bool join(const lexer::token& t0, const lexer::token& t1, const lexer::token& t2, - lexer::token& t) + lexer::token& t) exprtk_override { // '[ * ]' --> '[*]' if ( @@ -3637,7 +3629,7 @@ namespace exprtk }; template <typename T> - class numeric_checker : public lexer::token_scanner + class numeric_checker exprtk_final : public lexer::token_scanner { public: @@ -3767,7 +3759,7 @@ namespace exprtk replace_map_t replace_map_; }; - class sequence_validator : public lexer::token_scanner + class sequence_validator exprtk_final : public lexer::token_scanner { private: @@ -3939,7 +3931,7 @@ namespace exprtk std::vector<std::pair<lexer::token,lexer::token> > error_list_; }; - class sequence_validator_3tokens : public lexer::token_scanner + class sequence_validator_3tokens exprtk_final : public lexer::token_scanner { private: @@ -4773,12 +4765,12 @@ namespace exprtk inline void dump_ptr(const std::string& s, const void* ptr, const std::size_t size = 0) { if (size) - exprtk_debug(("%s - addr: %p\n",s.c_str(),ptr)); - else exprtk_debug(("%s - addr: %p size: %d\n", s.c_str(), ptr, static_cast<unsigned int>(size))); + else + exprtk_debug(("%s - addr: %p\n",s.c_str(),ptr)); } #else inline void dump_ptr(const std::string&, const void*) {} @@ -4822,7 +4814,7 @@ namespace exprtk { if (data && destruct && (0 == ref_count)) { - dump_ptr("~control_block() data",data); + dump_ptr("~vec_data_store::control_block() data",data); delete[] data; data = reinterpret_cast<data_t>(0); } @@ -5235,12 +5227,6 @@ namespace exprtk 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> inline bool is_true(const expression_node<T>* node) { @@ -5957,16 +5943,16 @@ namespace exprtk : vector_holder_base_(new(buffer)array_vector_impl(vec,vec_size)) {} - vector_holder(const vds_t& vds) + explicit vector_holder(const vds_t& vds) : vector_holder_base_(new(buffer)array_vector_impl(vds.data(),vds.size())) {} template <typename Allocator> - vector_holder(std::vector<Type,Allocator>& vec) + explicit vector_holder(std::vector<Type,Allocator>& vec) : vector_holder_base_(new(buffer)sequence_vector_impl<Allocator,std::vector>(vec)) {} - vector_holder(exprtk::vector_view<Type>& vec) + explicit vector_holder(exprtk::vector_view<Type>& vec) : vector_holder_base_(new(buffer)vector_view_impl(vec)) {} @@ -6084,9 +6070,9 @@ namespace exprtk const bool result = details::numeric::is_nan(v); if (result) - return (equality_) ? T(1) : T(0); + return equality_ ? T(1) : T(0); else - return (equality_) ? T(0) : T(1); + return equality_ ? T(0) : T(1); } inline typename expression_node<T>::node_type type() const exprtk_override @@ -6270,9 +6256,7 @@ namespace exprtk inline T value() const exprtk_override { assert(branch_.first); - const T arg = branch_.first->value(); - return numeric::process<T>(operation_,arg); } @@ -6301,12 +6285,12 @@ namespace exprtk expression_node<T>::ndb_t::collect(branch_, node_delete_list); } - std::size_t node_depth() const exprtk_override exprtk_final + std::size_t node_depth() const exprtk_final { return expression_node<T>::ndb_t::compute_node_depth(branch_); } - protected: + private: operator_type operation_; branch_t branch_; @@ -6336,7 +6320,7 @@ namespace exprtk const T arg0 = branch_[0].first->value(); const T arg1 = branch_[1].first->value(); - return numeric::process<T>(operation_,arg0,arg1); + return numeric::process<T>(operation_, arg0, arg1); } inline typename expression_node<T>::node_type type() const exprtk_override @@ -6364,12 +6348,12 @@ namespace exprtk expression_node<T>::ndb_t::template collect(branch_, node_delete_list); } - std::size_t node_depth() const exprtk_override exprtk_final + std::size_t node_depth() const exprtk_final { return expression_node<T>::ndb_t::template compute_node_depth<2>(branch_); } - protected: + private: operator_type operation_; branch_t branch_[2]; @@ -6748,7 +6732,7 @@ namespace exprtk { if ( (0 == loop_runtime_check_) || - (++iteration_count_ <= max_loop_iterations_) + ((++iteration_count_ <= max_loop_iterations_) && loop_runtime_check_->check()) ) { return true; @@ -8184,6 +8168,8 @@ namespace exprtk typedef vector_node <T>* vector_node_ptr; typedef vec_data_store <T> vds_t; + using binary_node<T>::branch; + swap_vecvec_node(expression_ptr branch0, expression_ptr branch1) : binary_node<T>(details::e_swap, branch0, branch1) @@ -8192,22 +8178,22 @@ namespace exprtk , vec_size_ (0) , initialised_ (false) { - if (is_ivector_node(binary_node<T>::branch_[0].first)) + if (is_ivector_node(branch(0))) { vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); - if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first))) + if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0)))) { vec0_node_ptr_ = vi->vec(); vds() = vi->vds(); } } - if (is_ivector_node(binary_node<T>::branch_[1].first)) + if (is_ivector_node(branch(1))) { vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); - if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first))) + if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1)))) { vec1_node_ptr_ = vi->vec(); } @@ -8228,11 +8214,11 @@ namespace exprtk { if (initialised_) { - assert(binary_node<T>::branch_[0].first); - assert(binary_node<T>::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node<T>::branch_[0].first->value(); - binary_node<T>::branch_[1].first->value(); + binary_node<T>::branch(0)->value(); + binary_node<T>::branch(1)->value(); T* vec0 = vec0_node_ptr_->vds().data(); T* vec1 = vec1_node_ptr_->vds().data(); @@ -8693,6 +8679,8 @@ namespace exprtk typedef expression_node <T>* expression_ptr; typedef string_base_node<T>* str_base_ptr; + using binary_node<T>::branch; + string_concat_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -8709,27 +8697,27 @@ namespace exprtk range_.cache.first = range_.n0_c.second; range_.cache.second = range_.n1_c.second; - if (is_generally_string_node(binary_node<T>::branch_[0].first)) + if (is_generally_string_node(branch(0))) { - str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first); + str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0)); if (0 == str0_base_ptr_) return; - str0_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first); + str0_range_ptr_ = dynamic_cast<irange_ptr>(branch(0)); if (0 == str0_range_ptr_) return; } - if (is_generally_string_node(binary_node<T>::branch_[1].first)) + if (is_generally_string_node(branch(1))) { - str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first); + str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1)); if (0 == str1_base_ptr_) return; - str1_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first); + str1_range_ptr_ = dynamic_cast<irange_ptr>(branch(1)); if (0 == str1_range_ptr_) return; @@ -8747,11 +8735,11 @@ namespace exprtk { if (initialised_) { - assert(binary_node<T>::branch_[0].first); - assert(binary_node<T>::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node<T>::branch_[0].first->value(); - binary_node<T>::branch_[1].first->value(); + branch(0)->value(); + branch(1)->value(); std::size_t str0_r0 = 0; std::size_t str0_r1 = 0; @@ -8838,20 +8826,22 @@ namespace exprtk typedef stringvar_node <T>* strvar_node_ptr; typedef string_base_node<T>* str_base_ptr; + using binary_node<T>::branch; + swap_string_node(expression_ptr branch0, expression_ptr branch1) : binary_node<T>(details::e_swap, branch0, branch1), initialised_(false), str0_node_ptr_(0), str1_node_ptr_(0) { - if (is_string_node(binary_node<T>::branch_[0].first)) + if (is_string_node(branch(0))) { - str0_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[0].first); + str0_node_ptr_ = static_cast<strvar_node_ptr>(branch(0)); } - if (is_string_node(binary_node<T>::branch_[1].first)) + if (is_string_node(branch(1))) { - str1_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[1].first); + str1_node_ptr_ = static_cast<strvar_node_ptr>(branch(1)); } initialised_ = (str0_node_ptr_ && str1_node_ptr_); @@ -8863,11 +8853,11 @@ namespace exprtk { if (initialised_) { - assert(binary_node<T>::branch_[0].first); - assert(binary_node<T>::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node<T>::branch_[0].first->value(); - binary_node<T>::branch_[1].first->value(); + branch(0)->value(); + branch(1)->value(); std::swap(str0_node_ptr_->ref(), str1_node_ptr_->ref()); } @@ -8924,6 +8914,8 @@ namespace exprtk typedef expression_node <T>* expression_ptr; typedef string_base_node<T>* str_base_ptr; + using binary_node<T>::branch; + swap_genstrings_node(expression_ptr branch0, expression_ptr branch1) : binary_node<T>(details::e_default, branch0, branch1) @@ -8933,14 +8925,14 @@ namespace exprtk , str1_range_ptr_(0) , initialised_(false) { - if (is_generally_string_node(binary_node<T>::branch_[0].first)) + if (is_generally_string_node(branch(0))) { - str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first); + str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0)); if (0 == str0_base_ptr_) return; - irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first); + irange_ptr range = dynamic_cast<irange_ptr>(branch(0)); if (0 == range) return; @@ -8948,14 +8940,14 @@ namespace exprtk str0_range_ptr_ = &(range->range_ref()); } - if (is_generally_string_node(binary_node<T>::branch_[1].first)) + if (is_generally_string_node(branch(1))) { - str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first); + str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1)); if (0 == str1_base_ptr_) return; - irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first); + irange_ptr range = dynamic_cast<irange_ptr>(branch(1)); if (0 == range) return; @@ -8975,11 +8967,11 @@ namespace exprtk { if (initialised_) { - assert(binary_node<T>::branch_[0].first); - assert(binary_node<T>::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node<T>::branch_[0].first->value(); - binary_node<T>::branch_[1].first->value(); + branch(0)->value(); + branch(1)->value(); std::size_t str0_r0 = 0; std::size_t str0_r1 = 0; @@ -9189,6 +9181,8 @@ namespace exprtk typedef stringvar_node <T>* strvar_node_ptr; typedef string_base_node<T>* str_base_ptr; + using binary_node<T>::branch; + assignment_string_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -9199,21 +9193,20 @@ namespace exprtk , str0_node_ptr_ (0) , str1_range_ptr_(0) { - if (is_string_node(binary_node<T>::branch_[0].first)) + if (is_string_node(branch(0))) { - str0_node_ptr_ = static_cast<strvar_node_ptr>(binary_node<T>::branch_[0].first); - - str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first); + str0_node_ptr_ = static_cast<strvar_node_ptr>(branch(0)); + str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0)); } - if (is_generally_string_node(binary_node<T>::branch_[1].first)) + if (is_generally_string_node(branch(1))) { - str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first); + str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1)); if (0 == str1_base_ptr_) return; - irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first); + irange_ptr range = dynamic_cast<irange_ptr>(branch(1)); if (0 == range) return; @@ -9233,10 +9226,10 @@ namespace exprtk { if (initialised_) { - assert(binary_node<T>::branch_[0].first); - assert(binary_node<T>::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node<T>::branch_[1].first->value(); + branch(1)->value(); std::size_t r0 = 0; std::size_t r1 = 0; @@ -9249,7 +9242,7 @@ namespace exprtk str1_base_ptr_->base() + r0, (r1 - r0) + 1); - binary_node<T>::branch_[0].first->value(); + branch(0)->value(); } } @@ -9312,6 +9305,8 @@ namespace exprtk typedef string_range_node<T>* str_rng_node_ptr; typedef string_base_node <T>* str_base_ptr; + using binary_node<T>::branch; + assignment_string_range_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -9323,13 +9318,11 @@ namespace exprtk , str0_range_ptr_ (0) , str1_range_ptr_ (0) { - if (is_string_range_node(binary_node<T>::branch_[0].first)) + if (is_string_range_node(branch(0))) { - str0_rng_node_ptr_ = static_cast<str_rng_node_ptr>(binary_node<T>::branch_[0].first); - - str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first); - - irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first); + str0_rng_node_ptr_ = static_cast<str_rng_node_ptr>(branch(0)); + str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0)); + irange_ptr range = dynamic_cast<irange_ptr>(branch(0)); if (0 == range) return; @@ -9337,14 +9330,14 @@ namespace exprtk str0_range_ptr_ = &(range->range_ref()); } - if (is_generally_string_node(binary_node<T>::branch_[1].first)) + if (is_generally_string_node(branch(1))) { - str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first); + str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1)); if (0 == str1_base_ptr_) return; - irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first); + irange_ptr range = dynamic_cast<irange_ptr>(branch(1)); if (0 == range) return; @@ -9365,11 +9358,11 @@ namespace exprtk { if (initialised_) { - assert(binary_node<T>::branch_[0].first); - assert(binary_node<T>::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node<T>::branch_[0].first->value(); - binary_node<T>::branch_[1].first->value(); + branch(0)->value(); + branch(1)->value(); std::size_t s0_r0 = 0; std::size_t s0_r1 = 0; @@ -9616,6 +9609,8 @@ namespace exprtk typedef expression_node <T>* expression_ptr; typedef string_base_node<T>* str_base_ptr; + using binary_node<T>::branch; + cons_conditional_str_node(expression_ptr condition, expression_ptr consequent) : binary_node<T>(details::e_default, consequent, condition) @@ -9631,14 +9626,14 @@ namespace exprtk range_.cache.first = range_.n0_c.second; range_.cache.second = range_.n1_c.second; - if (is_generally_string_node(binary_node<T>::branch_[0].first)) + if (is_generally_string_node(branch(0))) { - str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first); + str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0)); if (0 == str0_base_ptr_) return; - str0_range_ptr_ = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first); + str0_range_ptr_ = dynamic_cast<irange_ptr>(branch(0)); if (0 == str0_range_ptr_) return; @@ -10364,6 +10359,7 @@ namespace exprtk public: typedef expression_node<T>* expression_ptr; + using binary_node<T>::branch; assignment_node(const operator_type& opr, expression_ptr branch0, @@ -10371,9 +10367,9 @@ namespace exprtk : binary_node<T>(opr, branch0, branch1) , var_node_ptr_(0) { - if (is_variable_node(binary_node<T>::branch_[0].first)) + if (is_variable_node(branch(0))) { - var_node_ptr_ = static_cast<variable_node<T>*>(binary_node<T>::branch_[0].first); + var_node_ptr_ = static_cast<variable_node<T>*>(branch(0)); } } @@ -10381,11 +10377,10 @@ namespace exprtk { if (var_node_ptr_) { - assert(binary_node<T>::branch_[1].first); + assert(branch(1)); T& result = var_node_ptr_->ref(); - - result = binary_node<T>::branch_[1].first->value(); + result = branch(1)->value(); return result; } @@ -10404,6 +10399,7 @@ namespace exprtk public: typedef expression_node<T>* expression_ptr; + using binary_node<T>::branch; assignment_vec_elem_node(const operator_type& opr, expression_ptr branch0, @@ -10411,9 +10407,9 @@ namespace exprtk : binary_node<T>(opr, branch0, branch1) , vec_node_ptr_(0) { - if (is_vector_elem_node(binary_node<T>::branch_[0].first)) + if (is_vector_elem_node(branch(0))) { - vec_node_ptr_ = static_cast<vector_elem_node<T>*>(binary_node<T>::branch_[0].first); + vec_node_ptr_ = static_cast<vector_elem_node<T>*>(branch(0)); } } @@ -10421,11 +10417,10 @@ namespace exprtk { if (vec_node_ptr_) { - assert(binary_node<T>::branch_[1].first); + assert(branch(1)); T& result = vec_node_ptr_->ref(); - - result = binary_node<T>::branch_[1].first->value(); + result = branch(1)->value(); return result; } @@ -10444,6 +10439,7 @@ namespace exprtk public: typedef expression_node<T>* expression_ptr; + using expression_node<T>::branch; assignment_rebasevec_elem_node(const operator_type& opr, expression_ptr branch0, @@ -10451,9 +10447,9 @@ namespace exprtk : binary_node<T>(opr, branch0, branch1) , rbvec_node_ptr_(0) { - if (is_rebasevector_elem_node(binary_node<T>::branch_[0].first)) + if (is_rebasevector_elem_node(branch(0))) { - rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(binary_node<T>::branch_[0].first); + rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(branch(0)); } } @@ -10461,11 +10457,11 @@ namespace exprtk { if (rbvec_node_ptr_) { - assert(binary_node<T>::branch_[1].first); + assert(branch(1)); T& result = rbvec_node_ptr_->ref(); - result = binary_node<T>::branch_[1].first->value(); + result = branch(1)->value(); return result; } @@ -10484,6 +10480,7 @@ namespace exprtk public: typedef expression_node<T>* expression_ptr; + using binary_node<T>::branch; assignment_rebasevec_celem_node(const operator_type& opr, expression_ptr branch0, @@ -10491,9 +10488,9 @@ namespace exprtk : binary_node<T>(opr, branch0, branch1) , rbvec_node_ptr_(0) { - if (is_rebasevector_celem_node(binary_node<T>::branch_[0].first)) + if (is_rebasevector_celem_node(branch(0))) { - rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(binary_node<T>::branch_[0].first); + rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(branch(0)); } } @@ -10501,11 +10498,10 @@ namespace exprtk { if (rbvec_node_ptr_) { - assert(binary_node<T>::branch_[1].first); + assert(branch(1)); T& result = rbvec_node_ptr_->ref(); - - result = binary_node<T>::branch_[1].first->value(); + result = branch(1)->value(); return result; } @@ -10529,15 +10525,17 @@ namespace exprtk typedef vector_node<T>* vector_node_ptr; typedef vec_data_store<T> vds_t; + using binary_node<T>::branch; + assignment_vec_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) : binary_node<T>(opr, branch0, branch1) , vec_node_ptr_(0) { - if (is_vector_node(binary_node<T>::branch_[0].first)) + if (is_vector_node(branch(0))) { - vec_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first); + vec_node_ptr_ = static_cast<vector_node<T>*>(branch(0)); vds() = vec_node_ptr_->vds(); } } @@ -10546,9 +10544,9 @@ namespace exprtk { if (vec_node_ptr_) { - assert(binary_node<T>::branch_[1].first); + assert(branch(1)); - const T v = binary_node<T>::branch_[1].first->value(); + const T v = branch(1)->value(); T* vec = vds().data(); @@ -10649,6 +10647,8 @@ namespace exprtk typedef vector_node<T>* vector_node_ptr; typedef vec_data_store<T> vds_t; + using binary_node<T>::branch; + assignment_vecvec_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -10658,22 +10658,22 @@ namespace exprtk , initialised_(false) , src_is_ivec_(false) { - if (is_vector_node(binary_node<T>::branch_[0].first)) + if (is_vector_node(branch(0))) { - vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first); + vec0_node_ptr_ = static_cast<vector_node<T>*>(branch(0)); vds() = vec0_node_ptr_->vds(); } - if (is_vector_node(binary_node<T>::branch_[1].first)) + if (is_vector_node(branch(1))) { - vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first); + vec1_node_ptr_ = static_cast<vector_node<T>*>(branch(1)); vds_t::match_sizes(vds(),vec1_node_ptr_->vds()); } - else if (is_ivector_node(binary_node<T>::branch_[1].first)) + else if (is_ivector_node(branch(1))) { vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); - if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first))) + if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1)))) { vec1_node_ptr_ = vi->vec(); @@ -10696,9 +10696,9 @@ namespace exprtk { if (initialised_) { - assert(binary_node<T>::branch_[1].first); + assert(branch(1)); - binary_node<T>::branch_[1].first->value(); + branch(1)->value(); if (src_is_ivec_) return vec0_node_ptr_->value(); @@ -10802,6 +10802,7 @@ namespace exprtk public: typedef expression_node<T>* expression_ptr; + using binary_node<T>::branch; assignment_op_node(const operator_type& opr, expression_ptr branch0, @@ -10809,9 +10810,9 @@ namespace exprtk : binary_node<T>(opr, branch0, branch1) , var_node_ptr_(0) { - if (is_variable_node(binary_node<T>::branch_[0].first)) + if (is_variable_node(branch(0))) { - var_node_ptr_ = static_cast<variable_node<T>*>(binary_node<T>::branch_[0].first); + var_node_ptr_ = static_cast<variable_node<T>*>(branch(0)); } } @@ -10819,10 +10820,10 @@ namespace exprtk { if (var_node_ptr_) { - assert(binary_node<T>::branch_[1].first); + assert(branch(1)); T& v = var_node_ptr_->ref(); - v = Operation::process(v,binary_node<T>::branch_[1].first->value()); + v = Operation::process(v,branch(1)->value()); return v; } @@ -10841,6 +10842,7 @@ namespace exprtk public: typedef expression_node<T>* expression_ptr; + using binary_node<T>::branch; assignment_vec_elem_op_node(const operator_type& opr, expression_ptr branch0, @@ -10848,9 +10850,9 @@ namespace exprtk : binary_node<T>(opr, branch0, branch1) , vec_node_ptr_(0) { - if (is_vector_elem_node(binary_node<T>::branch_[0].first)) + if (is_vector_elem_node(branch(0))) { - vec_node_ptr_ = static_cast<vector_elem_node<T>*>(binary_node<T>::branch_[0].first); + vec_node_ptr_ = static_cast<vector_elem_node<T>*>(branch(0)); } } @@ -10858,10 +10860,10 @@ namespace exprtk { if (vec_node_ptr_) { - assert(binary_node<T>::branch_[1].first); + assert(branch(1)); T& v = vec_node_ptr_->ref(); - v = Operation::process(v,binary_node<T>::branch_[1].first->value()); + v = Operation::process(v,branch(1)->value()); return v; } @@ -10880,6 +10882,7 @@ namespace exprtk public: typedef expression_node<T>* expression_ptr; + using binary_node<T>::branch; assignment_rebasevec_elem_op_node(const operator_type& opr, expression_ptr branch0, @@ -10887,9 +10890,9 @@ namespace exprtk : binary_node<T>(opr, branch0, branch1) , rbvec_node_ptr_(0) { - if (is_rebasevector_elem_node(binary_node<T>::branch_[0].first)) + if (is_rebasevector_elem_node(branch(0))) { - rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(binary_node<T>::branch_[0].first); + rbvec_node_ptr_ = static_cast<rebasevector_elem_node<T>*>(branch(0)); } } @@ -10897,10 +10900,10 @@ namespace exprtk { if (rbvec_node_ptr_) { - assert(binary_node<T>::branch_[1].first); + assert(branch(1)); T& v = rbvec_node_ptr_->ref(); - v = Operation::process(v,binary_node<T>::branch_[1].first->value()); + v = Operation::process(v,branch(1)->value()); return v; } @@ -10919,6 +10922,7 @@ namespace exprtk public: typedef expression_node<T>* expression_ptr; + using binary_node<T>::branch; assignment_rebasevec_celem_op_node(const operator_type& opr, expression_ptr branch0, @@ -10926,9 +10930,9 @@ namespace exprtk : binary_node<T>(opr, branch0, branch1) , rbvec_node_ptr_(0) { - if (is_rebasevector_celem_node(binary_node<T>::branch_[0].first)) + if (is_rebasevector_celem_node(branch(0))) { - rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(binary_node<T>::branch_[0].first); + rbvec_node_ptr_ = static_cast<rebasevector_celem_node<T>*>(branch(0)); } } @@ -10936,10 +10940,10 @@ namespace exprtk { if (rbvec_node_ptr_) { - assert(binary_node<T>::branch_[1].first); + assert(branch(1)); T& v = rbvec_node_ptr_->ref(); - v = Operation::process(v,binary_node<T>::branch_[1].first->value()); + v = Operation::process(v,branch(1)->value()); return v; } @@ -10963,15 +10967,17 @@ namespace exprtk typedef vector_node<T>* vector_node_ptr; typedef vec_data_store<T> vds_t; + using binary_node<T>::branch; + assignment_vec_op_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) : binary_node<T>(opr, branch0, branch1) , vec_node_ptr_(0) { - if (is_vector_node(binary_node<T>::branch_[0].first)) + if (is_vector_node(branch(0))) { - vec_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first); + vec_node_ptr_ = static_cast<vector_node<T>*>(branch(0)); vds() = vec_node_ptr_->vds(); } } @@ -10980,9 +10986,9 @@ namespace exprtk { if (vec_node_ptr_) { - assert(binary_node<T>::branch_[1].first); + assert(branch(1)); - const T v = binary_node<T>::branch_[1].first->value(); + const T v = branch(1)->value(); T* vec = vds().data(); @@ -11088,6 +11094,8 @@ namespace exprtk typedef vector_node<T>* vector_node_ptr; typedef vec_data_store<T> vds_t; + using binary_node<T>::branch; + assignment_vecvec_op_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -11096,22 +11104,22 @@ namespace exprtk , vec1_node_ptr_(0) , initialised_(false) { - if (is_vector_node(binary_node<T>::branch_[0].first)) + if (is_vector_node(branch(0))) { - vec0_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[0].first); + vec0_node_ptr_ = static_cast<vector_node<T>*>(branch(0)); vds() = vec0_node_ptr_->vds(); } - if (is_vector_node(binary_node<T>::branch_[1].first)) + if (is_vector_node(branch(1))) { - vec1_node_ptr_ = static_cast<vector_node<T>*>(binary_node<T>::branch_[1].first); + vec1_node_ptr_ = static_cast<vector_node<T>*>(branch(1)); vec1_node_ptr_->vds() = vds(); } - else if (is_ivector_node(binary_node<T>::branch_[1].first)) + else if (is_ivector_node(branch(1))) { vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); - if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first))) + if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1)))) { vec1_node_ptr_ = vi->vec(); vec1_node_ptr_->vds() = vds(); @@ -11129,11 +11137,11 @@ namespace exprtk { if (initialised_) { - assert(binary_node<T>::branch_[0].first); - assert(binary_node<T>::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node<T>::branch_[0].first->value(); - binary_node<T>::branch_[1].first->value(); + branch(0)->value(); + branch(1)->value(); T* vec0 = vec0_node_ptr_->vds().data(); const T* vec1 = vec1_node_ptr_->vds().data(); @@ -11246,6 +11254,8 @@ namespace exprtk typedef vector_holder<T>* vector_holder_ptr; typedef vec_data_store<T> vds_t; + using binary_node<T>::branch; + vec_binop_vecvec_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -11259,30 +11269,30 @@ namespace exprtk bool v0_is_ivec = false; bool v1_is_ivec = false; - if (is_vector_node(binary_node<T>::branch_[0].first)) + if (is_vector_node(branch(0))) { - vec0_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[0].first); + vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0)); } - else if (is_ivector_node(binary_node<T>::branch_[0].first)) + else if (is_ivector_node(branch(0))) { vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); - if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first))) + if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0)))) { vec0_node_ptr_ = vi->vec(); v0_is_ivec = true; } } - if (is_vector_node(binary_node<T>::branch_[1].first)) + if (is_vector_node(branch(1))) { - vec1_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[1].first); + vec1_node_ptr_ = static_cast<vector_node_ptr>(branch(1)); } - else if (is_ivector_node(binary_node<T>::branch_[1].first)) + else if (is_ivector_node(branch(1))) { vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); - if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first))) + if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1)))) { vec1_node_ptr_ = vi->vec(); v1_is_ivec = true; @@ -11320,11 +11330,11 @@ namespace exprtk { if (initialised_) { - assert(binary_node<T>::branch_[0].first); - assert(binary_node<T>::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node<T>::branch_[0].first->value(); - binary_node<T>::branch_[1].first->value(); + branch(0)->value(); + branch(1)->value(); const T* vec0 = vec0_node_ptr_->vds().data(); const T* vec1 = vec1_node_ptr_->vds().data(); @@ -11436,6 +11446,8 @@ namespace exprtk typedef vector_holder<T>* vector_holder_ptr; typedef vec_data_store<T> vds_t; + using binary_node<T>::branch; + vec_binop_vecval_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -11446,15 +11458,15 @@ namespace exprtk { bool v0_is_ivec = false; - if (is_vector_node(binary_node<T>::branch_[0].first)) + if (is_vector_node(branch(0))) { - vec0_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[0].first); + vec0_node_ptr_ = static_cast<vector_node_ptr>(branch(0)); } - else if (is_ivector_node(binary_node<T>::branch_[0].first)) + else if (is_ivector_node(branch(0))) { vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); - if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first))) + if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(0)))) { vec0_node_ptr_ = vi->vec(); v0_is_ivec = true; @@ -11483,11 +11495,11 @@ namespace exprtk { if (vec0_node_ptr_) { - assert(binary_node<T>::branch_[0].first); - assert(binary_node<T>::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - binary_node<T>::branch_[0].first->value(); - const T v = binary_node<T>::branch_[1].first->value(); + branch(0)->value(); + const T v = branch(1)->value(); const T* vec0 = vec0_node_ptr_->vds().data(); T* vec1 = vds().data(); @@ -11595,6 +11607,8 @@ namespace exprtk typedef vector_holder<T>* vector_holder_ptr; typedef vec_data_store<T> vds_t; + using binary_node<T>::branch; + vec_binop_valvec_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -11605,15 +11619,15 @@ namespace exprtk { bool v1_is_ivec = false; - if (is_vector_node(binary_node<T>::branch_[1].first)) + if (is_vector_node(branch(1))) { - vec1_node_ptr_ = static_cast<vector_node_ptr>(binary_node<T>::branch_[1].first); + vec1_node_ptr_ = static_cast<vector_node_ptr>(branch(1)); } - else if (is_ivector_node(binary_node<T>::branch_[1].first)) + else if (is_ivector_node(branch(1))) { vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); - if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first))) + if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch(1)))) { vec1_node_ptr_ = vi->vec(); v1_is_ivec = true; @@ -11642,11 +11656,11 @@ namespace exprtk { if (vec1_node_ptr_) { - assert(binary_node<T>::branch_[0].first); - assert(binary_node<T>::branch_[1].first); + assert(branch(0)); + assert(branch(1)); - const T v = binary_node<T>::branch_[0].first->value(); - binary_node<T>::branch_[1].first->value(); + const T v = branch(0)->value(); + branch(1)->value(); T* vec0 = vds().data(); const T* vec1 = vec1_node_ptr_->vds().data(); @@ -11754,6 +11768,8 @@ namespace exprtk typedef vector_holder<T>* vector_holder_ptr; typedef vec_data_store<T> vds_t; + using expression_node<T>::branch; + unary_vector_node(const operator_type& opr, expression_ptr branch0) : unary_node<T>(opr, branch0) , vec0_node_ptr_(0) @@ -11762,15 +11778,15 @@ namespace exprtk { bool vec0_is_ivec = false; - if (is_vector_node(unary_node<T>::branch_.first)) + if (is_vector_node(branch())) { - vec0_node_ptr_ = static_cast<vector_node_ptr>(unary_node<T>::branch_.first); + vec0_node_ptr_ = static_cast<vector_node_ptr>(branch()); } - else if (is_ivector_node(unary_node<T>::branch_.first)) + else if (is_ivector_node(branch())) { vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0); - if (0 != (vi = dynamic_cast<vector_interface<T>*>(unary_node<T>::branch_.first))) + if (0 != (vi = dynamic_cast<vector_interface<T>*>(branch()))) { vec0_node_ptr_ = vi->vec(); vec0_is_ivec = true; @@ -11797,9 +11813,9 @@ namespace exprtk inline T value() const exprtk_override { - assert(unary_node<T>::branch_.first); + assert(branch()); - unary_node<T>::branch_.first->value(); + branch()->value(); if (vec0_node_ptr_) { @@ -12063,6 +12079,7 @@ namespace exprtk public: typedef expression_node<T>* expression_ptr; + using binary_node<T>::branch; scand_node(const operator_type& opr, expression_ptr branch0, @@ -12072,14 +12089,14 @@ namespace exprtk inline T value() const exprtk_override { - assert(binary_node<T>::branch_[0].first); - assert(binary_node<T>::branch_[1].first); + assert(branch(0)); + assert(branch(1)); return ( std::not_equal_to<T>() - (T(0),binary_node<T>::branch_[0].first->value()) && + (T(0),branch(0)->value()) && std::not_equal_to<T>() - (T(0),binary_node<T>::branch_[1].first->value()) + (T(0),branch(1)->value()) ) ? T(1) : T(0); } }; @@ -12090,6 +12107,7 @@ namespace exprtk public: typedef expression_node<T>* expression_ptr; + using binary_node<T>::branch; scor_node(const operator_type& opr, expression_ptr branch0, @@ -12099,14 +12117,14 @@ namespace exprtk inline T value() const exprtk_override { - assert(binary_node<T>::branch_[0].first); - assert(binary_node<T>::branch_[1].first); + assert(branch(0)); + assert(branch(1)); return ( std::not_equal_to<T>() - (T(0),binary_node<T>::branch_[0].first->value()) || + (T(0),branch(0)->value()) || std::not_equal_to<T>() - (T(0),binary_node<T>::branch_[1].first->value()) + (T(0),branch(1)->value()) ) ? T(1) : T(0); } }; @@ -13533,7 +13551,7 @@ namespace exprtk case 3 : return process_3(arg_list); case 4 : return process_4(arg_list); case 5 : return process_5(arg_list); - default : return vararg_add_op<T>::process(arg_list) / arg_list.size(); + default : return vararg_add_op<T>::process(arg_list) / T(arg_list.size()); } } @@ -14192,8 +14210,7 @@ namespace exprtk static inline T process(const ivector_ptr v) { - const std::size_t vec_size = v->vec()->vds().size(); - + const T vec_size = T(v->vec()->vds().size()); return vec_add_op<T>::process(v) / vec_size; } }; @@ -16122,6 +16139,8 @@ namespace exprtk typedef range_interface <T> irange_t; typedef irange_t* irange_ptr; + using binary_node<T>::branch; + str_sogens_node(const operator_type& opr, expression_ptr branch0, expression_ptr branch1) @@ -16131,14 +16150,14 @@ namespace exprtk , str0_range_ptr_(0) , str1_range_ptr_(0) { - if (is_generally_string_node(binary_node<T>::branch_[0].first)) + if (is_generally_string_node(branch(0))) { - str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first); + str0_base_ptr_ = dynamic_cast<str_base_ptr>(branch(0)); if (0 == str0_base_ptr_) return; - irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first); + irange_ptr range = dynamic_cast<irange_ptr>(branch(0)); if (0 == range) return; @@ -16146,14 +16165,14 @@ namespace exprtk str0_range_ptr_ = &(range->range_ref()); } - if (is_generally_string_node(binary_node<T>::branch_[1].first)) + if (is_generally_string_node(branch(1))) { - str1_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[1].first); + str1_base_ptr_ = dynamic_cast<str_base_ptr>(branch(1)); if (0 == str1_base_ptr_) return; - irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first); + irange_ptr range = dynamic_cast<irange_ptr>(branch(1)); if (0 == range) return; @@ -16171,8 +16190,8 @@ namespace exprtk str1_range_ptr_ ) { - binary_node<T>::branch_[0].first->value(); - binary_node<T>::branch_[1].first->value(); + branch(0)->value(); + branch(1)->value(); std::size_t str0_r0 = 0; std::size_t str0_r1 = 0; @@ -17292,22 +17311,29 @@ namespace exprtk { public: - typedef T (*ff00_functor)(); - typedef T (*ff01_functor)(T); - typedef T (*ff02_functor)(T, T); - typedef T (*ff03_functor)(T, T, T); - typedef T (*ff04_functor)(T, T, T, T); - typedef T (*ff05_functor)(T, T, T, T, T); - typedef T (*ff06_functor)(T, T, T, T, T, T); - typedef T (*ff07_functor)(T, T, T, T, T, T, T); - typedef T (*ff08_functor)(T, T, T, T, T, T, T, T); - typedef T (*ff09_functor)(T, T, T, T, T, T, T, T, T); - typedef T (*ff10_functor)(T, T, T, T, T, T, T, T, T, T); - typedef T (*ff11_functor)(T, T, T, T, T, T, T, T, T, T, T); - typedef T (*ff12_functor)(T, T, T, T, T, T, T, T, T, T, T, T); - typedef T (*ff13_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T); - typedef T (*ff14_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T); - typedef T (*ff15_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T); + enum symtab_mutability_type + { + e_unknown = 0, + e_mutable = 1, + e_immutable = 2 + }; + + typedef T (*ff00_functor)(); + typedef T (*ff01_functor)(T); + typedef T (*ff02_functor)(T, T); + typedef T (*ff03_functor)(T, T, T); + typedef T (*ff04_functor)(T, T, T, T); + typedef T (*ff05_functor)(T, T, T, T, T); + typedef T (*ff06_functor)(T, T, T, T, T, T); + typedef T (*ff07_functor)(T, T, T, T, T, T, T); + typedef T (*ff08_functor)(T, T, T, T, T, T, T, T); + typedef T (*ff09_functor)(T, T, T, T, T, T, T, T, T); + typedef T (*ff10_functor)(T, T, T, T, T, T, T, T, T, T); + typedef T (*ff11_functor)(T, T, T, T, T, T, T, T, T, T, T); + typedef T (*ff12_functor)(T, T, T, T, T, T, T, T, T, T, T, T); + typedef T (*ff13_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T); + typedef T (*ff14_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T); + typedef T (*ff15_functor)(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T); protected: @@ -17949,11 +17975,13 @@ namespace exprtk control_block() : ref_count(1) , data_(st_data::create()) + , mutability_(e_mutable) {} explicit control_block(st_data* data) : ref_count(1) , data_(data) + , mutability_(e_mutable) {} ~control_block() @@ -17989,21 +18017,29 @@ namespace exprtk } } + void set_mutability(const symtab_mutability_type mutability) + { + mutability_ = mutability; + } + std::size_t ref_count; st_data* data_; + symtab_mutability_type mutability_; }; public: - symbol_table() + symbol_table(const symtab_mutability_type mutability = e_mutable) : control_block_(control_block::create()) { + control_block_->set_mutability(mutability); clear(); } ~symbol_table() { - control_block::destroy(control_block_,this); + exprtk::details::dump_ptr("~symbol_table", this); + control_block::destroy(control_block_, this); } symbol_table(const symbol_table<T>& st) @@ -18030,6 +18066,11 @@ namespace exprtk return (this == &st) || (control_block_ == st.control_block_); } + inline symtab_mutability_type mutability() const + { + return valid() ? control_block_->mutability_ : e_unknown; + } + inline void clear_variables(const bool delete_node = true) { local_data().variable_store.clear(delete_node); @@ -19103,6 +19144,7 @@ namespace exprtk inline expression<T>& release() { + exprtk::details::dump_ptr("expression::release", this); control_block::destroy(control_block_); return (*this); @@ -19138,6 +19180,14 @@ namespace exprtk inline void register_symbol_table(symbol_table<T>& st) { + for (std::size_t i = 0; i < symbol_table_list_.size(); ++i) + { + if (&st == &symbol_table_list_[i]) + { + return; + } + } + symbol_table_list_.push_back(st); } @@ -19905,6 +19955,130 @@ namespace exprtk parser_t& parser_; }; + template <typename T_> + struct halfopen_range_policy + { + static inline bool is_within(const T_& v, const T_& begin, const T_& end) + { + assert(begin <= end); + return (begin <= v) && (v < end); + } + + static inline bool is_less(const T_& v, const T_& begin) + { + return (v < begin); + } + + static inline bool is_greater(const T_& v, const T_& end) + { + return (end <= v); + } + + static inline bool end_inclusive() + { + return false; + } + }; + + template <typename T_> + struct closed_range_policy + { + static inline bool is_within(const T_& v, const T_& begin, const T_& end) + { + assert(begin <= end); + return (begin <= v) && (v <= end); + } + + static inline bool is_less(const T_& v, const T_& begin) + { + return (v < begin); + } + + static inline bool is_greater(const T_& v, const T_& end) + { + return (end < v); + } + + static inline bool end_inclusive() + { + return true; + } + }; + + template <typename IntervalPointType, + typename RangePolicy = halfopen_range_policy<IntervalPointType> > + class interval_container_t + { + public: + + typedef IntervalPointType interval_point_t; + typedef std::pair<interval_point_t, interval_point_t> interval_t; + typedef std::map<interval_point_t, interval_t> interval_map_t; + typedef typename interval_map_t::const_iterator interval_map_citr_t; + + std::size_t size() const + { + return interval_map_.size(); + } + + void reset() + { + interval_map_.clear(); + } + + bool in_interval(const interval_point_t point, interval_t& interval) const + { + interval_map_citr_t itr = RangePolicy::end_inclusive() ? + interval_map_.lower_bound(point): + interval_map_.upper_bound(point); + + for (; itr != interval_map_.end(); ++itr) + { + const interval_point_t& begin = itr->second.first; + const interval_point_t& end = itr->second.second; + + if (RangePolicy::is_within(point, begin, end)) + { + interval = interval_t(begin,end); + return true; + } + else if (RangePolicy::is_greater(point, end)) + { + break; + } + } + + return false; + } + + bool in_interval(const interval_point_t point) const + { + interval_t interval; + return in_interval(point,interval); + } + + bool add_interval(const interval_point_t begin, const interval_point_t end) + { + if ((end <= begin) || in_interval(begin) || in_interval(end)) + { + return false; + } + + interval_map_[end] = std::make_pair(begin, end); + + return true; + } + + bool add_interval(const interval_t interval) + { + return add_interval(interval.first, interval.second); + } + + private: + + interval_map_t interval_map_; + }; + class stack_limit_handler { public: @@ -19959,6 +20133,41 @@ namespace exprtk typedef typename symbol_table_t::vararg_function_ptr vararg_function_ptr; typedef typename symbol_table_t::generic_function_ptr generic_function_ptr; + struct variable_context + { + variable_context() + : symbol_table(0) + , variable(0) + {} + + const symbol_table_t* symbol_table; + variable_ptr variable; + }; + + struct vector_context + { + vector_context() + : symbol_table(0) + , vector_holder(0) + {} + + const symbol_table_t* symbol_table; + vector_holder_ptr vector_holder; + }; + + #ifndef exprtk_disable_string_capabilities + struct string_context + { + string_context() + : symbol_table(0) + , str_var(0) + {} + + const symbol_table_t* symbol_table; + stringvar_ptr str_var; + }; + #endif + inline bool empty() const { return symtab_list_.empty(); @@ -19999,6 +20208,31 @@ namespace exprtk return false; } + inline variable_context get_variable_context(const std::string& variable_name) const + { + variable_context result; + if (!valid_symbol(variable_name)) + return result; + + for (std::size_t i = 0; i < symtab_list_.size(); ++i) + { + if (!symtab_list_[i].valid()) + { + continue; + } + + result.variable = local_data(i) + .variable_store.get(variable_name); + if (result.variable) + { + result.symbol_table = &symtab_list_[i]; + break; + } + } + + return result; + } + inline variable_ptr get_variable(const std::string& variable_name) const { if (!valid_symbol(variable_name)) @@ -20039,6 +20273,32 @@ namespace exprtk } #ifndef exprtk_disable_string_capabilities + inline string_context get_string_context(const std::string& string_name) const + { + string_context result; + + if (!valid_symbol(string_name)) + return result; + + for (std::size_t i = 0; i < symtab_list_.size(); ++i) + { + if (!symtab_list_[i].valid()) + { + continue; + } + + result.str_var = local_data(i).stringvar_store.get(string_name); + + if (result.str_var) + { + result.symbol_table = &symtab_list_[i]; + break; + } + } + + return result; + } + inline stringvar_ptr get_stringvar(const std::string& string_name) const { if (!valid_symbol(string_name)) @@ -20166,6 +20426,31 @@ namespace exprtk return result; } + inline vector_context get_vector_context(const std::string& vector_name) const + { + vector_context result; + if (!valid_symbol(vector_name)) + return result; + + for (std::size_t i = 0; i < symtab_list_.size(); ++i) + { + if (!symtab_list_[i].valid()) + { + continue; + } + + result.vector_holder = local_data(i).vector_store.get(vector_name); + + if (result.vector_holder) + { + result.symbol_table = &symtab_list_[i]; + break; + } + } + + return result; + } + inline vector_holder_ptr get_vector(const std::string& vector_name) const { if (!valid_symbol(vector_name)) @@ -23215,6 +23500,12 @@ namespace exprtk return parse_base_operation(); } + void handle_brkcnt_scope_exit() + { + assert(!brkcnt_list_.empty()); + brkcnt_list_.pop_front(); + } + inline expression_node_ptr parse_while_loop() { // Parse: [while][(][test expr][)][{][expression][}] @@ -23263,7 +23554,7 @@ namespace exprtk { scoped_inc_dec sid(state_.parsing_loop_stmt_count); - if (0 == (branch = parse_multi_sequence("while-loop"))) + if (0 == (branch = parse_multi_sequence("while-loop", true))) { set_error( make_error(parser_error::e_syntax, @@ -23285,18 +23576,18 @@ namespace exprtk } } + handle_brkcnt_scope_exit(); + if (!result) { free_node(node_allocator_, branch ); free_node(node_allocator_, condition ); free_node(node_allocator_, result_node); - brkcnt_list_.pop_front(); - return error_node(); } - else - return result_node; + + return result_node; } inline expression_node_ptr parse_repeat_until_loop() @@ -23375,8 +23666,6 @@ namespace exprtk if (sdd.delete_ptr) { - brkcnt_list_.pop_front(); - set_error( make_error(parser_error::e_syntax, current_token(), @@ -23389,8 +23678,6 @@ namespace exprtk if (!token_is(token_t::e_lbracket)) { - brkcnt_list_.pop_front(); - set_error( make_error(parser_error::e_syntax, current_token(), @@ -23398,13 +23685,10 @@ namespace exprtk exprtk_error_location)); free_node(node_allocator_,branch); - return error_node(); } else if (0 == (condition = parse_expression())) { - brkcnt_list_.pop_front(); - set_error( make_error(parser_error::e_syntax, current_token(), @@ -23412,7 +23696,6 @@ namespace exprtk exprtk_error_location)); free_node(node_allocator_,branch); - return error_node(); } else if (!token_is(token_t::e_rbracket)) @@ -23426,8 +23709,6 @@ namespace exprtk free_node(node_allocator_, branch ); free_node(node_allocator_, condition); - brkcnt_list_.pop_front(); - return error_node(); } @@ -23446,15 +23727,12 @@ namespace exprtk free_node(node_allocator_,condition); - brkcnt_list_.pop_front(); - return error_node(); } - else - { - brkcnt_list_.pop_front(); - return result; - } + + handle_brkcnt_scope_exit(); + + return result; } inline expression_node_ptr parse_for_loop() @@ -23646,7 +23924,7 @@ namespace exprtk scoped_inc_dec sid(state_.parsing_loop_stmt_count); - if (0 == (loop_body = parse_multi_sequence("for-loop"))) + if (0 == (loop_body = parse_multi_sequence("for-loop", true))) { set_error( make_error(parser_error::e_syntax, @@ -23669,26 +23947,18 @@ namespace exprtk free_node(node_allocator_, condition ); free_node(node_allocator_, incrementor); free_node(node_allocator_, loop_body ); - - if (!brkcnt_list_.empty()) - { - brkcnt_list_.pop_front(); - } - return error_node(); } - else - { - expression_node_ptr result_node = - expression_generator_.for_loop(initialiser, - condition, - incrementor, - loop_body, - brkcnt_list_.front()); - brkcnt_list_.pop_front(); - return result_node; - } + expression_node_ptr result_node = + expression_generator_.for_loop(initialiser, + condition, + incrementor, + loop_body, + brkcnt_list_.front()); + handle_brkcnt_scope_exit(); + + return result_node; } inline expression_node_ptr parse_switch_statement() @@ -23998,7 +24268,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR096 - Unsupported vararg function: " + symbol, + "ERR096 - Unsupported built-in vararg function: " + symbol, exprtk_error_location)); return error_node(); @@ -24021,6 +24291,18 @@ namespace exprtk return error_node(); } + if (token_is(token_t::e_rbracket)) + { + set_error( + make_error(parser_error::e_syntax, + current_token(), + "ERR098 - vararg function: " + symbol + + " requires at least one input parameter", + exprtk_error_location)); + + return error_node(); + } + for ( ; ; ) { expression_node_ptr arg = parse_expression(); @@ -24037,7 +24319,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR098 - Expected ',' for call to vararg function: " + symbol, + "ERR099 - Expected ',' for call to vararg function: " + symbol, exprtk_error_location)); return error_node(); @@ -24058,7 +24340,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR099 - Expected '[' as start of string range definition", + "ERR100 - Expected '[' as start of string range definition", exprtk_error_location)); free_node(node_allocator_,expression); @@ -24086,7 +24368,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR100 - Failed to generate string range node", + "ERR101 - Failed to generate string range node", exprtk_error_location)); free_node(node_allocator_,expression); @@ -24206,15 +24488,18 @@ namespace exprtk return expression_generator_.vararg_function(details::e_multi,expression_list); } - inline expression_node_ptr parse_multi_sequence(const std::string& source = "") + inline expression_node_ptr parse_multi_sequence(const std::string& source = "", + const bool enforce_crlbrackets = false) { + token_t::token_type open_bracket = token_t::e_lcrlbracket; token_t::token_type close_bracket = token_t::e_rcrlbracket; token_t::token_type seperator = token_t::e_eof; - if (!token_is(token_t::e_lcrlbracket)) + if (!token_is(open_bracket)) { - if (token_is(token_t::e_lbracket)) + if (!enforce_crlbrackets && token_is(token_t::e_lbracket)) { + open_bracket = token_t::e_lbracket; close_bracket = token_t::e_rbracket; seperator = token_t::e_comma; } @@ -24223,14 +24508,14 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR101 - Expected '" + token_t::to_str(close_bracket) + "' for call to multi-sequence" + + "ERR102 - Expected '" + token_t::to_str(open_bracket) + "' for call to multi-sequence" + ((!source.empty()) ? std::string(" section of " + source): ""), exprtk_error_location)); return error_node(); } } - else if (token_is(token_t::e_rcrlbracket)) + else if (token_is(close_bracket)) { return node_allocator_.allocate<details::null_node<T> >(); } @@ -24270,7 +24555,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR102 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source, + "ERR103 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source, exprtk_error_location)); return error_node(); @@ -24280,7 +24565,7 @@ namespace exprtk break; } - result = simplify(arg_list,side_effect_list,source.empty()); + result = simplify(arg_list, side_effect_list, source.empty()); sdd.delete_ptr = (0 == result); return result; @@ -24304,7 +24589,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR103 - Expected '[' for start of range", + "ERR104 - Expected '[' for start of range", exprtk_error_location)); return false; @@ -24325,7 +24610,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR104 - Failed parse begin section of range", + "ERR105 - Failed parse begin section of range", exprtk_error_location)); return false; @@ -24348,7 +24633,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR105 - Range lower bound less than zero! Constraint: r0 >= 0", + "ERR106 - Range lower bound less than zero! Constraint: r0 >= 0", exprtk_error_location)); return false; @@ -24365,7 +24650,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR106 - Expected ':' for break in range", + "ERR107 - Expected ':' for break in range", exprtk_error_location)); rp.free(); @@ -24388,7 +24673,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR107 - Failed parse end section of range", + "ERR108 - Failed parse end section of range", exprtk_error_location)); rp.free(); @@ -24413,7 +24698,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR108 - Range upper bound less than zero! Constraint: r1 >= 0", + "ERR109 - Range upper bound less than zero! Constraint: r1 >= 0", exprtk_error_location)); rp.free(); @@ -24432,7 +24717,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR109 - Expected ']' for start of range", + "ERR110 - Expected ']' for start of range", exprtk_error_location)); rp.free(); @@ -24460,7 +24745,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR110 - Invalid range, Constraint: r0 <= r1", + "ERR111 - Invalid range, Constraint: r0 <= r1", exprtk_error_location)); return false; @@ -24496,24 +24781,36 @@ namespace exprtk } else { - if (!symtab_store_.is_conststr_stringvar(symbol)) + typedef typename symtab_store::string_context str_ctxt_t; + str_ctxt_t str_ctx = symtab_store_.get_string_context(symbol); + + if ((0 == str_ctx.str_var) || !symtab_store_.is_conststr_stringvar(symbol)) { set_error( make_error(parser_error::e_syntax, current_token(), - "ERR111 - Unknown string symbol", + "ERR112 - Unknown string symbol", exprtk_error_location)); return error_node(); } - result = symtab_store_.get_stringvar(symbol); + assert(str_ctx.str_var != 0); + assert(str_ctx.symbol_table != 0); + + result = str_ctx.str_var; if (symtab_store_.is_constant_string(symbol)) { const_str_node = static_cast<strvar_node_t>(result); result = expression_generator_(const_str_node->str()); } + else if (symbol_table_t::e_immutable == str_ctx.symbol_table->mutability()) + { + lodge_immutable_symbol( + current_token(), + make_memory_range(str_ctx.str_var->base(), str_ctx.str_var->size())); + } lodge_symbol(symbol, e_st_string); } @@ -24616,7 +24913,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR112 - Overflow in range for string: '" + const_str + "'[" + + "ERR113 - Overflow in range for string: '" + const_str + "'[" + (rp.n0_c.first ? details::to_str(static_cast<int>(rp.n0_c.second)) : "?") + ":" + (rp.n1_c.first ? details::to_str(static_cast<int>(rp.n1_c.second)) : "?") + "]", exprtk_error_location)); @@ -24657,20 +24954,37 @@ namespace exprtk (scope_element::e_vector != se.type) ) { - if (0 == (vec = symtab_store_.get_vector(symbol))) + typedef typename symtab_store::vector_context vec_ctxt_t; + vec_ctxt_t vec_ctx = symtab_store_.get_vector_context(symbol); + + if (0 == vec_ctx.vector_holder) { set_error( make_error(parser_error::e_syntax, current_token(), - "ERR113 - Symbol '" + symbol+ " not a vector", + "ERR114 - Symbol '" + symbol+ " not a vector", exprtk_error_location)); return error_node(); } + + assert(0 != vec_ctx.vector_holder); + assert(0 != vec_ctx.symbol_table ); + + vec = vec_ctx.vector_holder; + + if (symbol_table_t::e_immutable == vec_ctx.symbol_table->mutability()) + { + lodge_immutable_symbol( + current_token(), + make_memory_range(vec->data(), vec->size())); + } } else vec = se.vec_node; + assert(0 != vec); + expression_node_ptr index_expr = error_node(); next_token(); @@ -24688,7 +25002,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR114 - Failed to parse index for vector: '" + symbol + "'", + "ERR115 - Failed to parse index for vector: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -24698,7 +25012,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR115 - Expected ']' for index of vector: '" + symbol + "'", + "ERR116 - Expected ']' for index of vector: '" + symbol + "'", exprtk_error_location)); free_node(node_allocator_,index_expr); @@ -24717,7 +25031,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR116 - Index of " + details::to_str(index) + " out of range for " + "ERR117 - Index of " + details::to_str(index) + " out of range for " "vector '" + symbol + "' of size " + details::to_str(vec_size), exprtk_error_location)); @@ -24749,7 +25063,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR117 - Zero parameter call to vararg function: " + "ERR118 - Zero parameter call to vararg function: " + vararg_function_name + " not allowed", exprtk_error_location)); @@ -24774,7 +25088,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR118 - Expected ',' for call to vararg function: " + "ERR119 - Expected ',' for call to vararg function: " + vararg_function_name, exprtk_error_location)); @@ -24788,7 +25102,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR119 - Zero parameter call to vararg function: " + "ERR120 - Zero parameter call to vararg function: " + vararg_function_name + " not allowed", exprtk_error_location)); @@ -24800,7 +25114,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR120 - Invalid number of parameters to call to vararg function: " + "ERR121 - Invalid number of parameters to call to vararg function: " + vararg_function_name + ", require at least " + details::to_str(static_cast<int>(vararg_function->min_num_args())) + " parameters", exprtk_error_location)); @@ -24812,7 +25126,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR121 - Invalid number of parameters to call to vararg function: " + "ERR122 - Invalid number of parameters to call to vararg function: " + vararg_function_name + ", require no more than " + details::to_str(static_cast<int>(vararg_function->max_num_args())) + " parameters", exprtk_error_location)); @@ -24890,7 +25204,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, parser_.current_token(), - "ERR122 - Failed parameter type check for function '" + function_name_ + "', " + "ERR123 - Failed parameter type check for function '" + function_name_ + "', " "Expected '" + function_definition_list_[0].param_seq + "' call set: '" + param_seq + "'", exprtk_error_location)); @@ -24912,7 +25226,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, parser_.current_token(), - "ERR123 - Failed parameter type check for function '" + function_name_ + "', " + "ERR124 - Failed parameter type check for function '" + function_name_ + "', " "Best match: '" + function_definition_list_[max_diff_index].param_seq + "' call set: '" + param_seq + "'", exprtk_error_location)); @@ -25054,7 +25368,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, parser_.current_token(), - "ERR124 - Invalid parameter sequence of '" + param_seq_list[i] + + "ERR125 - Invalid parameter sequence of '" + param_seq_list[i] + "' for function: " + function_name_, exprtk_error_location)); return; @@ -25070,7 +25384,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, parser_.current_token(), - "ERR125 - Function '" + function_name_ + "' has a parameter sequence conflict between " + + "ERR126 - Function '" + function_name_ + "' has a parameter sequence conflict between " + "pseq_idx[" + details::to_str(seq_itr->second) + "] and" + "pseq_idx[" + details::to_str(i) + "] " + "param seq: " + param_seq_list[i], @@ -25102,14 +25416,18 @@ namespace exprtk std::string param_type_list; - type_checker tc((*this), function_name, function->parameter_sequence, type_checker::e_string); + type_checker tc( + (*this), + function_name, + function->parameter_sequence, + type_checker::e_string); if (tc.invalid()) { set_error( make_error(parser_error::e_syntax, current_token(), - "ERR126 - Type checker instantiation failure for generic function: " + function_name, + "ERR127 - Type checker instantiation failure for generic function: " + function_name, exprtk_error_location)); return error_node(); @@ -25127,7 +25445,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR127 - Zero parameter call to generic function: " + "ERR128 - Zero parameter call to generic function: " + function_name + " not allowed", exprtk_error_location)); @@ -25159,7 +25477,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR128 - Expected ',' for call to generic function: " + function_name, + "ERR129 - Expected ',' for call to generic function: " + function_name, exprtk_error_location)); return error_node(); @@ -25176,7 +25494,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR129 - Zero parameter call to generic function: " + "ERR130 - Zero parameter call to generic function: " + function_name + " not allowed", exprtk_error_location)); @@ -25193,7 +25511,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR130 - Invalid input parameter sequence for call to generic function: " + function_name, + "ERR131 - Invalid input parameter sequence for call to generic function: " + function_name, exprtk_error_location)); return error_node(); @@ -25231,7 +25549,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR131 - Zero parameter call to generic function: " + "ERR132 - Zero parameter call to generic function: " + function_name + " not allowed", exprtk_error_location)); @@ -25263,7 +25581,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR132 - Expected ',' for call to string function: " + function_name, + "ERR133 - Expected ',' for call to string function: " + function_name, exprtk_error_location)); return false; @@ -25310,7 +25628,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR133 - Invalid input parameter sequence for call to string function: " + function_name, + "ERR134 - Invalid input parameter sequence for call to string function: " + function_name, exprtk_error_location)); return error_node(); @@ -25362,7 +25680,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR134 - Invalid input parameter sequence for call to overloaded function: " + function_name, + "ERR135 - Invalid input parameter sequence for call to overloaded function: " + function_name, exprtk_error_location)); return error_node(); @@ -25393,7 +25711,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR135 - Invalid return type for call to overloaded function: " + function_name, + "ERR136 - Invalid return type for call to overloaded function: " + function_name, exprtk_error_location)); } @@ -25421,7 +25739,7 @@ namespace exprtk p.set_error( make_error(parser_error::e_syntax, p.current_token(), - "ERR136 - Expected '(' for special function '" + sf_name + "'", + "ERR137 - Expected '(' for special function '" + sf_name + "'", exprtk_error_location)); return error_node(); @@ -25442,7 +25760,7 @@ namespace exprtk p.set_error( make_error(parser_error::e_syntax, p.current_token(), - "ERR137 - Expected ',' before next parameter of special function '" + sf_name + "'", + "ERR138 - Expected ',' before next parameter of special function '" + sf_name + "'", exprtk_error_location)); return p.error_node(); @@ -25455,7 +25773,7 @@ namespace exprtk p.set_error( make_error(parser_error::e_syntax, p.current_token(), - "ERR138 - Invalid number of parameters for special function '" + sf_name + "'", + "ERR139 - Invalid number of parameters for special function '" + sf_name + "'", exprtk_error_location)); return p.error_node(); @@ -25482,7 +25800,7 @@ namespace exprtk set_error( make_error(parser_error::e_token, current_token(), - "ERR139 - Invalid special function[1]: " + sf_name, + "ERR140 - Invalid special function[1]: " + sf_name, exprtk_error_location)); return error_node(); @@ -25496,7 +25814,7 @@ namespace exprtk set_error( make_error(parser_error::e_token, current_token(), - "ERR140 - Invalid special function[2]: " + sf_name, + "ERR141 - Invalid special function[2]: " + sf_name, exprtk_error_location)); return error_node(); @@ -25528,7 +25846,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR141 - Invoking 'break' within a break call is not allowed", + "ERR142 - Invoking 'break' within a break call is not allowed", exprtk_error_location)); return error_node(); @@ -25538,7 +25856,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR142 - Invalid use of 'break', allowed only in the scope of a loop", + "ERR143 - Invalid use of 'break', allowed only in the scope of a loop", exprtk_error_location)); return error_node(); @@ -25561,7 +25879,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR143 - Failed to parse return expression for 'break' statement", + "ERR144 - Failed to parse return expression for 'break' statement", exprtk_error_location)); return error_node(); @@ -25571,7 +25889,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR144 - Expected ']' at the completion of break's return expression", + "ERR145 - Expected ']' at the completion of break's return expression", exprtk_error_location)); free_node(node_allocator_,return_expr); @@ -25589,7 +25907,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR145 - Invalid use of 'break', allowed only in the scope of a loop", + "ERR146 - Invalid use of 'break', allowed only in the scope of a loop", exprtk_error_location)); } @@ -25603,7 +25921,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR146 - Invalid use of 'continue', allowed only in the scope of a loop", + "ERR147 - Invalid use of 'continue', allowed only in the scope of a loop", exprtk_error_location)); return error_node(); @@ -25629,7 +25947,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR147 - Expected '[' as part of vector size definition", + "ERR148 - Expected '[' as part of vector size definition", exprtk_error_location)); return error_node(); @@ -25639,7 +25957,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR148 - Failed to determine size of vector '" + vec_name + "'", + "ERR149 - Failed to determine size of vector '" + vec_name + "'", exprtk_error_location)); return error_node(); @@ -25651,7 +25969,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR149 - Expected a literal number as size of vector '" + vec_name + "'", + "ERR150 - Expected a literal number as size of vector '" + vec_name + "'", exprtk_error_location)); return error_node(); @@ -25673,7 +25991,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR150 - Invalid vector size. Must be an integer in the range [0,2e9], size: " + + "ERR151 - Invalid vector size. Must be an integer in the range [0,2e9], size: " + details::to_str(details::numeric::to_int32(vector_size)), exprtk_error_location)); @@ -25693,7 +26011,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR151 - Expected ']' as part of vector size definition", + "ERR152 - Expected ']' as part of vector size definition", exprtk_error_location)); return error_node(); @@ -25705,7 +26023,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR152 - Expected ':=' as part of vector definition", + "ERR153 - Expected ':=' as part of vector definition", exprtk_error_location)); return error_node(); @@ -25719,7 +26037,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR153 - Failed to parse single vector initialiser", + "ERR154 - Failed to parse single vector initialiser", exprtk_error_location)); return error_node(); @@ -25732,7 +26050,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR154 - Expected ']' to close single value vector initialiser", + "ERR155 - Expected ']' to close single value vector initialiser", exprtk_error_location)); return error_node(); @@ -25779,7 +26097,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR155 - Expected '{' as part of vector initialiser list", + "ERR156 - Expected '{' as part of vector initialiser list", exprtk_error_location)); return error_node(); @@ -25799,7 +26117,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR156 - Expected '{' as part of vector initialiser list", + "ERR157 - Expected '{' as part of vector initialiser list", exprtk_error_location)); return error_node(); @@ -25817,7 +26135,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR157 - Expected ',' between vector initialisers", + "ERR158 - Expected ',' between vector initialisers", exprtk_error_location)); return error_node(); @@ -25839,19 +26157,19 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR158 - Expected ';' at end of vector definition", + "ERR159 - Expected ';' at end of vector definition", exprtk_error_location)); return error_node(); } } - if (vec_initilizer_list.size() > vector_size) + if (T(vec_initilizer_list.size()) > vector_size) { set_error( make_error(parser_error::e_syntax, current_token(), - "ERR159 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'", + "ERR160 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'", exprtk_error_location)); return error_node(); @@ -25871,7 +26189,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR160 - Illegal redefinition of local vector: '" + vec_name + "'", + "ERR161 - Illegal redefinition of local vector: '" + vec_name + "'", exprtk_error_location)); return error_node(); @@ -25905,7 +26223,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR161 - Failed to add new local vector '" + vec_name + "' to SEM", + "ERR162 - Failed to add new local vector '" + vec_name + "' to SEM", exprtk_error_location)); sem_.free_element(nse); @@ -25964,7 +26282,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR162 - Illegal redefinition of local variable: '" + str_name + "'", + "ERR163 - Illegal redefinition of local variable: '" + str_name + "'", exprtk_error_location)); free_node(node_allocator_,initialisation_expression); @@ -25996,7 +26314,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR163 - Failed to add new local string variable '" + str_name + "' to SEM", + "ERR164 - Failed to add new local string variable '" + str_name + "' to SEM", exprtk_error_location)); free_node(node_allocator_,initialisation_expression); @@ -26042,7 +26360,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR164 - Illegal variable definition", + "ERR165 - Illegal variable definition", exprtk_error_location)); return error_node(); @@ -26063,7 +26381,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR165 - Expected a symbol for variable definition", + "ERR166 - Expected a symbol for variable definition", exprtk_error_location)); return error_node(); @@ -26073,7 +26391,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR166 - Illegal redefinition of reserved keyword: '" + var_name + "'", + "ERR167 - Illegal redefinition of reserved keyword: '" + var_name + "'", exprtk_error_location)); return error_node(); @@ -26083,7 +26401,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR167 - Illegal redefinition of variable '" + var_name + "'", + "ERR168 - Illegal redefinition of variable '" + var_name + "'", exprtk_error_location)); return error_node(); @@ -26093,7 +26411,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR168 - Illegal redefinition of local variable: '" + var_name + "'", + "ERR169 - Illegal redefinition of local variable: '" + var_name + "'", exprtk_error_location)); return error_node(); @@ -26113,7 +26431,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR169 - Failed to parse initialisation expression", + "ERR170 - Failed to parse initialisation expression", exprtk_error_location)); return error_node(); @@ -26131,7 +26449,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR170 - Expected ';' after variable definition", + "ERR171 - Expected ';' after variable definition", exprtk_error_location)); free_node(node_allocator_,initialisation_expression); @@ -26159,7 +26477,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR171 - Illegal redefinition of local variable: '" + var_name + "'", + "ERR172 - Illegal redefinition of local variable: '" + var_name + "'", exprtk_error_location)); free_node(node_allocator_, initialisation_expression); @@ -26191,7 +26509,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR172 - Failed to add new local variable '" + var_name + "' to SEM", + "ERR173 - Failed to add new local variable '" + var_name + "' to SEM", exprtk_error_location)); free_node(node_allocator_, initialisation_expression); @@ -26228,7 +26546,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR173 - Expected a '{}' for uninitialised var definition", + "ERR174 - Expected a '{}' for uninitialised var definition", exprtk_error_location)); return error_node(); @@ -26238,7 +26556,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR174 - Expected ';' after uninitialised variable definition", + "ERR175 - Expected ';' after uninitialised variable definition", exprtk_error_location)); return error_node(); @@ -26255,7 +26573,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR175 - Illegal redefinition of local variable: '" + var_name + "'", + "ERR176 - Illegal redefinition of local variable: '" + var_name + "'", exprtk_error_location)); return error_node(); @@ -26285,7 +26603,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR176 - Failed to add new local variable '" + var_name + "' to SEM", + "ERR177 - Failed to add new local variable '" + var_name + "' to SEM", exprtk_error_location)); sem_.free_element(nse); @@ -26318,7 +26636,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR177 - Expected '(' at start of swap statement", + "ERR178 - Expected '(' at start of swap statement", exprtk_error_location)); return error_node(); @@ -26337,7 +26655,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR178 - Expected a symbol for variable or vector element definition", + "ERR179 - Expected a symbol for variable or vector element definition", exprtk_error_location)); return error_node(); @@ -26349,7 +26667,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR179 - First parameter to swap is an invalid vector element: '" + var0_name + "'", + "ERR180 - First parameter to swap is an invalid vector element: '" + var0_name + "'", exprtk_error_location)); return error_node(); @@ -26382,7 +26700,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR180 - First parameter to swap is an invalid variable: '" + var0_name + "'", + "ERR181 - First parameter to swap is an invalid variable: '" + var0_name + "'", exprtk_error_location)); return error_node(); @@ -26396,7 +26714,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR181 - Expected ',' between parameters to swap", + "ERR182 - Expected ',' between parameters to swap", exprtk_error_location)); if (variable0_generated) @@ -26414,7 +26732,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR182 - Expected a symbol for variable or vector element definition", + "ERR183 - Expected a symbol for variable or vector element definition", exprtk_error_location)); if (variable0_generated) @@ -26431,7 +26749,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR183 - Second parameter to swap is an invalid vector element: '" + var1_name + "'", + "ERR184 - Second parameter to swap is an invalid vector element: '" + var1_name + "'", exprtk_error_location)); if (variable0_generated) @@ -26469,7 +26787,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR184 - Second parameter to swap is an invalid variable: '" + var1_name + "'", + "ERR185 - Second parameter to swap is an invalid variable: '" + var1_name + "'", exprtk_error_location)); if (variable0_generated) @@ -26488,7 +26806,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR185 - Expected ')' at end of swap statement", + "ERR186 - Expected ')' at end of swap statement", exprtk_error_location)); if (variable0_generated) @@ -26545,7 +26863,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR186 - Return call within a return call is not allowed", + "ERR187 - Return call within a return call is not allowed", exprtk_error_location)); return error_node(); @@ -26569,7 +26887,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR187 - Expected '[' at start of return statement", + "ERR188 - Expected '[' at start of return statement", exprtk_error_location)); return error_node(); @@ -26592,7 +26910,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR188 - Expected ',' between values during call to return", + "ERR189 - Expected ',' between values during call to return", exprtk_error_location)); return error_node(); @@ -26604,7 +26922,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR189 - Zero parameter return statement not allowed", + "ERR190 - Zero parameter return statement not allowed", exprtk_error_location)); return error_node(); @@ -26619,7 +26937,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, prev_token, - "ERR190 - Invalid ']' found during return call", + "ERR191 - Invalid ']' found during return call", exprtk_error_location)); return error_node(); @@ -26672,7 +26990,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR191 - Invalid sequence of variable '"+ symbol + "' and bracket", + "ERR192 - Invalid sequence of variable '" + symbol + "' and bracket", exprtk_error_location)); return false; @@ -26720,7 +27038,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR192 - Invalid sequence of brackets", + "ERR193 - Invalid sequence of brackets", exprtk_error_location)); return false; @@ -26736,27 +27054,65 @@ namespace exprtk return true; } + typedef typename interval_container_t<const void*>::interval_t interval_t; + typedef interval_container_t<const void*> immutable_memory_map_t; + typedef std::map<interval_t,token_t> immutable_symtok_map_t; + + inline interval_t make_memory_range(const T& t) + { + const T* begin = reinterpret_cast<const T*>(&t); + const T* end = begin + 1; + return interval_t(begin, end); + } + + inline interval_t make_memory_range(const T* begin, const std::size_t size) + { + return interval_t(begin, begin + size); + } + + inline interval_t make_memory_range(details::char_cptr begin, const std::size_t size) + { + return interval_t(begin, begin + size); + } + + void lodge_immutable_symbol(const lexer::token& token, const interval_t interval) + { + immutable_memory_map_.add_interval(interval); + immutable_symtok_map_[interval] = token; + } + inline expression_node_ptr parse_symtab_symbol() { const std::string symbol = current_token().value; // Are we dealing with a variable or a special constant? - expression_node_ptr variable = symtab_store_.get_variable(symbol); + typedef typename symtab_store::variable_context var_ctxt_t; + var_ctxt_t var_ctx = symtab_store_.get_variable_context(symbol); - if (variable) + if (var_ctx.variable) { + assert(var_ctx.symbol_table); + + expression_node_ptr result_variable = var_ctx.variable; + if (symtab_store_.is_constant_node(symbol)) { - variable = expression_generator_(variable->value()); + result_variable = expression_generator_(var_ctx.variable->value()); + } + else if (symbol_table_t::e_immutable == var_ctx.symbol_table->mutability()) + { + lodge_immutable_symbol(current_token(), make_memory_range(var_ctx.variable->ref())); + result_variable = var_ctx.variable; } if (!post_variable_process(symbol)) return error_node(); lodge_symbol(symbol, e_st_variable); + next_token(); - return variable; + return result_variable; } // Are we dealing with a locally defined variable, vector or string? @@ -26817,7 +27173,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR193 - Failed to generate node for function: '" + symbol + "'", + "ERR194 - Failed to generate node for function: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -26843,7 +27199,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR194 - Failed to generate node for vararg function: '" + symbol + "'", + "ERR195 - Failed to generate node for vararg function: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -26869,7 +27225,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR195 - Failed to generate node for generic function: '" + symbol + "'", + "ERR196 - Failed to generate node for generic function: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -26896,7 +27252,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR196 - Failed to generate node for string function: '" + symbol + "'", + "ERR197 - Failed to generate node for string function: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -26922,7 +27278,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR197 - Failed to generate node for overload function: '" + symbol + "'", + "ERR198 - Failed to generate node for overload function: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -26948,7 +27304,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR198 - Invalid use of reserved symbol '" + symbol + "'", + "ERR199 - Invalid use of reserved symbol '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -27011,7 +27367,7 @@ namespace exprtk set_error( make_error(parser_error::e_symtab, current_token(), - "ERR199 - Failed to create variable: '" + symbol + "'" + + "ERR200 - Failed to create variable: '" + symbol + "'" + (error_message.empty() ? "" : " - " + error_message), exprtk_error_location)); @@ -27031,7 +27387,7 @@ namespace exprtk set_error( make_error(parser_error::e_symtab, current_token(), - "ERR200 - Failed to resolve symbol: '" + symbol + "'" + + "ERR201 - Failed to resolve symbol: '" + symbol + "'" + (error_message.empty() ? "" : " - " + error_message), exprtk_error_location)); } @@ -27043,7 +27399,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR201 - Undefined symbol: '" + symbol + "'", + "ERR202 - Undefined symbol: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -27157,7 +27513,7 @@ namespace exprtk set_error( make_error(parser_error::e_symtab, current_token(), - "ERR202 - Variable or function detected, yet symbol-table is invalid, Symbol: " + symbol, + "ERR203 - Variable or function detected, yet symbol-table is invalid, Symbol: " + symbol, exprtk_error_location)); return error_node(); @@ -27188,7 +27544,7 @@ namespace exprtk set_error( make_error(parser_error::e_numeric, current_token(), - "ERR203 - Failed generate node for scalar: '" + current_token().value + "'", + "ERR204 - Failed generate node for scalar: '" + current_token().value + "'", exprtk_error_location)); return error_node(); @@ -27202,7 +27558,7 @@ namespace exprtk set_error( make_error(parser_error::e_numeric, current_token(), - "ERR204 - Failed to convert '" + current_token().value + "' to a number", + "ERR205 - Failed to convert '" + current_token().value + "' to a number", exprtk_error_location)); return error_node(); @@ -27229,7 +27585,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR205 - Expected ')' instead of: '" + current_token().value + "'", + "ERR206 - Expected ')' instead of: '" + current_token().value + "'", exprtk_error_location)); details::free_node(node_allocator_,branch); @@ -27254,7 +27610,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR206 - Expected ']' instead of: '" + current_token().value + "'", + "ERR207 - Expected ']' instead of: '" + current_token().value + "'", exprtk_error_location)); details::free_node(node_allocator_,branch); @@ -27279,7 +27635,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR207 - Expected '}' instead of: '" + current_token().value + "'", + "ERR208 - Expected '}' instead of: '" + current_token().value + "'", exprtk_error_location)); details::free_node(node_allocator_,branch); @@ -27328,7 +27684,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR208 - Premature end of expression[1]", + "ERR209 - Premature end of expression[1]", exprtk_error_location)); return error_node(); @@ -27338,7 +27694,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR209 - Premature end of expression[2]", + "ERR210 - Premature end of expression[2]", exprtk_error_location)); return error_node(); @@ -29627,43 +29983,105 @@ namespace exprtk } } + const void* base_ptr(expression_node_ptr node) + { + if (node) + { + switch(node->type()) + { + case details::expression_node<T>::e_variable: + return reinterpret_cast<const void*>(&static_cast<variable_node_t*>(node)->ref()); + + case details::expression_node<T>::e_vecelem: + return reinterpret_cast<const void*>(&static_cast<vector_elem_node_t*>(node)->ref()); + + case details::expression_node<T>::e_rbvecelem: + return reinterpret_cast<const void*>(&static_cast<rebasevector_elem_node_t*>(node)->ref()); + + case details::expression_node<T>::e_rbveccelem: + return reinterpret_cast<const void*>(&static_cast<rebasevector_celem_node_t*>(node)->ref()); + + case details::expression_node<T>::e_vector: + return reinterpret_cast<const void*>(static_cast<vector_node_t*>(node)->vec_holder().data()); + + #ifndef exprtk_disable_string_capabilities + case details::expression_node<T>::e_stringvar: + return reinterpret_cast<const void*>((static_cast<stringvar_node_t*>(node)->base())); + + case details::expression_node<T>::e_stringvarrng: + return reinterpret_cast<const void*>((static_cast<string_range_node_t*>(node)->base())); + #endif + default : return reinterpret_cast<const void*>(0); + } + } + + return reinterpret_cast<const void*>(0); + } + + bool assign_immutable_symbol(expression_node_ptr node) + { + interval_t interval; + const void* baseptr_addr = base_ptr(node); + + exprtk_debug(("assign_immutable_symbol - base ptr addr: %p\n", baseptr_addr)); + + if (parser_->immutable_memory_map_.in_interval(baseptr_addr,interval)) + { + typename immutable_symtok_map_t::iterator itr = parser_->immutable_symtok_map_.find(interval); + + if (parser_->immutable_symtok_map_.end() != itr) + { + token_t& token = itr->second; + parser_->set_error( + parser_error::make_error(parser_error::e_parser, + token, + "ERR211 - Symbol '" + token.value + "' cannot be assigned-to as it is immutable.", + exprtk_error_location)); + } + else + parser_->set_synthesis_error("Unable to assign symbol is immutable."); + + return true; + } + + return false; + } + inline expression_node_ptr synthesize_assignment_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2]) { - if (details::is_variable_node(branch[0])) + if (assign_immutable_symbol(branch[0])) + { + return error_node(); + } + else if (details::is_variable_node(branch[0])) { lodge_assignment(e_st_variable,branch[0]); - return synthesize_expression<assignment_node_t,2>(operation,branch); } else if (details::is_vector_elem_node(branch[0])) { lodge_assignment(e_st_vecelem,branch[0]); - return synthesize_expression<assignment_vec_elem_node_t, 2>(operation, branch); } else if (details::is_rebasevector_elem_node(branch[0])) { lodge_assignment(e_st_vecelem,branch[0]); - return synthesize_expression<assignment_rebasevec_elem_node_t, 2>(operation, branch); } else if (details::is_rebasevector_celem_node(branch[0])) { lodge_assignment(e_st_vecelem,branch[0]); - return synthesize_expression<assignment_rebasevec_celem_node_t, 2>(operation, branch); } #ifndef exprtk_disable_string_capabilities else if (details::is_string_node(branch[0])) { lodge_assignment(e_st_string,branch[0]); - return synthesize_expression<assignment_string_node_t,2>(operation, branch); } else if (details::is_string_range_node(branch[0])) { lodge_assignment(e_st_string,branch[0]); - return synthesize_expression<assignment_string_range_node_t,2>(operation, branch); } #endif @@ -29687,6 +30105,11 @@ namespace exprtk inline expression_node_ptr synthesize_assignment_operation_expression(const details::operator_type& operation, expression_node_ptr (&branch)[2]) { + if (assign_immutable_symbol(branch[0])) + { + return error_node(); + } + if (details::is_variable_node(branch[0])) { lodge_assignment(e_st_variable,branch[0]); @@ -37006,6 +37429,9 @@ namespace exprtk std::string synthesis_error_; scope_element_manager sem_; + immutable_memory_map_t immutable_memory_map_; + immutable_symtok_map_t immutable_symtok_map_; + lexer::helper::helper_assembly helper_assembly_; lexer::helper::commutative_inserter commutative_inserter_; @@ -38552,202 +38978,7 @@ namespace exprtk std::vector<symbol_table_t*> auxiliary_symtab_list_; }; // class function_compositor - template <typename T> - inline bool pgo_primer() - { - static const std::string expression_list[] = - { - "(y + x)", - "2 * (y + x)", - "(2 * y + 2 * x)", - "(y + x / y) * (x - y / x)", - "x / ((x + y) * (x - y)) / y", - "1 - ((x * y) + (y / x)) - 3", - "sin(2 * x) + cos(pi / y)", - "1 - sin(2 * x) + cos(pi / y)", - "sqrt(1 - sin(2 * x) + cos(pi / y) / 3)", - "(x^2 / sin(2 * pi / y)) -x / 2", - "x + (cos(y - sin(2 / x * pi)) - sin(x - cos(2 * y / pi))) - y", - "clamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)", - "iclamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)", - "max(3.33, min(sqrt(1 - sin(2 * x) + cos(pi / y) / 3), 1.11))", - "if(avg(x,y) <= x + y, x - y, x * y) + 2 * pi / x", - "1.1x^1 + 2.2y^2 - 3.3x^3 + 4.4y^4 - 5.5x^5 + 6.6y^6 - 7.7x^27 + 8.8y^55", - "(yy + xx)", - "2 * (yy + xx)", - "(2 * yy + 2 * xx)", - "(yy + xx / yy) * (xx - yy / xx)", - "xx / ((xx + yy) * (xx - yy)) / yy", - "1 - ((xx * yy) + (yy / xx)) - 3", - "sin(2 * xx) + cos(pi / yy)", - "1 - sin(2 * xx) + cos(pi / yy)", - "sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3)", - "(xx^2 / sin(2 * pi / yy)) -xx / 2", - "xx + (cos(yy - sin(2 / xx * pi)) - sin(xx - cos(2 * yy / pi))) - yy", - "clamp(-1.0, sin(2 * pi * xx) + cos(yy / 2 * pi), +1.0)", - "max(3.33, min(sqrt(1 - sin(2 * xx) + cos(pi / yy) / 3), 1.11))", - "if(avg(xx,yy) <= xx + yy, xx - yy, xx * yy) + 2 * pi / xx", - "1.1xx^1 + 2.2yy^2 - 3.3xx^3 + 4.4yy^4 - 5.5xx^5 + 6.6yy^6 - 7.7xx^27 + 8.8yy^55", - "(1.1*(2.2*(3.3*(4.4*(5.5*(6.6*(7.7*(8.8*(9.9+x)))))))))", - "(((((((((x+9.9)*8.8)*7.7)*6.6)*5.5)*4.4)*3.3)*2.2)*1.1)", - "(x + y) * z", "x + (y * z)", "(x + y) * 7", "x + (y * 7)", - "(x + 7) * y", "x + (7 * y)", "(7 + x) * y", "7 + (x * y)", - "(2 + x) * 3", "2 + (x * 3)", "(2 + 3) * x", "2 + (3 * x)", - "(x + 2) * 3", "x + (2 * 3)", - "(x + y) * (z / w)", "(x + y) * (z / 7)", "(x + y) * (7 / z)", "(x + 7) * (y / z)", - "(7 + x) * (y / z)", "(2 + x) * (y / z)", "(x + 2) * (y / 3)", "(2 + x) * (y / 3)", - "(x + 2) * (3 / y)", "x + (y * (z / w))", "x + (y * (z / 7))", "x + (y * (7 / z))", - "x + (7 * (y / z))", "7 + (x * (y / z))", "2 + (x * (3 / y))", "x + (2 * (y / 4))", - "2 + (x * (y / 3))", "x + (2 * (3 / y))", - "x + ((y * z) / w)", "x + ((y * z) / 7)", "x + ((y * 7) / z)", "x + ((7 * y) / z)", - "7 + ((y * z) / w)", "2 + ((x * 3) / y)", "x + ((2 * y) / 3)", "2 + ((x * y) / 3)", - "x + ((2 * 3) / y)", "(((x + y) * z) / w)", - "(((x + y) * z) / 7)", "(((x + y) * 7) / z)", "(((x + 7) * y) / z)", "(((7 + x) * y) / z)", - "(((2 + x) * 3) / y)", "(((x + 2) * y) / 3)", "(((2 + x) * y) / 3)", "(((x + 2) * 3) / y)", - "((x + (y * z)) / w)", "((x + (y * z)) / 7)", "((x + (y * 7)) / y)", "((x + (7 * y)) / z)", - "((7 + (x * y)) / z)", "((2 + (x * 3)) / y)", "((x + (2 * y)) / 3)", "((2 + (x * y)) / 3)", - "((x + (2 * 3)) / y)", - "(xx + yy) * zz", "xx + (yy * zz)", - "(xx + yy) * 7", "xx + (yy * 7)", - "(xx + 7) * yy", "xx + (7 * yy)", - "(7 + xx) * yy", "7 + (xx * yy)", - "(2 + x) * 3", "2 + (x * 3)", - "(2 + 3) * x", "2 + (3 * x)", - "(x + 2) * 3", "x + (2 * 3)", - "(xx + yy) * (zz / ww)", "(xx + yy) * (zz / 7)", - "(xx + yy) * (7 / zz)", "(xx + 7) * (yy / zz)", - "(7 + xx) * (yy / zz)", "(2 + xx) * (yy / zz)", - "(xx + 2) * (yy / 3)", "(2 + xx) * (yy / 3)", - "(xx + 2) * (3 / yy)", "xx + (yy * (zz / ww))", - "xx + (yy * (zz / 7))", "xx + (yy * (7 / zz))", - "xx + (7 * (yy / zz))", "7 + (xx * (yy / zz))", - "2 + (xx * (3 / yy))", "xx + (2 * (yy / 4))", - "2 + (xx * (yy / 3))", "xx + (2 * (3 / yy))", - "xx + ((yy * zz) / ww)", "xx + ((yy * zz) / 7)", - "xx + ((yy * 7) / zz)", "xx + ((7 * yy) / zz)", - "7 + ((yy * zz) / ww)", "2 + ((xx * 3) / yy)", - "xx + ((2 * yy) / 3)", "2 + ((xx * yy) / 3)", - "xx + ((2 * 3) / yy)", "(((xx + yy) * zz) / ww)", - "(((xx + yy) * zz) / 7)", "(((xx + yy) * 7) / zz)", - "(((xx + 7) * yy) / zz)", "(((7 + xx) * yy) / zz)", - "(((2 + xx) * 3) / yy)", "(((xx + 2) * yy) / 3)", - "(((2 + xx) * yy) / 3)", "(((xx + 2) * 3) / yy)", - "((xx + (yy * zz)) / ww)", "((xx + (yy * zz)) / 7)", - "((xx + (yy * 7)) / yy)", "((xx + (7 * yy)) / zz)", - "((7 + (xx * yy)) / zz)", "((2 + (xx * 3)) / yy)", - "((xx + (2 * yy)) / 3)", "((2 + (xx * yy)) / 3)", - "((xx + (2 * 3)) / yy)" - }; - - static const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string); - - T x = T(0); - T y = T(0); - T z = T(0); - T w = T(0); - T xx = T(0); - T yy = T(0); - T zz = T(0); - T ww = T(0); - - exprtk::symbol_table<T> symbol_table; - symbol_table.add_constants(); - symbol_table.add_variable( "x", x); - symbol_table.add_variable( "y", y); - symbol_table.add_variable( "z", z); - symbol_table.add_variable( "w", w); - symbol_table.add_variable("xx",xx); - symbol_table.add_variable("yy",yy); - symbol_table.add_variable("zz",zz); - symbol_table.add_variable("ww",ww); - - typedef typename std::deque<exprtk::expression<T> > expr_list_t; - expr_list_t expr_list; - - const std::size_t rounds = 50; - - { - for (std::size_t r = 0; r < rounds; ++r) - { - expr_list.clear(); - exprtk::parser<T> parser; - - for (std::size_t i = 0; i < expression_list_size; ++i) - { - exprtk::expression<T> expression; - expression.register_symbol_table(symbol_table); - - if (!parser.compile(expression_list[i],expression)) - { - return false; - } - - expr_list.push_back(expression); - } - } - } - - struct execute - { - static inline T process(T& x, T& y, expression<T>& expression) - { - static const T lower_bound = T(-20); - static const T upper_bound = T(+20); - static const T delta = T(0.1); - - T total = T(0); - - for (x = lower_bound; x <= upper_bound; x += delta) - { - for (y = lower_bound; y <= upper_bound; y += delta) - { - total += expression.value(); - } - } - - return total; - } - }; - - for (std::size_t i = 0; i < expr_list.size(); ++i) - { - execute::process( x, y, expr_list[i]); - execute::process(xx, yy, expr_list[i]); - } - - { - for (std::size_t i = 0; i < 10000; ++i) - { - const T v = T(123.456 + i); - - if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T, 1>::result(v),details::numeric::pow(v,T(1))))) - return false; - - #define else_stmt(N) \ - else if (details::is_true(details::numeric::nequal(details::numeric::fast_exp<T,N>::result(v),details::numeric::pow(v,T(N))))) \ - return false; \ - - else_stmt( 2) else_stmt( 3) else_stmt( 4) else_stmt( 5) - else_stmt( 6) else_stmt( 7) else_stmt( 8) else_stmt( 9) - else_stmt(10) else_stmt(11) else_stmt(12) else_stmt(13) - else_stmt(14) else_stmt(15) else_stmt(16) else_stmt(17) - else_stmt(18) else_stmt(19) else_stmt(20) else_stmt(21) - else_stmt(22) else_stmt(23) else_stmt(24) else_stmt(25) - else_stmt(26) else_stmt(27) else_stmt(28) else_stmt(29) - else_stmt(30) else_stmt(31) else_stmt(32) else_stmt(33) - else_stmt(34) else_stmt(35) else_stmt(36) else_stmt(37) - else_stmt(38) else_stmt(39) else_stmt(40) else_stmt(41) - else_stmt(42) else_stmt(43) else_stmt(44) else_stmt(45) - else_stmt(46) else_stmt(47) else_stmt(48) else_stmt(49) - else_stmt(50) else_stmt(51) else_stmt(52) else_stmt(53) - else_stmt(54) else_stmt(55) else_stmt(56) else_stmt(57) - else_stmt(58) else_stmt(59) else_stmt(60) else_stmt(61) - } - } - - return true; - } -} +} // namespace exprtk #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) # ifndef NOMINMAX @@ -39023,6 +39254,9 @@ namespace exprtk { namespace rtl { namespace io { namespace file { namespace details { + using ::exprtk::details::char_ptr; + using ::exprtk::details::char_cptr; + enum file_mode { e_error = 0, @@ -39131,11 +39365,11 @@ namespace exprtk switch (mode) { case e_write : reinterpret_cast<std::ofstream*>(stream_ptr)-> - write(reinterpret_cast<const char*>(view.begin() + offset), amount * sizeof(typename View::value_t)); + write(reinterpret_cast<char_cptr>(view.begin() + offset), amount * sizeof(typename View::value_t)); break; case e_rdwrt : reinterpret_cast<std::fstream*>(stream_ptr)-> - write(reinterpret_cast<const char*>(view.begin() + offset) , amount * sizeof(typename View::value_t)); + write(reinterpret_cast<char_cptr>(view.begin() + offset) , amount * sizeof(typename View::value_t)); break; default : return false; @@ -39150,11 +39384,11 @@ namespace exprtk switch (mode) { case e_read : reinterpret_cast<std::ifstream*>(stream_ptr)-> - read(reinterpret_cast<char*>(view.begin() + offset), amount * sizeof(typename View::value_t)); + read(reinterpret_cast<char_ptr>(view.begin() + offset), amount * sizeof(typename View::value_t)); break; case e_rdwrt : reinterpret_cast<std::fstream*>(stream_ptr)-> - read(reinterpret_cast<char*>(view.begin() + offset) , amount * sizeof(typename View::value_t)); + read(reinterpret_cast<char_ptr>(view.begin() + offset) , amount * sizeof(typename View::value_t)); break; default : return false; @@ -39218,12 +39452,11 @@ namespace exprtk template <typename T> file_descriptor* make_handle(T v) { + const std::size_t fd_size = sizeof(details::file_descriptor*); details::file_descriptor* fd = reinterpret_cast<file_descriptor*>(0); - const std::size_t fd_size = sizeof(details::file_descriptor*); - - std::memcpy(reinterpret_cast<char*>(&fd), - reinterpret_cast<const char*>(&v), + std::memcpy(reinterpret_cast<char_ptr >(&fd), + reinterpret_cast<char_cptr>(&v ), fd_size); return fd; } @@ -39264,18 +39497,18 @@ namespace exprtk inline T operator() (const std::size_t& ps_index, parameter_list_t parameters) { - std::string file_name = to_str(string_t(parameters[0])); - std::string access; + const std::string file_name = to_str(string_t(parameters[0])); if (file_name.empty()) return T(0); - if (0 == ps_index) - access = "r"; - else if (0 == string_t(parameters[1]).size()) + if ((1 == ps_index) && (0 == string_t(parameters[1]).size())) + { return T(0); - else - access = to_str(string_t(parameters[1])); + } + + const std::string access = + (0 == ps_index) ? "r" : to_str(string_t(parameters[1])); details::file_descriptor* fd = new details::file_descriptor(file_name,access); @@ -40696,18 +40929,22 @@ namespace exprtk { namespace information { - static const char* library = "Mathematical Expression Toolkit"; - static const char* version = "2.7182818284590452353602874713526" - "624977572470936999595749669676277" - "240766303535475945713821785251664" - "274274663919320030599218174135966"; - static const char* date = "20220101"; + using ::exprtk::details::char_cptr; + + static char_cptr library = "Mathematical Expression Toolkit"; + static char_cptr version = "2.71828182845904523536028747135266" + "2497757247093699959574966967627724" + "0766303535475945713821785251664274" + "2746639193200305992181741359662904"; + static char_cptr date = "20230101"; + static char_cptr min_cpp = "199711L"; static inline std::string data() { static const std::string info_str = std::string(library) + std::string(" v") + std::string(version) + - std::string(" (") + date + std::string(")"); + std::string(" (") + date + std::string(")") + + std::string(" (") + min_cpp + std::string(")"); return info_str; } diff --git a/server/src/main.cpp b/server/src/main.cpp index eb4feaa..d24d605 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -270,8 +270,19 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl typedef exprtk::expression<double> expression_t; typedef exprtk::parser<double> parser_t; const std::string expression_string = Watchdog(ID)->m_aRule; + int ClientID = ClientNetToClient(ClientNetID); + std::string username = Client(ClientID)->m_aUsername; + std::string name = Client(ClientID)->m_aName; + std::string type = Client(ClientID)->m_aType; + std::string host = Client(ClientID)->m_aHost; + std::string location = Client(ClientID)->m_aLocation; symbol_table_t symbol_table; + symbol_table.add_stringvar("username", username); + symbol_table.add_stringvar("name", name); + symbol_table.add_stringvar("type", type); + symbol_table.add_stringvar("host", host); + symbol_table.add_stringvar("location", location); symbol_table.add_variable("load_1",load_1); symbol_table.add_variable("load_5",load_5); symbol_table.add_variable("load_15",load_15); @@ -310,7 +321,6 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl if (expression.value() > 0) { - int ClientID = ClientNetToClient(ClientNetID); time_t currentStamp = (long long)time(/*ago*/0); if ((currentStamp-Client(ClientID)->m_AlarmLastTime) > Watchdog(ID)->m_aInterval) { @@ -330,11 +340,11 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl sprintf(encodeBuffer, "【告警名称】 %s \n\n【告警时间】 %s \n\n【用户名】 %s \n\n【节点名】 %s \n\n【虚拟化】 %s \n\n【主机名】 %s \n\n【位 置】 %s", Watchdog(ID)->m_aName, standardTime, - Client(ClientID)->m_aUsername, - Client(ClientID)->m_aName, - Client(ClientID)->m_aType, - Client(ClientID)->m_aHost, - Client(ClientID)->m_aLocation); + username.c_str(), + name.c_str(), + type.c_str(), + host.c_str(), + location.c_str()); char *encodeUrl = curl_easy_escape(curl, encodeBuffer, strlen(encodeBuffer)); //standard url