diff --git a/exprtk.hpp b/exprtk.hpp index 9abf311..0da0960 100644 --- a/exprtk.hpp +++ b/exprtk.hpp @@ -66,7 +66,10 @@ namespace exprtk namespace details { - inline bool is_whitespace(const char c) + typedef unsigned char uchar_t; + typedef char char_t; + + inline bool is_whitespace(const char_t c) { return (' ' == c) || ('\n' == c) || ('\r' == c) || ('\t' == c) || @@ -74,7 +77,7 @@ namespace exprtk ('\f' == c) ; } - inline bool is_operator_char(const char c) + inline bool is_operator_char(const char_t c) { return ('+' == c) || ('-' == c) || ('*' == c) || ('/' == c) || @@ -89,43 +92,43 @@ namespace exprtk ('|' == c) || (';' == c) ; } - inline bool is_letter(const char c) + inline bool is_letter(const char_t c) { return (('a' <= c) && (c <= 'z')) || (('A' <= c) && (c <= 'Z')) ; } - inline bool is_digit(const char c) + inline bool is_digit(const char_t c) { return ('0' <= c) && (c <= '9'); } - inline bool is_letter_or_digit(const char c) + inline bool is_letter_or_digit(const char_t c) { return is_letter(c) || is_digit(c); } - inline bool is_left_bracket(const char c) + inline bool is_left_bracket(const char_t c) { return ('(' == c) || ('[' == c) || ('{' == c); } - inline bool is_right_bracket(const char c) + inline bool is_right_bracket(const char_t c) { return (')' == c) || (']' == c) || ('}' == c); } - inline bool is_bracket(const char c) + inline bool is_bracket(const char_t c) { return is_left_bracket(c) || is_right_bracket(c); } - inline bool is_sign(const char c) + inline bool is_sign(const char_t c) { return ('+' == c) || ('-' == c); } - inline bool is_invalid(const char c) + inline bool is_invalid(const char_t c) { return !is_whitespace (c) && !is_operator_char(c) && @@ -138,7 +141,7 @@ namespace exprtk ('\'' != c); } - inline bool imatch(const char c1, const char c2) + inline bool imatch(const char_t c1, const char_t c2) { return std::tolower(c1) == std::tolower(c2); } @@ -217,7 +220,7 @@ namespace exprtk (('a' <= digit) && (digit <= 'f')) ; } - inline unsigned char hex_to_bin(unsigned char h) + inline uchar_t hex_to_bin(uchar_t h) { if (('0' <= h) && (h <= '9')) return (h - '0'); @@ -339,8 +342,8 @@ namespace exprtk for (std::size_t i = 0; i < length; ++i) { - const char c1 = static_cast(std::tolower(s1[i])); - const char c2 = static_cast(std::tolower(s2[i])); + const char_t c1 = static_cast(std::tolower(s1[i])); + const char_t c2 = static_cast(std::tolower(s2[i])); if (c1 > c2) return false; @@ -502,7 +505,7 @@ namespace exprtk struct cs_match { - static inline bool cmp(const char c0, const char c1) + static inline bool cmp(const char_t c0, const char_t c1) { return (c0 == c1); } @@ -510,7 +513,7 @@ namespace exprtk struct cis_match { - static inline bool cmp(const char c0, const char c1) + static inline bool cmp(const char_t c0, const char_t c1) { return (std::tolower(c0) == std::tolower(c1)); } @@ -621,7 +624,7 @@ namespace exprtk { if ('*' == (*p_itr)) { - const char target = static_cast(std::toupper(*(p_itr - 1))); + const char_t target = static_cast(std::toupper(*(p_itr - 1))); if ('*' == target) { @@ -1697,8 +1700,8 @@ namespace exprtk template static inline bool parse_inf(Iterator& itr, const Iterator end, T& t, bool negative) { - static const char inf_uc[] = "INFINITY"; - static const char inf_lc[] = "infinity"; + static const char_t inf_uc[] = "INFINITY"; + static const char_t inf_lc[] = "infinity"; static const std::size_t inf_length = 8; const std::size_t length = std::distance(itr,end); @@ -2091,6 +2094,7 @@ namespace exprtk typedef token token_t; typedef std::vector token_list_t; typedef std::vector::iterator token_list_itr_t; + typedef details::char_t char_t; generator() : base_itr_(0), @@ -2255,7 +2259,7 @@ namespace exprtk // 3. /* .... */ struct test { - static inline bool comment_start(const char c0, const char c1, int& mode, int& incr) + static inline bool comment_start(const char_t c0, const char_t c1, int& mode, int& incr) { mode = 0; if ('#' == c0) { mode = 1; incr = 1; } @@ -2267,7 +2271,7 @@ namespace exprtk return (0 != mode); } - static inline bool comment_end(const char c0, const char c1, const int mode) + static inline bool comment_end(const char_t c0, const char_t c1, const int mode) { return ( ((1 == mode) && ('\n' == c0)) || @@ -2358,15 +2362,15 @@ namespace exprtk { token_t t; - const char c0 = s_itr_[0]; + const char_t c0 = s_itr_[0]; if (!is_end(s_itr_ + 1)) { - const char c1 = s_itr_[1]; + const char_t c1 = s_itr_[1]; if (!is_end(s_itr_ + 2)) { - const char c2 = s_itr_[2]; + const char_t c2 = s_itr_[2]; if ((c0 == '<') && (c1 == '=') && (c2 == '>')) { @@ -3283,7 +3287,7 @@ namespace exprtk exprtk::details::is_bracket(t.value[0]) ) { - char c = t.value[0]; + details::char_t c = t.value[0]; if (t.type == lexer::token::e_lbracket) stack_.push(std::make_pair(')',t.position)); else if (t.type == lexer::token::e_lcrlbracket) stack_.push(std::make_pair('}',t.position)); @@ -4142,16 +4146,40 @@ namespace exprtk : v_(*reinterpret_cast(const_cast(ts).data)) {} - value_t& operator()() + inline value_t& operator()() { return v_; } - const value_t& operator()() const + inline const value_t& operator()() const { return v_; } + template + inline bool to_int(IntType& i) const + { + if (!exprtk::details::numeric::is_integer(v_)) + return false; + + i = static_cast(v_); + + return true; + } + + template + inline bool to_uint(UIntType& u) const + { + if (v_ < T(0)) + return false; + else if (!exprtk::details::numeric::is_integer(v_)) + return false; + + u = static_cast(v_); + + return true; + } + T& v_; }; }; @@ -5252,7 +5280,7 @@ namespace exprtk private: mutable vector_holder_base* vector_holder_base_; - unsigned char buffer[64]; + uchar_t buffer[64]; }; template @@ -17557,7 +17585,7 @@ namespace exprtk for (std::size_t i = error.token.position; i > 0; --i) { - const char c = expression[i]; + const details::char_t c = expression[i]; if (('\n' == c) || ('\r' == c)) { @@ -18455,12 +18483,9 @@ namespace exprtk struct parser_state { parser_state() - : parsing_return_stmt(false), - parsing_break_stmt (false), - return_stmt_present(false), - side_effect_present(false), - scope_depth(0) - {} + { + reset(); + } void reset() { @@ -21225,7 +21250,7 @@ namespace exprtk nse.type = scope_element::e_variable; nse.depth = state_.scope_depth; nse.data = new T(T(0)); - nse.var_node = new variable_node_t(*(T*)(nse.data)); + nse.var_node = node_allocator_.allocate(*(T*)(nse.data)); if (!sem_.add_element(nse)) { @@ -22429,8 +22454,8 @@ namespace exprtk for (std::size_t i = 0; i < param_seq_list_.size(); ++i) { - std::size_t diff_index = 0; - char diff_value = 0; + details::char_t diff_value = 0; + std::size_t diff_index = 0; bool result = details::sequence_match(param_seq_list_[i], param_seq, @@ -23519,7 +23544,7 @@ namespace exprtk nse.type = scope_element::e_variable; nse.depth = state_.scope_depth; nse.data = new T(T(0)); - nse.var_node = new variable_node_t(*(T*)(nse.data)); + nse.var_node = node_allocator_.allocate(*(T*)(nse.data)); if (!sem_.add_element(nse)) { @@ -23609,7 +23634,7 @@ namespace exprtk nse.depth = state_.scope_depth; nse.ip_index = sem_.next_ip_index(); nse.data = new T(T(0)); - nse.var_node = new variable_node_t(*(T*)(nse.data)); + nse.var_node = node_allocator_.allocate(*(T*)(nse.data)); if (!sem_.add_element(nse)) { @@ -26535,7 +26560,7 @@ namespace exprtk } break; - case e_st_vecelem : { + case e_st_vecelem : { typedef details::vector_holder vector_holder_t; vector_holder_t& vh = static_cast(node)->vec_holder(); diff --git a/exprtk_simple_example_18.cpp b/exprtk_simple_example_18.cpp index 4cf4b79..a6ac9e4 100644 --- a/exprtk_simple_example_18.cpp +++ b/exprtk_simple_example_18.cpp @@ -56,12 +56,12 @@ void file_io() " return [false]; " " } "; + exprtk::rtl::io::file::package fileio_package; exprtk::rtl::io::println println; - exprtk::rtl::io::file::package package; symbol_table_t symbol_table; symbol_table.add_function("println",println); - symbol_table.add_package (package); + symbol_table.add_package (fileio_package ); expression_t expression; expression.register_symbol_table(symbol_table); diff --git a/exprtk_test.cpp b/exprtk_test.cpp index 9792186..d161ca8 100644 --- a/exprtk_test.cpp +++ b/exprtk_test.cpp @@ -6336,6 +6336,132 @@ inline bool run_test18() return false; } + { + bool failure = false; + + typedef exprtk::symbol_table symbol_table_t; + typedef exprtk::expression expression_t; + typedef exprtk::parser parser_t; + + std::vector v0; + std::vector s; + + #define pb(v,N) \ + v.push_back(T(N)); \ + + pb(v0,0) pb(v0,1) pb(v0,2) pb(v0,3) pb(v0,4) + pb(v0,5) pb(v0,6) pb(v0,7) pb(v0,8) pb(v0,9) + + pb(s, 3) pb(s, 6) pb(s, 9) pb(s,12) + pb(s,15) pb(s,18) pb(s,21) + #undef pb + + const std::string expr_string = "var i := 0; var j := 1; var k := 2; v[i] + v[j] + v[k]"; + + exprtk::vector_view v = exprtk::make_vector_view(v0,4); + + symbol_table_t symbol_table; + symbol_table.add_vector("v",v); + + expression_t expression; + expression.register_symbol_table(symbol_table); + + parser_t parser; + + if (!parser.compile(expr_string,expression)) + { + printf("run_test18() - Error: %s\tExpression: %s\n", + parser.error().c_str(), + expr_string.c_str()); + + failure = true; + } + + for (std::size_t i = 0; i < v0.size() - 4; ++i) + { + v.rebase(v0.data() + i); + + T sum = expression.value(); + + if (not_equal(sum,s[i])) + { + printf("run_test18() - Error in evaluation! (8) Expression: %s Expected: %5.3f Computed: %5.3f\n", + expr_string.c_str(), + s[i], + sum); + + failure = true; + } + + } + + if (failure) + return false; + } + + { + bool failure = false; + + typedef exprtk::symbol_table symbol_table_t; + typedef exprtk::expression expression_t; + typedef exprtk::parser parser_t; + + std::vector v0; + std::vector s; + + #define pb(v,N) \ + v.push_back(T(N)); \ + + pb(v0,0) pb(v0,1) pb(v0,2) pb(v0,3) pb(v0,4) + pb(v0,5) pb(v0,6) pb(v0,7) pb(v0,8) pb(v0,9) + + pb(s, 3) pb(s, 6) pb(s, 9) pb(s,12) + pb(s,15) pb(s,18) pb(s,21) + #undef pb + + const std::string expr_string = "var i := 0; v[i + 0] + v[i + 1] + v[i + 2]"; + + exprtk::vector_view v = exprtk::make_vector_view(v0,4); + + symbol_table_t symbol_table; + symbol_table.add_vector("v",v); + + expression_t expression; + expression.register_symbol_table(symbol_table); + + parser_t parser; + + if (!parser.compile(expr_string,expression)) + { + printf("run_test18() - Error: %s\tExpression: %s\n", + parser.error().c_str(), + expr_string.c_str()); + + failure = true; + } + + for (std::size_t i = 0; i < v0.size() - 4; ++i) + { + v.rebase(v0.data() + i); + + T sum = expression.value(); + + if (not_equal(sum,s[i])) + { + printf("run_test18() - Error in evaluation! (9) Expression: %s Expected: %5.3f Computed: %5.3f\n", + expr_string.c_str(), + s[i], + sum); + + failure = true; + } + + } + + if (failure) + return false; + } + return true; }