From f0525af6679ea1039c71e17891e47f2317ba81d5 Mon Sep 17 00:00:00 2001 From: Arash Partow Date: Tue, 1 Jul 2014 20:46:51 +1000 Subject: [PATCH] C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html --- exprtk.hpp | 321 ++++++++++++++++++++++++----------- exprtk_simple_example_06.cpp | 8 +- exprtk_simple_example_12.cpp | 34 ++-- exprtk_simple_example_13.cpp | 60 +++---- exprtk_test.cpp | 96 ++++++----- readme.txt | 10 +- 6 files changed, 334 insertions(+), 195 deletions(-) diff --git a/exprtk.hpp b/exprtk.hpp index 4754765..af5e7fa 100644 --- a/exprtk.hpp +++ b/exprtk.hpp @@ -3278,7 +3278,9 @@ namespace exprtk e_sf4ext36 = 2036, e_sf4ext37 = 2037, e_sf4ext38 = 2038, e_sf4ext39 = 2039, e_sf4ext40 = 2040, e_sf4ext41 = 2041, e_sf4ext42 = 2042, e_sf4ext43 = 2043, e_sf4ext44 = 2044, e_sf4ext45 = 2045, e_sf4ext46 = 2046, e_sf4ext47 = 2047, - e_sf4ext48 = 2048, e_sf4ext49 = 2049 + e_sf4ext48 = 2048, e_sf4ext49 = 2049, e_sf4ext50 = 2050, e_sf4ext51 = 2051, + e_sf4ext52 = 2052, e_sf4ext53 = 2053, e_sf4ext54 = 2054, e_sf4ext55 = 2055, + e_sf4ext56 = 2056, e_sf4ext57 = 2057, e_sf4ext58 = 2058 }; struct base_operation_t @@ -5953,16 +5955,25 @@ namespace exprtk template struct sfext37_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x / y) / (z - w); } static inline std::string id() { return "(t/t)/(t-t)";} }; template struct sfext38_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x * y) * (z - w); } static inline std::string id() { return "(t*t)*(t-t)";} }; template struct sfext39_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x * y) / (z * w); } static inline std::string id() { return "(t*t)/(t*t)";} }; - template struct sfext40_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x / y) * (z - w); } static inline std::string id() { return "(t/t)*(t-t)";} }; - template struct sfext41_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x * y) * (z * w); } static inline std::string id() { return "(t*t)*(t*t)";} }; - template struct sfext42_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return x + (y * (z / w)); } static inline std::string id() { return "t+(t*(t/t))";} }; - template struct sfext43_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return x - (y * (z / w)); } static inline std::string id() { return "t-(t*(t/t))";} }; - template struct sfext44_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return x + (y / (z * w)); } static inline std::string id() { return "t+(t/(t*t))";} }; - template struct sfext45_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return x - (y / (z * w)); } static inline std::string id() { return "t-(t/(t*t))";} }; - template struct sfext46_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return ((x - y) - z) * w; } static inline std::string id() { return "((t-t)-t)*t";} }; - template struct sfext47_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return ((x - y) - z) / w; } static inline std::string id() { return "((t-t)-t)/t";} }; - template struct sfext48_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return ((x - y) + z) * w; } static inline std::string id() { return "((t-t)+t)*t";} }; - template struct sfext49_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return ((x - y) + z) / w; } static inline std::string id() { return "((t-t)+t)/t";} }; + template struct sfext40_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x / y) * (z / w); } static inline std::string id() { return "(t/t)*(t/t)";} }; + template struct sfext41_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x / y) * (z - w); } static inline std::string id() { return "(t/t)*(t-t)";} }; + template struct sfext42_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x * y) * (z * w); } static inline std::string id() { return "(t*t)*(t*t)";} }; + template struct sfext43_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return x + (y * (z / w)); } static inline std::string id() { return "t+(t*(t/t))";} }; + template struct sfext44_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return x - (y * (z / w)); } static inline std::string id() { return "t-(t*(t/t))";} }; + template struct sfext45_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return x + (y / (z * w)); } static inline std::string id() { return "t+(t/(t*t))";} }; + template struct sfext46_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return x - (y / (z * w)); } static inline std::string id() { return "t-(t/(t*t))";} }; + template struct sfext47_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return ((x - y) - z) * w; } static inline std::string id() { return "((t-t)-t)*t";} }; + template struct sfext48_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return ((x - y) - z) / w; } static inline std::string id() { return "((t-t)-t)/t";} }; + template struct sfext49_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return ((x - y) + z) * w; } static inline std::string id() { return "((t-t)+t)*t";} }; + template struct sfext50_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return ((x - y) + z) / w; } static inline std::string id() { return "((t-t)+t)/t";} }; + template struct sfext51_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x + (y - z)) * w; } static inline std::string id() { return "(t+(t-t))*t";} }; + template struct sfext52_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x + (y - z)) / w; } static inline std::string id() { return "(t+(t-t))/t";} }; + template struct sfext53_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x + y) / (z + w); } static inline std::string id() { return "(t+t)/(t+t)";} }; + template struct sfext54_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x - y) / (z - w); } static inline std::string id() { return "(t-t)/(t-t)";} }; + template struct sfext55_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x + y) * (z + w); } static inline std::string id() { return "(t+t)*(t+t)";} }; + template struct sfext56_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x - y) * (z - w); } static inline std::string id() { return "(t-t)*(t-t)";} }; + template struct sfext57_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x - y) + (z - w); } static inline std::string id() { return "(t-t)+(t-t)";} }; + template struct sfext58_op : public sf_base { typedef typename sf_base::Type Type; static inline T process(Type x, Type y, Type z, Type w) { return (x - y) - (z - w); } static inline std::string id() { return "(t-t)-(t-t)";} }; template class sf3_node : public trinary_node @@ -14523,72 +14534,80 @@ namespace exprtk if (!token_is(token_t::e_eof)) { - if (!token_is(token_t::e_symbol,false)) + if ( + !token_is(token_t::e_symbol,false) && + details::imatch(current_token_.value,"var") + ) { - set_error( - make_error(parser_error::e_syntax, - current_token_, - "ERR52 - Expected a variable at the start of initialiser section of for-loop")); + next_token(); - return error_node(); - } - else if (!peek_token_is(token_t::e_assign)) - { - set_error( - make_error(parser_error::e_syntax, - current_token_, - "ERR53 - Expected variable assignment of initialiser section of for-loop")); - - return error_node(); - } - - loop_counter_symbol = current_token_.value; - - se = &sem_.get_element(loop_counter_symbol); - - if ((se->name == loop_counter_symbol) && se->active) - { - set_error( - make_error(parser_error::e_syntax, - current_token_, - "ERR54 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration")); - - return error_node(); - } - else if (!symbol_table_.is_variable(loop_counter_symbol)) - { - if ( - !se->active && - (se->name == loop_counter_symbol) && - (se->type == scope_element::e_variable) - ) + if (!token_is(token_t::e_symbol,false)) { - se->active = true; - se->ref_count++; + set_error( + make_error(parser_error::e_syntax, + current_token_, + "ERR52 - Expected a variable at the start of initialiser section of for-loop")); + + return error_node(); } - else + else if (!peek_token_is(token_t::e_assign)) { - scope_element nse; - nse.name = loop_counter_symbol; - nse.type = scope_element::e_variable; - nse.depth = scope_depth_; - nse.data = new T(T(0)); - nse.var_node = new variable_node_t(*(T*)(nse.data)); + set_error( + make_error(parser_error::e_syntax, + current_token_, + "ERR53 - Expected variable assignment of initialiser section of for-loop")); - if (!sem_.add_element(nse)) + return error_node(); + } + + loop_counter_symbol = current_token_.value; + + se = &sem_.get_element(loop_counter_symbol); + + if ((se->name == loop_counter_symbol) && se->active) + { + set_error( + make_error(parser_error::e_syntax, + current_token_, + "ERR54 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration")); + + return error_node(); + } + else if (!symbol_table_.is_variable(loop_counter_symbol)) + { + if ( + !se->active && + (se->name == loop_counter_symbol) && + (se->type == scope_element::e_variable) + ) { - set_error( - make_error(parser_error::e_syntax, - current_token_, - "ERR55 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM")); - - result = false; - + se->active = true; + se->ref_count++; } - #ifdef exprtk_enable_debugging else - printf("parse_for_loop() - INFO - Added new local variable: %s\n",nse.name.c_str()); - #endif + { + scope_element nse; + nse.name = loop_counter_symbol; + nse.type = scope_element::e_variable; + nse.depth = scope_depth_; + nse.data = new T(T(0)); + nse.var_node = new variable_node_t(*(T*)(nse.data)); + + if (!sem_.add_element(nse)) + { + set_error( + make_error(parser_error::e_syntax, + current_token_, + "ERR55 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM")); + + result = false; + + } + #ifdef exprtk_enable_debugging + else + printf("parse_for_loop() - INFO - Added new local variable: %s\n",nse.name.c_str()); + #endif + } } } @@ -14666,7 +14685,11 @@ namespace exprtk if (!result) { - se->ref_count--; + if (se) + { + se->ref_count--; + } + sem_.cleanup(); free_node(node_allocator_,initialiser); free_node(node_allocator_,condition ); @@ -19160,6 +19183,11 @@ namespace exprtk case_stmt(details::e_sf4ext44,details::sfext44_op) case_stmt(details::e_sf4ext45,details::sfext45_op) case_stmt(details::e_sf4ext46,details::sfext46_op) case_stmt(details::e_sf4ext47,details::sfext47_op) case_stmt(details::e_sf4ext48,details::sfext48_op) case_stmt(details::e_sf4ext49,details::sfext49_op) + case_stmt(details::e_sf4ext50,details::sfext50_op) case_stmt(details::e_sf4ext51,details::sfext51_op) + case_stmt(details::e_sf4ext52,details::sfext52_op) case_stmt(details::e_sf4ext53,details::sfext53_op) + case_stmt(details::e_sf4ext54,details::sfext54_op) case_stmt(details::e_sf4ext55,details::sfext55_op) + case_stmt(details::e_sf4ext56,details::sfext56_op) case_stmt(details::e_sf4ext57,details::sfext57_op) + case_stmt(details::e_sf4ext58,details::sfext58_op) #undef case_stmt default : return error_node(); @@ -20114,7 +20142,7 @@ namespace exprtk return (synthesis_result) ? result : error_node(); } // (v0 / v1) / (v2 / v3) --> (vovovov) (v0 * v3) / (v1 * v2) - if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) + else if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) { const bool synthesis_result = synthesize_sf4ext_expression:: @@ -20171,6 +20199,27 @@ namespace exprtk details::free_node(*(expr_gen.node_allocator_),branch[0]); details::free_node(*(expr_gen.node_allocator_),branch[1]); expression_node_ptr result = error_node(); + + if (expr_gen.strength_reduction_enabled()) + { + // (v0 / v1) * (v2 / c) --> (vovovoc) (v0 * v2) / (v1 * c) + if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) + { + const bool synthesis_result = + synthesize_sf4ext_expression:: + template compile(expr_gen,"(t*t)/(t*t)",v0,v2,v1,c,result); + return (synthesis_result) ? result : error_node(); + } + // (v0 / v1) / (v2 / c) --> (vocovov) (v0 * c) / (v1 * v2) + if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) + { + const bool synthesis_result = + synthesize_sf4ext_expression:: + template compile(expr_gen,"(t*t)/(t*t)",v0,c,v1,v2,result); + return (synthesis_result) ? result : error_node(); + } + } + if (synthesize_sf4ext_expression::template compile(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,v2,c,result)) return result; else if (!expr_gen.valid_operator(o0,f0)) @@ -20220,6 +20269,27 @@ namespace exprtk details::free_node(*(expr_gen.node_allocator_),branch[0]); details::free_node(*(expr_gen.node_allocator_),branch[1]); expression_node_ptr result = error_node(); + + if (expr_gen.strength_reduction_enabled()) + { + // (v0 / v1) * (c / v2) --> (vocovov) (v0 * c) / (v1 * v2) + if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) + { + const bool synthesis_result = + synthesize_sf4ext_expression:: + template compile(expr_gen,"(t*t)/(t*t)",v0,c,v1,v2,result); + return (synthesis_result) ? result : error_node(); + } + // (v0 / v1) / (c / v2) --> (vovovoc) (v0 * v2) / (v1 * c) + if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) + { + const bool synthesis_result = + synthesize_sf4ext_expression:: + template compile(expr_gen,"(t*t)/(t*t)",v0,v2,v1,c,result); + return (synthesis_result) ? result : error_node(); + } + } + if (synthesize_sf4ext_expression::template compile(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,c,v2,result)) return result; else if (!expr_gen.valid_operator(o0,f0)) @@ -20269,6 +20339,27 @@ namespace exprtk details::free_node(*(expr_gen.node_allocator_),branch[0]); details::free_node(*(expr_gen.node_allocator_),branch[1]); expression_node_ptr result = error_node(); + + if (expr_gen.strength_reduction_enabled()) + { + // (v0 / c) * (v1 / v2) --> (vovocov) (v0 * v1) / (c * v2) + if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) + { + const bool synthesis_result = + synthesize_sf4ext_expression:: + template compile(expr_gen,"(t*t)/(t*t)",v0,v1,c,v2,result); + return (synthesis_result) ? result : error_node(); + } + // (v0 / c) / (v1 / v2) --> (vovocov) (v0 * v2) / (c * v1) + if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) + { + const bool synthesis_result = + synthesize_sf4ext_expression:: + template compile(expr_gen,"(t*t)/(t*t)",v0,v2,c,v1,result); + return (synthesis_result) ? result : error_node(); + } + } + if (synthesize_sf4ext_expression::template compile(expr_gen,id(expr_gen,o0,o1,o2),v0,c,v1,v2,result)) return result; else if (!expr_gen.valid_operator(o0,f0)) @@ -20318,6 +20409,27 @@ namespace exprtk details::free_node(*(expr_gen.node_allocator_),branch[0]); details::free_node(*(expr_gen.node_allocator_),branch[1]); expression_node_ptr result = error_node(); + + if (expr_gen.strength_reduction_enabled()) + { + // (c / v0) * (v1 / v2) --> (covovov) (c * v1) / (v0 * v2) + if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_div == o2)) + { + const bool synthesis_result = + synthesize_sf4ext_expression:: + template compile(expr_gen,"(t*t)/(t*t)",c,v1,v0,v2,result); + return (synthesis_result) ? result : error_node(); + } + // (c / v0) / (v1 / v2) --> (covovov) (c * v2) / (v0 * v1) + if ((details::e_div == o0) && (details::e_div == o1) && (details::e_div == o2)) + { + const bool synthesis_result = + synthesize_sf4ext_expression:: + template compile(expr_gen,"(t*t)/(t*t)",c,v2,v0,v1,result); + return (synthesis_result) ? result : error_node(); + } + } + if (synthesize_sf4ext_expression::template compile(expr_gen,id(expr_gen,o0,o1,o2),c,v0,v1,v2,result)) return result; else if (!expr_gen.valid_operator(o0,f0)) @@ -20576,6 +20688,22 @@ namespace exprtk template compile(expr_gen,"t*(t/t)",Type(1) / (c0 * c1),v0,v1,result); return (synthesis_result) ? result : error_node(); } + // (v0 / c0) * (v1 + c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 + c1) + else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_add == o2)) + { + const bool synthesis_result = + synthesize_sf4ext_expression:: + template compile(expr_gen,"(t*t)*(t+t)",v0,T(1) / c0,v1,c1,result); + return (synthesis_result) ? result : error_node(); + } + // (v0 / c0) * (v1 - c1) --> (vocovoc) (v0 * (1 / c0)) * (v1 - c1) + else if ((details::e_div == o0) && (details::e_mul == o1) && (details::e_sub == o2)) + { + const bool synthesis_result = + synthesize_sf4ext_expression:: + template compile(expr_gen,"(t*t)*(t-t)",v0,T(1) / c0,v1,c1,result); + return (synthesis_result) ? result : error_node(); + } // (v0 * c) +/- (v1 * c) --> (covov) c * (v0 +/- v1) else if ( (c0 == c1) && @@ -22563,7 +22691,7 @@ namespace exprtk { std::string& s0 = static_cast*>(branch[0])->ref(); std::string& s1 = static_cast*>(branch[1])->ref(); - range_pack rp0 = static_cast*>(branch[0])->range(); + range_pack rp0 = static_cast*>(branch[0])->range(); static_cast*>(branch[0])->range_ref().clear(); free_node(*node_allocator_,branch[0]); return synthesize_str_xrox_expression_impl(opr,s0,s1,rp0); @@ -22572,8 +22700,8 @@ namespace exprtk inline expression_node_ptr synthesize_sosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) { std::string& s0 = static_cast*>(branch[0])->ref(); - std::string& s1 = static_cast*>(branch[1])->ref(); - range_pack rp1 = static_cast*>(branch[1])->range(); + std::string& s1 = static_cast*>(branch[1])->ref (); + range_pack rp1 = static_cast*>(branch[1])->range(); static_cast*>(branch[1])->range_ref().clear(); free_node(*node_allocator_,branch[1]); return synthesize_str_xoxr_expression_impl(opr,s0,s1,rp1); @@ -22582,8 +22710,8 @@ namespace exprtk inline expression_node_ptr synthesize_socsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) { std::string& s0 = static_cast*>(branch[0])->ref(); - std::string s1 = static_cast*>(branch[1])->str(); - range_pack rp1 = static_cast*>(branch[1])->range(); + std::string s1 = static_cast*>(branch[1])->str (); + range_pack rp1 = static_cast*>(branch[1])->range(); static_cast*>(branch[1])->range_ref().clear(); free_node(*node_allocator_,branch[1]); return synthesize_str_xoxr_expression_impl(opr,s0,s1,rp1); @@ -22591,10 +22719,10 @@ namespace exprtk inline expression_node_ptr synthesize_srosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) { - std::string& s0 = static_cast*>(branch[0])->ref(); - std::string& s1 = static_cast*>(branch[1])->ref(); - range_pack rp0 = static_cast*>(branch[0])->range(); - range_pack rp1 = static_cast*>(branch[1])->range(); + std::string& s0 = static_cast*>(branch[0])->ref (); + std::string& s1 = static_cast*>(branch[1])->ref (); + range_pack rp0 = static_cast*>(branch[0])->range(); + range_pack rp1 = static_cast*>(branch[1])->range(); static_cast*>(branch[0])->range_ref().clear(); static_cast*>(branch[1])->range_ref().clear(); details::free_node(*node_allocator_,branch[0]); @@ -22620,9 +22748,9 @@ namespace exprtk inline expression_node_ptr synthesize_csosr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) { - std::string s0 = static_cast*> (branch[0])->str(); - std::string& s1 = static_cast*>(branch[1])->ref(); - range_pack rp1 = static_cast*>(branch[1])->range(); + std::string s0 = static_cast*> (branch[0])->str (); + std::string& s1 = static_cast*>(branch[1])->ref (); + range_pack rp1 = static_cast*>(branch[1])->range(); static_cast*>(branch[1])->range_ref().clear(); details::free_node(*node_allocator_,branch[0]); details::free_node(*node_allocator_,branch[1]); @@ -22631,9 +22759,9 @@ namespace exprtk inline expression_node_ptr synthesize_srocs_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) { - std::string& s0 = static_cast*>(branch[0])->ref(); - std::string s1 = static_cast*> (branch[1])->str(); - range_pack rp0 = static_cast*>(branch[0])->range(); + std::string& s0 = static_cast*>(branch[0])->ref (); + std::string s1 = static_cast*> (branch[1])->str (); + range_pack rp0 = static_cast*>(branch[0])->range(); static_cast*>(branch[0])->range_ref().clear(); details::free_node(*node_allocator_,branch[0]); details::free_node(*node_allocator_,branch[1]); @@ -22642,10 +22770,10 @@ namespace exprtk inline expression_node_ptr synthesize_srocsr_expression(const details::operator_type& opr, expression_node_ptr (&branch)[2]) { - std::string& s0 = static_cast*> (branch[0])->ref(); - std::string s1 = static_cast*>(branch[1])->str(); - range_pack rp0 = static_cast*> (branch[0])->range(); - range_pack rp1 = static_cast*>(branch[1])->range(); + std::string& s0 = static_cast*> (branch[0])->ref (); + std::string s1 = static_cast*>(branch[1])->str (); + range_pack rp0 = static_cast*> (branch[0])->range(); + range_pack rp1 = static_cast*>(branch[1])->range(); static_cast*> (branch[0])->range_ref().clear(); static_cast*>(branch[1])->range_ref().clear(); details::free_node(*node_allocator_,branch[0]); @@ -23254,7 +23382,9 @@ namespace exprtk register_sf4ext(36) register_sf4ext(36) register_sf4ext(38) register_sf4ext(39) register_sf4ext(40) register_sf4ext(41) register_sf4ext(42) register_sf4ext(43) register_sf4ext(44) register_sf4ext(45) register_sf4ext(46) register_sf4ext(47) - register_sf4ext(48) register_sf4ext(49) + register_sf4ext(48) register_sf4ext(49) register_sf4ext(50) register_sf4ext(51) + register_sf4ext(52) register_sf4ext(53) register_sf4ext(54) register_sf4ext(55) + register_sf4ext(56) register_sf4ext(57) register_sf4ext(58) #undef register_sf4ext } @@ -24061,6 +24191,7 @@ namespace exprtk const std::size_t n = var_list.size(); std::vector v(n,0); std::vector sv(n); + if (expr_map_.end() != expr_map_.find(name)) return false; else if (!forward(name,n)) @@ -24071,11 +24202,7 @@ namespace exprtk { if (!add_variable(var_list[i],v[i],sv[i])) { - for (std::size_t j = 0; j <= i; ++j) - { - delete v[j]; - } - remove(name,n); + remove(name,sv); return false; } else @@ -24090,10 +24217,6 @@ namespace exprtk else { remove(name,sv); - for (std::size_t i = 0; i < v.size(); ++i) - { - delete v[i]; - } return false; } } diff --git a/exprtk_simple_example_06.cpp b/exprtk_simple_example_06.cpp index dae66b3..2a126e2 100644 --- a/exprtk_simple_example_06.cpp +++ b/exprtk_simple_example_06.cpp @@ -29,10 +29,10 @@ void vector_function() typedef exprtk::parser parser_t; std::string expression_string = - " for (i := 0; i < min(x[],y[],z[]); i += 1) " - " { " - " z[i] := 3sin(x[i]) + 2log(y[i]); " - " } "; + " for (var i := 0; i < min(x[],y[],z[]); i += 1) " + " { " + " z[i] := 3sin(x[i]) + 2log(y[i]); " + " } "; T x[] = { T(1.1), T(2.2), T(3.3), T(4.4), T(5.5) }; T y[] = { T(1.1), T(2.2), T(3.3), T(4.4), T(5.5) }; diff --git a/exprtk_simple_example_12.cpp b/exprtk_simple_example_12.cpp index 8aedf10..d7a90f8 100644 --- a/exprtk_simple_example_12.cpp +++ b/exprtk_simple_example_12.cpp @@ -29,23 +29,23 @@ void bubble_sort() typedef exprtk::parser parser_t; std::string bubblesort_program = - " var upper_bound := v[]; " - " var swapped := false; " - " repeat " - " swapped := false; " - " for(i := 0; i < upper_bound; i += 1) " - " { " - " for(j := i + 1; j < upper_bound; j += 1) " - " { " - " if (v[i] > v[j]) " - " { " - " v[i] <=> v[j]; " - " swapped := true; " - " }; " - " }; " - " }; " - " upper_bound -= 1; " - " until (not(swapped) or (upper_bound == 0)); "; + " var upper_bound := v[]; " + " var swapped := false; " + " repeat " + " swapped := false; " + " for(var i := 0; i < upper_bound; i += 1) " + " { " + " for(var j := i + 1; j < upper_bound; j += 1) " + " { " + " if (v[i] > v[j]) " + " { " + " v[i] <=> v[j]; " + " swapped := true; " + " }; " + " }; " + " }; " + " upper_bound -= 1; " + " until (not(swapped) or (upper_bound == 0)); "; T v[] = { T(2.2), T(1.1), T(5.5), T(4.4), T(3.3) }; diff --git a/exprtk_simple_example_13.cpp b/exprtk_simple_example_13.cpp index 59e7c82..69b4523 100644 --- a/exprtk_simple_example_13.cpp +++ b/exprtk_simple_example_13.cpp @@ -31,36 +31,36 @@ void savitzky_golay_filter() typedef exprtk::parser parser_t; std::string sgfilter_program = - " var weight[9] := " - " { " - " -21, 14, 39, " - " 54, 59, 54, " - " 39, 14, -21 " - " }; " - " " - " if (v_in[] >= weight[]) " - " { " - " var lower_bound := trunc(weight[] / 2); " - " var upper_bound := v_in[] - lower_bound; " - " " - " v_out := 0; " - " " - " for (i := lower_bound; i < upper_bound; i += 1) " - " { " - " for (j := -lower_bound; j <= lower_bound; j += 1) " - " { " - " v_out[i] += weight[j + lower_bound] * v_in[i + j]; " - " }; " - " }; " - " " - " v_out /= sum(weight); " - " " - " for (i := 0; i < lower_bound; i += 1) " - " { " - " v_out[i] := 0; " - " v_out[v_out[] - i - 1] := 0; " - " }; " - " } "; + " var weight[9] := " + " { " + " -21, 14, 39, " + " 54, 59, 54, " + " 39, 14, -21 " + " }; " + " " + " if (v_in[] >= weight[]) " + " { " + " var lower_bound := trunc(weight[] / 2); " + " var upper_bound := v_in[] - lower_bound; " + " " + " v_out := 0; " + " " + " for (var i := lower_bound; i < upper_bound; i += 1) " + " { " + " for (var j := -lower_bound; j <= lower_bound; j += 1) " + " { " + " v_out[i] += weight[j + lower_bound] * v_in[i + j]; " + " }; " + " }; " + " " + " v_out /= sum(weight); " + " " + " for (var i := 0; i < lower_bound; i += 1) " + " { " + " v_out[i] := 0; " + " v_out[v_out[] - i - 1] := 0; " + " }; " + " } "; const std::size_t n = 1024; diff --git a/exprtk_test.cpp b/exprtk_test.cpp index 0355c26..f1dcd54 100644 --- a/exprtk_test.cpp +++ b/exprtk_test.cpp @@ -1524,11 +1524,11 @@ inline bool run_test01() test_xy("(x *= 2y) == 6 " ,T(1),T(3),T(1)), test_xy("(x /= 2 ) == (1/2)" ,T(1),T(3),T(1)), test_xy("(x /= 2y) == (1/6)" ,T(1),T(3),T(1)), - test_xy("for(i := 0; (i < 10);) { i += 1; }; x;" ,T(1),T(20),T( 1)), - test_xy("for(i := 0; (i < 10) and (i != y); i+=2) { x += i; }; x;" ,T(1),T(20),T(21)), - test_xy("for(i := 0; (i < 10) and (i != y);) { x += i; i+=2; }; x;",T(1),T(20),T(21)), - test_xy("for(i := 0; (i < y); i += 1) { if (i <= (y / 2)) x += i; else break; }; x;" ,T(0),T(10),T(15)), - test_xy("for(i := 0; (i < y); i += 1) { if (i <= (y / 2)) continue; else x += i; }; x;" ,T(0),T(10),T(30)) + test_xy("for(var i := 0; (i < 10);) { i += 1; }; x;" ,T(1),T(20),T( 1)), + test_xy("for(var i := 0; (i < 10) and (i != y); i+=2) { x += i; }; x;" ,T(1),T(20),T(21)), + test_xy("for(var i := 0; (i < 10) and (i != y);) { x += i; i+=2; }; x;",T(1),T(20),T(21)), + test_xy("for(var i := 0; (i < y); i += 1) { if (i <= (y / 2)) x += i; else break; }; x;" ,T(0),T(10),T(15)), + test_xy("for(var i := 0; (i < y); i += 1) { if (i <= (y / 2)) continue; else x += i; }; x;" ,T(0),T(10),T(30)) }; static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_xy); @@ -3281,6 +3281,22 @@ inline bool run_test10() { std::string expression_list[] = { + "var x:=6; var y:=4; x + -3 == 3", + "var x:=6; var y:=4; x - -3 == 9", + "var x:=6; var y:=4; x * -3 == -18", + "var x:=6; var y:=4; x / -3 == -2", + "var x:=6; var y:=4; -x + -3 == -9", + "var x:=6; var y:=4; -x - -3 == -3", + "var x:=6; var y:=4; -x * -3 == 18", + "var x:=6; var y:=4; -x / -3 == 2", + "var x:=6; var y:=4; -3 + -x == -9", + "var x:=6; var y:=4; -3 - -x == 3", + "var x:=6; var y:=4; -3 * -x == 18", + "var x:=6; var y:=4; -3 / -x == 0.5", + "var x:=6; var y:=4; 3 + -x == -3", + "var x:=6; var y:=4; 3 - -x == 9", + "var x:=6; var y:=4; 3 * -x == -18", + "var x:=6; var y:=4; 3 / -x == -0.5", "var x := 3; var y := 6; x + -y == -3", "var x := 3; var y := 6; x - -y == 9", "var x := 3; var y := 6; -x + -y == -9", @@ -3444,20 +3460,20 @@ inline bool run_test10() "var x[3] := {-1,-2,-3}; sum(abs(x) ) == 6", "var x[3] := {0.1,0.2,0.3}; sum(trunc(x)) == 0", - "var x := 2; (~{ for (i := 0; i < 10; i += 1) { for (j := 0; j <= i;" - "j += 1) { var y := 3; if ((i + j + y + x) < 6) { y += x; continue; " - "} else break[i + j]; } } } + ~{ for (i := 0; i < 10; i += 1) { for " - "(j := 0; j <= i; j += 1) { var y := 3; if ((i + j + y + x) < 6) { " - "y += x; continue; } else break[i + j]; } } }) == 18 ", + "var x := 2; (~{ for (var i := 0; i < 10; i += 1) { for (var j := 0; j <= i; " + "j += 1) { var y := 3; if ((i + j + y + x) < 6) { y += x; continue; } else " + "break[i + j]; } } } + ~{ for (var i := 0; i < 10; i += 1) { for (var j := 0; " + "j <= i; j += 1) { var y := 3; if ((i + j + y + x) < 6) { y += x; continue; } " + " else break[i + j]; } } }) == 18 ", - "var x := 2; var v0[3] := {1,2,3}; ( ~{ for (i := 0; i < 10; i += 1) { " - "for (j := 0; j <= i; j += 1) { var y := 3; var v2[3] := {1,2,3}; if ( " - "(i + j + y + x + abs(v0[i % v0[]] - v2[j % v2[]])) < 6) { var v3[3] :=" - "{1,2,3}; y += x / v3[j % v3[]]; continue; } else break[i + j]; } } } " - "+ ~{ for (i := 0; i < 10; i += 1) { for (j := 0; j <= i; j += 1) { var" - " y := 3; var v2[3] := {1,2,3}; if ((i + j + y + x + abs(v0[i % v0[]] -" - "v2[j % v2[]])) < 6) { var v3[3] := {1,2,3}; y += x / v3[j % v3[]]; " - "continue; } else break[i + j]; } } } ) == 18 " + "var x := 2; var v0[3] := {1,2,3}; ( ~{ for (var i := 0; i < 10; i += 1) { " + "for (var j := 0; j <= i; j += 1) { var y := 3; var v2[3] := {1,2,3}; if ( " + "(i + j + y + x + abs(v0[i % v0[]] - v2[j % v2[]])) < 6) { var v3[3] := " + "{1,2,3}; y += x / v3[j % v3[]]; continue; } else break[i + j]; } } } " + "+ ~{ for (var i := 0; i < 10; i += 1) { for (var j := 0; j <= i; j += 1) " + " { var y := 3; var v2[3] := {1,2,3}; if ((i + j + y + x + abs(v0[i % v0[]] - " + "v2[j % v2[]])) < 6) { var v3[3] := {1,2,3}; y += x / v3[j % v3[]]; " + "continue; } else break[i + j]; } } } ) == 18 " }; const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string); @@ -4593,25 +4609,25 @@ inline bool run_test19() compositor .add("is_prime_impl4", - "switch " - "{ " - " case 1 == x : false; " - " case 2 == x : true; " - " case 3 == x : true; " - " case 5 == x : true; " - " case 7 == x : true; " - " case 0 == x % 2 : false; " - " default : " - " { " - " for (i := 3; i < y; i += 2) " - " { " - " if ((x % i) == 0) " - " break[false]; " - " else " - " true; " - " } " - " }; " - "} ", + "switch " + "{ " + " case 1 == x : false; " + " case 2 == x : true; " + " case 3 == x : true; " + " case 5 == x : true; " + " case 7 == x : true; " + " case 0 == x % 2 : false; " + " default : " + " { " + " for (var i := 3; i < y; i += 2) " + " { " + " if ((x % i) == 0) " + " break[false]; " + " else " + " true; " + " } " + " }; " + "} ", "x","y"); compositor @@ -5000,16 +5016,16 @@ inline bool run_test19() " var real_min := -2.5; " " var x_step := (real_max - real_min) / width; " " var y_step := (imag_max - imag_min) / height; " - " for (y := 0; y < height; y += 1) " + " for (var y := 0; y < height; y += 1) " " { " " var imag := imag_min + (y_step * y); " - " for (x := 0; x < width; x += 1) " + " for (var x := 0; x < width; x += 1) " " { " " var real := real_min + x_step * x; " " var z_real := real; " " var z_imag := imag; " " var plot_value; " - " for (n := 0; n < 30; n += 1) " + " for (var n := 0; n < 30; n += 1) " " { " " var a := z_real^2; " " var b := z_imag^2; " diff --git a/readme.txt b/readme.txt index 26c9a10..44500ee 100644 --- a/readme.txt +++ b/readme.txt @@ -474,7 +474,7 @@ of C++ compilers: | | The conditional is mandatory whereas the initializer | | | and incrementing expressions are optional. | | | eg: | -| | for (x := 0; (x < n) and (x != y); x += 1) | +| | for (var x := 0; (x < n) and (x != y); x += 1) | | | { | | | y := y + x / 2 - z; | | | w := u + y; | @@ -500,7 +500,7 @@ of C++ compilers: | continue | Continue results in the remaining portion of the nearest| | | enclosing loop body to be skipped. | | | eg: | -| | for (i := 0; i < 10; i += 1) | +| | for (var i := 0; i < 10; i += 1) | | | { | | | if (i < 5) | | | continue; | @@ -619,7 +619,7 @@ current values assigned to the variables will be used. expression.value(); // 3.7 * -9 + 3 // 'x * -9 + 3' for x in range of [0,100] in steps of 0.0001 - for (x = 0; x < 100; x += 0.0001) + for (var x = 0; x < 100; x += 0.0001) { expression.value(); // x * -9 + 3 } @@ -962,7 +962,7 @@ the previously mentioned dot-product computation expression: var v1[3] := {4,5,6}; var v0dotv1; - for (i := 0; i < min(v0[],v1[]); i += 1) + for (var i := 0; i < min(v0[],v1[]); i += 1) { v0dotv1 += (v0[i] * v1[i]); } @@ -1413,7 +1413,7 @@ in a compilation failure. | | | | +-----------------------<------------------------+ | | | | -| +--> [,] -+-> [condition] -+-> [,] ---+ | +| +--> [;] -+-> [condition] -+-> [;] ---+ | | | | | | | +------->--------+ v | | | |