diff --git a/exprtk.hpp b/exprtk.hpp index 7d861a8..b19268e 100644 --- a/exprtk.hpp +++ b/exprtk.hpp @@ -2393,7 +2393,7 @@ namespace exprtk private: - token_list_t token_list_; + token_list_t token_list_; token_list_itr_t token_itr_; token_list_itr_t store_token_itr_; token_t eof_token_; @@ -2436,7 +2436,7 @@ namespace exprtk inline std::size_t process(generator& g) { - if (!g.token_list_.empty()) + if (g.token_list_.size() >= stride_) { for (std::size_t i = 0; i < (g.token_list_.size() - stride_ + 1); ++i) { @@ -2561,6 +2561,8 @@ namespace exprtk { if (g.token_list_.empty()) return 0; + else if (g.token_list_.size() < stride_) + return 0; std::size_t changes = 0; @@ -4380,9 +4382,11 @@ namespace exprtk typedef range_data_type range_data_type_t; - virtual std::string str() const = 0; + virtual std::string str () const = 0; virtual const char* base() const = 0; + + virtual std::size_t size() const = 0; }; template @@ -4428,6 +4432,11 @@ namespace exprtk return value_.data(); } + std::size_t size() const + { + return value_.size(); + } + range_t& range_ref() { return rp_; @@ -5383,9 +5392,9 @@ namespace exprtk expression_ptr incrementor, expression_ptr loop_body) : initialiser_(initialiser), - condition_ (condition), + condition_ (condition ), incrementor_(incrementor), - loop_body_ (loop_body), + loop_body_ (loop_body ), initialiser_deletable_(branch_deletable(initialiser_)), condition_deletable_ (branch_deletable(condition_ )), incrementor_deletable_(branch_deletable(incrementor_)), @@ -6247,26 +6256,31 @@ namespace exprtk return std::numeric_limits::quiet_NaN(); } - inline std::string str() const + std::string str() const { return ref(); } - inline virtual std::string& ref() + const char* base() const + { + return (*value_).data(); + } + + std::size_t size() const + { + return ref().size(); + } + + std::string& ref() { return (*value_); } - inline virtual const std::string& ref() const + const std::string& ref() const { return (*value_); } - inline typename expression_node::node_type type() const - { - return expression_node::e_stringvar; - } - range_t& range_ref() { return rp_; @@ -6277,9 +6291,9 @@ namespace exprtk return rp_; } - const char* base() const + inline typename expression_node::node_type type() const { - return (*value_).data(); + return expression_node::e_stringvar; } private: @@ -6327,6 +6341,16 @@ namespace exprtk return (*value_); } + const char* base() const + { + return (*value_).data(); + } + + std::size_t size() const + { + return ref().size(); + } + inline range_t range() const { return rp_; @@ -6357,11 +6381,6 @@ namespace exprtk return expression_node::e_stringvarrng; } - const char* base() const - { - return (*value_).data(); - } - private: std::string* value_; @@ -6395,22 +6414,32 @@ namespace exprtk return std::numeric_limits::quiet_NaN(); } - inline std::string str() const + std::string str() const { return value_; } - inline range_t range() const + const char* base() const + { + return value_.data(); + } + + std::size_t size() const + { + return value_.size(); + } + + range_t range() const { return rp_; } - inline virtual range_t& range_ref() + range_t& range_ref() { return rp_; } - inline virtual const range_t& range_ref() const + const range_t& range_ref() const { return rp_; } @@ -6420,11 +6449,6 @@ namespace exprtk return expression_node::e_cstringvarrng; } - const char* base() const - { - return value_.data(); - } - private: const_string_range_node& operator=(const const_string_range_node&); @@ -6500,7 +6524,7 @@ namespace exprtk range_t& range = str_range_ptr_->range_ref(); - const std::size_t base_str_size = str_base_ptr_->str().size(); + const std::size_t base_str_size = str_base_ptr_->size(); if ( range (str_r0,str_r1,base_str_size) && @@ -6529,6 +6553,11 @@ namespace exprtk return value_.data(); } + std::size_t size() const + { + return value_.size(); + } + range_t& range_ref() { return range_; @@ -6634,8 +6663,8 @@ namespace exprtk range_t& range1 = str1_range_ptr_->range_ref(); if ( - range0(str0_r0,str0_r1,str0_base_ptr_->str().size()) && - range1(str1_r0,str1_r1,str1_base_ptr_->str().size()) + range0(str0_r0,str0_r1,str0_base_ptr_->size()) && + range1(str1_r0,str1_r1,str1_base_ptr_->size()) ) { const std::size_t size0 = (str0_r1 - str0_r0) + 1; @@ -6662,6 +6691,11 @@ namespace exprtk return value_.data(); } + std::size_t size() const + { + return value_.size(); + } + range_t& range_ref() { return range_; @@ -6745,6 +6779,11 @@ namespace exprtk return str0_node_ptr_->base(); } + std::size_t size() const + { + return str0_node_ptr_->size(); + } + range_t& range_ref() { return str0_node_ptr_->range_ref(); @@ -6837,7 +6876,7 @@ namespace exprtk if (str_base_ptr_) { branch_->value(); - result = T(str_base_ptr_->str().size()); + result = T(str_base_ptr_->size()); } return result; @@ -6854,6 +6893,266 @@ namespace exprtk bool branch_deletable_; str_base_ptr str_base_ptr_; }; + + struct asn_assignment + { + static inline void execute(std::string& s, const char* data, const std::size_t size) + { s.assign(data,size); } + }; + + struct asn_addassignment + { + static inline void execute(std::string& s, const char* data, const std::size_t size) + { s.append(data,size); } + }; + + template + class assignment_string_node : public binary_node , + public string_base_node, + public range_interface + { + public: + + typedef expression_node * expression_ptr; + typedef stringvar_node * strvar_node_ptr; + typedef string_base_node* str_base_ptr; + typedef range_pack range_t; + typedef range_t* range_ptr; + typedef range_interface irange_t; + typedef irange_t* irange_ptr; + typedef typename range_t::cached_range_t cached_range_t; + + assignment_string_node(const operator_type& opr, + expression_ptr branch0, + expression_ptr branch1) + : binary_node(opr,branch0,branch1), + str0_base_ptr_ (0), + str1_base_ptr_ (0), + str0_node_ptr_ (0), + str1_range_ptr_(0) + { + if (is_string_node(binary_node::branch_[0].first)) + { + str0_node_ptr_ = static_cast(binary_node::branch_[0].first); + + str0_base_ptr_ = dynamic_cast(binary_node::branch_[0].first); + } + + if (is_generally_string_node(binary_node::branch_[1].first)) + { + str1_base_ptr_ = dynamic_cast(binary_node::branch_[1].first); + + if (0 == str1_base_ptr_) + return; + + irange_ptr range_ptr = dynamic_cast(binary_node::branch_[1].first); + + if (0 == range_ptr) + return; + + str1_range_ptr_ = &(range_ptr->range_ref()); + } + } + + inline T value() const + { + if ( + str0_base_ptr_ && + str1_base_ptr_ && + str0_node_ptr_ && + str1_range_ptr_ + ) + { + binary_node::branch_[1].first->value(); + + std::size_t r0 = 0; + std::size_t r1 = 0; + + range_t& range = (*str1_range_ptr_); + + if (range(r0,r1,str1_base_ptr_->size())) + { + AssignmentProcess::execute(str0_node_ptr_->ref(), + str1_base_ptr_->base() + r0, + (r1 - r0) + 1); + + binary_node::branch_[0].first->value(); + } + } + + return std::numeric_limits::quiet_NaN(); + } + + std::string str() const + { + return str0_node_ptr_->str(); + } + + const char* base() const + { + return str0_node_ptr_->base(); + } + + std::size_t size() const + { + return str0_node_ptr_->size(); + } + + range_t& range_ref() + { + return str0_node_ptr_->range_ref(); + } + + const range_t& range_ref() const + { + return str0_node_ptr_->range_ref(); + } + + inline typename expression_node::node_type type() const + { + return expression_node::e_strass; + } + + private: + + str_base_ptr str0_base_ptr_; + str_base_ptr str1_base_ptr_; + strvar_node_ptr str0_node_ptr_; + range_ptr str1_range_ptr_; + }; + + template + class assignment_string_range_node : public binary_node , + public string_base_node, + public range_interface + { + public: + + typedef expression_node * expression_ptr; + typedef stringvar_node * strvar_node_ptr; + typedef string_base_node* str_base_ptr; + typedef range_pack range_t; + typedef range_t* range_ptr; + typedef range_interface irange_t; + typedef irange_t* irange_ptr; + typedef typename range_t::cached_range_t cached_range_t; + + assignment_string_range_node(const operator_type& opr, + expression_ptr branch0, + expression_ptr branch1) + : binary_node(opr,branch0,branch1), + str0_base_ptr_ (0), + str1_base_ptr_ (0), + str0_node_ptr_ (0), + str0_range_ptr_(0), + str1_range_ptr_(0) + { + if (is_string_range_node(binary_node::branch_[0].first)) + { + str0_node_ptr_ = static_cast(binary_node::branch_[0].first); + + str0_base_ptr_ = dynamic_cast(binary_node::branch_[0].first); + + irange_ptr range_ptr = dynamic_cast(binary_node::branch_[0].first); + + if (0 == range_ptr) + return; + + str0_range_ptr_ = &(range_ptr->range_ref()); + } + + if (is_generally_string_node(binary_node::branch_[1].first)) + { + str1_base_ptr_ = dynamic_cast(binary_node::branch_[1].first); + + if (0 == str1_base_ptr_) + return; + + irange_ptr range_ptr = dynamic_cast(binary_node::branch_[1].first); + + if (0 == range_ptr) + return; + + str1_range_ptr_ = &(range_ptr->range_ref()); + } + } + + inline T value() const + { + if ( + str0_base_ptr_ && + str1_base_ptr_ && + str0_node_ptr_ && + str0_range_ptr_ && + str1_range_ptr_ + ) + { + binary_node::branch_[0].first->value(); + binary_node::branch_[1].first->value(); + + std::size_t s0_r0 = 0; + std::size_t s0_r1 = 0; + + std::size_t s1_r0 = 0; + std::size_t s1_r1 = 0; + + range_t& range0 = (*str0_range_ptr_); + range_t& range1 = (*str1_range_ptr_); + + if ( + range0(s0_r0,s0_r1,str0_base_ptr_->size()) && + range1(s1_r0,s1_r1,str1_base_ptr_->size()) + ) + { + std::size_t size = std::min((s0_r1 - s0_r0),(s1_r1 - s1_r0)) + 1; + + std::copy(str1_base_ptr_->base() + s1_r0, + str1_base_ptr_->base() + s1_r0 + size, + const_cast(base() + s0_r0)); + } + } + + return std::numeric_limits::quiet_NaN(); + } + + std::string str() const + { + return str0_node_ptr_->str(); + } + + const char* base() const + { + return str0_node_ptr_->base(); + } + + std::size_t size() const + { + return str0_node_ptr_->size(); + } + + range_t& range_ref() + { + return str0_node_ptr_->range_ref(); + } + + const range_t& range_ref() const + { + return str0_node_ptr_->range_ref(); + } + + inline typename expression_node::node_type type() const + { + return expression_node::e_strass; + } + + private: + + str_base_ptr str0_base_ptr_; + str_base_ptr str1_base_ptr_; + strvar_node_ptr str0_node_ptr_; + range_ptr str0_range_ptr_; + range_ptr str1_range_ptr_; + }; #endif template @@ -7388,128 +7687,6 @@ namespace exprtk variable_node* var_node_ptr_; }; - struct asn_assignment - { - static inline void execute(std::string& s, const char* data, const std::size_t size) - { s.assign(data,size); } - }; - - struct asn_addassignment - { - static inline void execute(std::string& s, const char* data, const std::size_t size) - { s.append(data,size); } - }; - - template - class assignment_string_node : public binary_node , - public string_base_node, - public range_interface - { - public: - - typedef expression_node * expression_ptr; - typedef stringvar_node * strvar_node_ptr; - typedef string_base_node* str_base_ptr; - typedef range_pack range_t; - typedef range_t* range_ptr; - typedef range_interface irange_t; - typedef irange_t* irange_ptr; - typedef typename range_t::cached_range_t cached_range_t; - - assignment_string_node(const operator_type& opr, - expression_ptr branch0, - expression_ptr branch1) - : binary_node(opr,branch0,branch1), - str0_base_ptr_ (0), - str1_base_ptr_ (0), - str0_node_ptr_ (0), - str1_range_ptr_(0) - { - if (is_string_node(binary_node::branch_[0].first)) - { - str0_node_ptr_ = static_cast(binary_node::branch_[0].first); - - str0_base_ptr_ = dynamic_cast(binary_node::branch_[0].first); - } - - if (is_generally_string_node(binary_node::branch_[1].first)) - { - str1_base_ptr_ = dynamic_cast(binary_node::branch_[1].first); - - if (0 == str1_base_ptr_) - return; - - irange_ptr range_ptr = dynamic_cast(binary_node::branch_[1].first); - - if (0 == range_ptr) - return; - - str1_range_ptr_ = &(range_ptr->range_ref()); - } - } - - inline T value() const - { - if ( - str0_base_ptr_ && - str1_base_ptr_ && - str0_node_ptr_ && - str1_range_ptr_ - ) - { - binary_node::branch_[1].first->value(); - - std::size_t r0 = 0; - std::size_t r1 = 0; - - range_t& range = (*str1_range_ptr_); - - if (range(r0,r1,str1_base_ptr_->str().size())) - { - AssignmentProcess::execute(str0_node_ptr_->ref(), - str1_base_ptr_->str().data() + r0, - (r1 - r0) + 1); - - binary_node::branch_[0].first->value(); - } - } - - return std::numeric_limits::quiet_NaN(); - } - - std::string str() const - { - return str0_node_ptr_->str(); - } - - const char* base() const - { - return str0_node_ptr_->base(); - } - - range_t& range_ref() - { - return str0_node_ptr_->range_ref(); - } - - const range_t& range_ref() const - { - return str0_node_ptr_->range_ref(); - } - - inline typename expression_node::node_type type() const - { - return expression_node::e_strass; - } - - private: - - str_base_ptr str0_base_ptr_; - str_base_ptr str1_base_ptr_; - strvar_node_ptr str0_node_ptr_; - range_ptr str1_range_ptr_; - }; - template class assignment_vec_elem_node : public binary_node { @@ -9153,7 +9330,7 @@ namespace exprtk if (0 == (sbn = dynamic_cast*>(arg_list_[i]))) return false; - ts.size = sbn->str().size(); + ts.size = sbn->size(); ts.data = reinterpret_cast(const_cast(sbn->base())); ts.type = type_store_t::e_string; @@ -9328,7 +9505,8 @@ namespace exprtk { typedef typename StringFunction::parameter_list_t parameter_list_t; - result = (*gen_function_t::function_)(ret_string_,parameter_list_t(gen_function_t::typestore_list_)); + result = (*gen_function_t::function_)(ret_string_, + parameter_list_t(gen_function_t::typestore_list_)); range_.n1_c.second = ret_string_.size() - 1; range_.cache.second = range_.n1_c.second; @@ -9355,6 +9533,11 @@ namespace exprtk return ret_string_.data(); } + std::size_t size() const + { + return ret_string_.size(); + } + range_t& range_ref() { return range_; @@ -9396,7 +9579,8 @@ namespace exprtk { typedef typename GenericFunction::parameter_list_t parameter_list_t; - return (*gen_function_t::function_)(param_seq_index_,parameter_list_t(gen_function_t::typestore_list_)); + return (*gen_function_t::function_)(param_seq_index_, + parameter_list_t(gen_function_t::typestore_list_)); } } @@ -9462,27 +9646,27 @@ namespace exprtk std::size_t param_seq_index_; }; - #define exprtk_define_unary_op(OpName) \ - template \ - struct OpName##_op \ - { \ - typedef typename functor_t::Type Type; \ - \ - static inline T process(Type v) \ - { \ - return numeric:: OpName (v); \ - } \ - \ - static inline typename expression_node::node_type type()\ - { \ - return expression_node::e_##OpName; \ - } \ - \ - static inline details::operator_type operation() \ - { \ - return details::e_##OpName; \ - } \ - }; \ + #define exprtk_define_unary_op(OpName) \ + template \ + struct OpName##_op \ + { \ + typedef typename functor_t::Type Type; \ + \ + static inline T process(Type v) \ + { \ + return numeric:: OpName (v); \ + } \ + \ + static inline typename expression_node::node_type type() \ + { \ + return expression_node::e_##OpName; \ + } \ + \ + static inline details::operator_type operation() \ + { \ + return details::e_##OpName; \ + } \ + }; \ exprtk_define_unary_op(abs ) exprtk_define_unary_op(acos ) @@ -10373,6 +10557,7 @@ namespace exprtk static inline T process(const ivector_ptr v) { vector_holder& vec = v->vec()->ref(); + T result = T(0); for (std::size_t i = 0; i < vec.size(); ++i) @@ -10392,6 +10577,7 @@ namespace exprtk static inline T process(const ivector_ptr v) { vector_holder& vec = v->vec()->ref(); + T result = (*vec[0]); for (std::size_t i = 1; i < vec.size(); ++i) @@ -10411,6 +10597,7 @@ namespace exprtk static inline T process(const ivector_ptr v) { vector_holder& vec = v->vec()->ref(); + T result = T(0); for (std::size_t i = 0; i < vec.size(); ++i) @@ -10430,6 +10617,7 @@ namespace exprtk static inline T process(const ivector_ptr v) { vector_holder& vec = v->vec()->ref(); + T result = (*vec[0]); for (std::size_t i = 1; i < vec.size(); ++i) @@ -10452,6 +10640,7 @@ namespace exprtk static inline T process(const ivector_ptr v) { vector_holder& vec = v->vec()->ref(); + T result = (*vec[0]); for (std::size_t i = 1; i < vec.size(); ++i) @@ -12290,12 +12479,12 @@ namespace exprtk { public: - typedef expression_node * expression_ptr; - typedef string_base_node* str_base_ptr; - typedef range_pack range_t; - typedef range_t* range_ptr; - typedef range_interface irange_t; - typedef irange_t* irange_ptr; + typedef expression_node * expression_ptr; + typedef string_base_node* str_base_ptr; + typedef range_pack range_t; + typedef range_t* range_ptr; + typedef range_interface irange_t; + typedef irange_t* irange_ptr; str_sogens_node(const operator_type& opr, expression_ptr branch0, @@ -12359,8 +12548,8 @@ namespace exprtk range_t& range1 = (*str1_range_ptr_); if ( - range0(str0_r0,str0_r1,str0_base_ptr_->str().size()) && - range1(str1_r0,str1_r1,str1_base_ptr_->str().size()) + range0(str0_r0,str0_r1,str0_base_ptr_->size()) && + range1(str1_r0,str1_r1,str1_base_ptr_->size()) ) { return Operation::process( @@ -14883,9 +15072,10 @@ namespace exprtk typedef details::const_string_range_node const_string_range_node_t; typedef details::generic_string_range_node generic_string_range_node_t; typedef details::string_concat_node string_concat_node_t; + typedef details::assignment_string_node assignment_string_node_t; + typedef details::assignment_string_range_node assignment_string_range_node_t; #endif typedef details::assignment_node assignment_node_t; - typedef details::assignment_string_node assignment_string_node_t; typedef details::assignment_vec_elem_node assignment_vec_elem_node_t; typedef details::assignment_vec_node assignment_vec_node_t; typedef details::assignment_vecvec_node assignment_vecvec_node_t; @@ -15051,7 +15241,7 @@ namespace exprtk for (std::size_t j = 0; j < element_.size(); ++j) { if ( - (element_[j].name == se.name ) && + (element_[j].name == se.name ) && (element_[j].depth <= se.depth) && (element_[j].index == se.index) && (element_[j].size == se.size ) @@ -16780,6 +16970,7 @@ namespace exprtk make_error(parser_error::e_syntax, current_token_, "ERR38 - Expected '?' after condition of ternary if-statement")); + result = false; } else if (0 == (consequent = parse_expression())) @@ -16788,6 +16979,7 @@ namespace exprtk make_error(parser_error::e_syntax, current_token_, "ERR39 - Failed to parse consequent for if-statement")); + result = false; } else if (!token_is(token_t::e_colon)) @@ -16796,6 +16988,7 @@ namespace exprtk make_error(parser_error::e_syntax, current_token_, "ERR40 - Expected ':' between ternary if-statement consequent and alternative")); + result = false; } else if (0 == (alternative = parse_expression())) @@ -16804,6 +16997,7 @@ namespace exprtk make_error(parser_error::e_syntax, current_token_, "ERR41 - Failed to parse alternative for if-statement")); + result = false; } @@ -17944,7 +18138,7 @@ namespace exprtk { free_node(node_allocator_,result); - return expression_generator_(T(const_str_node->str().size())); + return expression_generator_(T(const_str_node->size())); } else return node_allocator_.allocate > @@ -21760,6 +21954,12 @@ namespace exprtk return synthesize_expression(operation,branch); } + else if (details::is_string_range_node(branch[0])) + { + lodge_assignment(e_st_string,branch[0]); + + return synthesize_expression(operation,branch); + } else if (details::is_vector_node(branch[0])) { lodge_assignment(e_st_vector,branch[0]); diff --git a/exprtk_test.cpp b/exprtk_test.cpp index f790cb8..c0e5157 100644 --- a/exprtk_test.cpp +++ b/exprtk_test.cpp @@ -2121,7 +2121,7 @@ inline bool run_test02() test_ab("('abc' + b[r0:r2]) == 'abc234567' ","abc","0123456789" ,T(1.0)), test_ab("(a[r0:r0] + b[r3:r3]) == 'c3' ","abc","0123456789" ,T(1.0)), test_ab("(a[r3:] + b) == 'defghij0123' ","abcdefghij","0123",T(1.0)), - test_ab("('abc' + b[:r2]) == 'abc01234567' ","abc","0123456789" ,T(1.0)), + test_ab("('abc' + b[:r2]) == 'abc01234567' ","abc","0123456789" ,T(1.0)), test_ab("a[0:r0] + '123' == 'abc' + b[0:r0] ","abcXYZ", "123XYZ", T(1.0)), test_ab("a[ :r0] + '123' == 'abc' + b[ :r0] ","abcXYZ", "123XYZ", T(1.0)), test_ab("a[r3: ] + '123' == 'abc' + b[r3: ]","XYZabc", "XYZ123", T(1.0)), @@ -2170,7 +2170,74 @@ inline bool run_test02() test_ab("(a + b)[0:5][] == 6 ","abc","123" ,T(1.0)), test_ab("(a + b)[0:5][1:4][] == 4 ","abc","123" ,T(1.0)), test_ab("(a + b)[0:5][1:4][1:2][] == 2 ","abc","123" ,T(1.0)), - test_ab("(a + b)[0:5][1:4][1:2][0:0][] == 1 ","abc","123" ,T(1.0)) + test_ab("(a + b)[0:5][1:4][1:2][0:0][] == 1 ","abc","123" ,T(1.0)), + test_ab("(a[ : ] := b); (a == 'ABCDEFGHIJ');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[0: ] := b); (a == 'ABCDEFGHIJ');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[ :9] := b); (a == 'ABCDEFGHIJ');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[3:7] := b); (a == '012ABCDE89');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[2:8] := b); (a == '01ABCDEFG9');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[1:9] := b); (a == '0ABCDEFGHI');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[0:0] := b); (a == 'A123456789');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[1:1] := b); (a == '0A23456789');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[2:2] := b); (a == '01A3456789');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[3:3] := b); (a == '012A456789');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[4:4] := b); (a == '0123A56789');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[5:5] := b); (a == '01234A6789');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[6:6] := b); (a == '012345A789');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[7:7] := b); (a == '0123456A89');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[8:8] := b); (a == '01234567A9');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[9:9] := b); (a == '012345678A');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[0:1] := b); (a == 'AB23456789');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[1:2] := b); (a == '0AB3456789');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[2:3] := b); (a == '01AB456789');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[3:4] := b); (a == '012AB56789');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[4:5] := b); (a == '0123AB6789');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[5:6] := b); (a == '01234AB789');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[6:7] := b); (a == '012345AB89');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[7:8] := b); (a == '0123456AB9');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[8:9] := b); (a == '01234567AB');", "0123456789","ABCDEFGHIJ" ,T(1.0)), + test_ab("(a[ : ] := b[3:b[] - 3]); (a == 'ABCDEFGHIJ');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[0: ] := b[3:b[] - 3]); (a == 'ABCDEFGHIJ');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[ :9] := b[3:b[] - 3]); (a == 'ABCDEFGHIJ');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[3:7] := b[3:b[] - 3]); (a == '012ABCDE89');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[2:8] := b[3:b[] - 3]); (a == '01ABCDEFG9');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[1:9] := b[3:b[] - 3]); (a == '0ABCDEFGHI');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[0:0] := b[3:b[] - 3]); (a == 'A123456789');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[1:1] := b[3:b[] - 3]); (a == '0A23456789');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[2:2] := b[3:b[] - 3]); (a == '01A3456789');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[3:3] := b[3:b[] - 3]); (a == '012A456789');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[4:4] := b[3:b[] - 3]); (a == '0123A56789');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[5:5] := b[3:b[] - 3]); (a == '01234A6789');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[6:6] := b[3:b[] - 3]); (a == '012345A789');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[7:7] := b[3:b[] - 3]); (a == '0123456A89');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[8:8] := b[3:b[] - 3]); (a == '01234567A9');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[9:9] := b[3:b[] - 3]); (a == '012345678A');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[0:1] := b[3:b[] - 3]); (a == 'AB23456789');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[1:2] := b[3:b[] - 3]); (a == '0AB3456789');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[2:3] := b[3:b[] - 3]); (a == '01AB456789');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[3:4] := b[3:b[] - 3]); (a == '012AB56789');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[4:5] := b[3:b[] - 3]); (a == '0123AB6789');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[5:6] := b[3:b[] - 3]); (a == '01234AB789');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[6:7] := b[3:b[] - 3]); (a == '012345AB89');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[7:8] := b[3:b[] - 3]); (a == '0123456AB9');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[8:9] := b[3:b[] - 3]); (a == '01234567AB');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[0:9] := b); (a == 'A123456789');", "0123456789","A" ,T(1.0)), + test_ab("(a[0:9] := b); (a == 'AB23456789');", "0123456789","AB" ,T(1.0)), + test_ab("(a[0:9] := b); (a == 'ABC3456789');", "0123456789","ABC" ,T(1.0)), + test_ab("(a[0:9] := b); (a == 'ABCD456789');", "0123456789","ABCD" ,T(1.0)), + test_ab("(a[0:9] := b); (a == 'ABCDE56789');", "0123456789","ABCDE" ,T(1.0)), + test_ab("(a[0:9] := b); (a == 'ABCDEF6789');", "0123456789","ABCDEF" ,T(1.0)), + test_ab("(a[0:9] := b); (a == 'ABCDEFG789');", "0123456789","ABCDEFG" ,T(1.0)), + test_ab("(a[0:9] := b); (a == 'ABCDEFGH89');", "0123456789","ABCDEFGH" ,T(1.0)), + test_ab("(a[0:9] := b); (a == 'ABCDEFGHI9');", "0123456789","ABCDEFGHI" ,T(1.0)), + test_ab("(a[3:9] := b); (a == '012A456789');", "0123456789","A" ,T(1.0)), + test_ab("(a[3:9] := b); (a == '012AB56789');", "0123456789","AB" ,T(1.0)), + test_ab("(a[3:9] := b); (a == '012ABC6789');", "0123456789","ABC" ,T(1.0)), + test_ab("(a[3:9] := b); (a == '012ABCD789');", "0123456789","ABCD" ,T(1.0)), + test_ab("(a[3:9] := b); (a == '012ABCDE89');", "0123456789","ABCDE" ,T(1.0)), + test_ab("(a[3:9] := b); (a == '012ABCDEF9');", "0123456789","ABCDEF" ,T(1.0)), + test_ab("(a[r1 / r0:r2] := b[3:b[] - r3]); (a == '012ABCDE89');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)), + test_ab("(a[r0:r2 + 1] := b[r3:b[] - r3]); (a == '01ABCDEFG9');", "0123456789","xyzABCDEFGHIJxyz",T(1.0)) }; static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_ab); diff --git a/readme.txt b/readme.txt index d983b68..3d1e536 100644 --- a/readme.txt +++ b/readme.txt @@ -403,13 +403,19 @@ of C++ compilers: | | will be performed. (eg: 1.67 --> 1) | +----------+---------------------------------------------------------+ | := | Assign the value of x to y. Where x is a mutable string | -| | and y is either a string or a string range. eg: | +| | or string range and y is either a string or a string | +| | range. eg: | | | 1. x := y | | | 2. x := 'abc' | | | 3. x := y[:i + j] | | | 4. x := '0123456789'[2:7] | | | 5. x := '0123456789'[2i + 1:7] | | | 6. x := (y := '0123456789'[2:7]) | +| | 7. x[i:j] := y | +| | 8. x[i:j] := (y + 'abcdefg'[8 / 4:5])[m:n] | +| | | +| | Note: For options 7 and 8 the shorter of the two ranges | +| | will denote the number characters that are to be copied.| +----------+---------------------------------------------------------+ | + | Concatenation of x and y. Where x and y are strings or | | | string ranges. eg | @@ -841,6 +847,7 @@ following are examples of the various transformations that can occur: (d) (2 / x) / (3 / y) ---> (2 / 3) / (x * y) (e) (2 * x) * (3 * y) ---> (2 * 3) * (x * y) + Note: When using strength reduction in conjunction with expressions whose inputs or sub-expressions may result in values nearing either of the @@ -1919,11 +1926,14 @@ into account when using Exprtk: be to recompile an expression from its string form every time it requires evaluating. - (24) Where appropriate the return values of method invocations from - the parser and symbol_table should be taken into account. - Specifically the 'compile' method of the parser and the - 'add_xxx' set of methods of the symbol table as they denote - success or failure of the invoked call. + (24) It is strongly recommended that the return value of method + invocations from the parser and symbol_table types be taken + into account. Specifically the 'compile' method of the parser + and the 'add_xxx' set of methods of the symbol_table as they + denote either the success or failure state of the invoked call. + Cointinued processing from a failed state without having first + rectified the underlying issue will in turn result in further + failures and undefined behaviours. (25) The following are examples of compliant floating point value representations: