From ef91ad59e967b07e225ca3e3d0785577f9a585de Mon Sep 17 00:00:00 2001 From: Arash Partow Date: Mon, 20 Apr 2015 22:37:52 +1000 Subject: [PATCH] C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html --- exprtk.hpp | 9 +++-- exprtk_simple_example_01.cpp | 1 + exprtk_test.cpp | 64 +++++++++++++++++++++++++++++++++--- 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/exprtk.hpp b/exprtk.hpp index c5411e7..fa85910 100644 --- a/exprtk.hpp +++ b/exprtk.hpp @@ -19539,11 +19539,16 @@ namespace exprtk { if (is_variable_node(expression_list[i])) continue; - else if (is_return_node(expression_list[i])) + else if ( + is_return_node (expression_list[i]) || + is_break_node (expression_list[i]) || + is_continue_node(expression_list[i]) + ) { tmp_expression_list.push_back(expression_list[i]); - // Remove all subexpressions after first encountered return node. + // Remove all subexpressions after first short-circuit + // node has been encountered. for (std::size_t j = i + 1; j < expression_list.size(); ++j) { diff --git a/exprtk_simple_example_01.cpp b/exprtk_simple_example_01.cpp index b4abe17..4792c87 100644 --- a/exprtk_simple_example_01.cpp +++ b/exprtk_simple_example_01.cpp @@ -29,6 +29,7 @@ void trig_function() typedef exprtk::parser parser_t; std::string expression_string = "clamp(-1.0,sin(2 * pi * x) + cos(x / 2 * pi),+1.0)"; + T x; symbol_table_t symbol_table; diff --git a/exprtk_test.cpp b/exprtk_test.cpp index bd43bf2..8880684 100644 --- a/exprtk_test.cpp +++ b/exprtk_test.cpp @@ -3955,11 +3955,30 @@ inline bool run_test10() "12 == (if (1 > 2) { var x:= 2; } else { var x[3] := {7,2,3}; sum(x); })", "12 == (if (1 < 2) { var x[3] := {7,2,3}; sum(x); } else { var x:= 2; })", "12 == (if (1 > 2) { var x:= 2; } else { var x[3] := {7,2,3}; sum(x); })", - "12 == (if (1 < 2) { var x[3] := {7,2,3}; sum(x); } else { var x:= 2; })" + "12 == (if (1 < 2) { var x[3] := {7,2,3}; sum(x); } else { var x:= 2; })", + + "21 == (for (var i := 0; i < 10; i += 1) { if (i > 2) { break [i * 7]; i += 1;" + "i += 2; i += 3; }; })", + + "21 == (for (var i := 0; i < 10; i += 1) { if (i > 2) { break [i * 7]; return " + "[i * 8]; i += 1; i += 2; i += 3; }; })", + + "2 == for (var i := 0; i < 10; i += 1) { if (i > 2) { continue; i += 1; i += 2;" + "i += 3; } else i; }", + + "2 == for (var i := 0; i < 10; i += 1) { if (i > 2) { continue; return [i * 8];" + "i += 1; i += 2; i += 3; } else i; }", + + "7 == (for (var i := 0; i < 10; i += 1) { ~{break[7]; continue; i += i} })", + "0 == (for (var i := 0; i < 10; i += 1) { ~{break[i]; continue; i += i} })", + "0 == (for (var i := 0; i < 10; i += 1) { ~{continue; break[7]; i += i} })", + "1 == (for (var i := 0; i < 10; i += 1) { ~{break[i += 1]; continue; i += i} })" }; const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string); + static const std::size_t rounds = 20; + exprtk::symbol_table symbol_table; T zero = T(0); @@ -3970,7 +3989,7 @@ inline bool run_test10() bool failed = false; - for (std::size_t r = 0; r < 10; ++r) + for (std::size_t r = 0; r < rounds; ++r) { for (std::size_t i = 0; i < expression_list_size; ++i) { @@ -3982,7 +4001,7 @@ inline bool run_test10() if (!parser.compile(expression_list[i],expression)) { - printf("run_test10() - swaps Error: %s Expression: %s\n", + printf("run_test10() - swaps[1] Error: %s Expression: %s\n", parser.error().c_str(), expression_list[i].c_str()); @@ -3995,7 +4014,44 @@ inline bool run_test10() if (T(1) != result) { - printf("run_test10() - swaps evaluation error Expression: %s\n", + printf("run_test10() - swaps[1] evaluation error Expression: %s\n", + expression_list[i].c_str()); + + failed = true; + } + } + + if (failed) + { + return false; + } + } + + // reuse parser + for (std::size_t r = 0; r < rounds; ++r) + { + exprtk::parser parser; + + for (std::size_t i = 0; i < expression_list_size; ++i) + { + expression_t expression; + expression.register_symbol_table(symbol_table); + + if (!parser.compile(expression_list[i],expression)) + { + printf("run_test10() - swaps[2] Error: %s Expression: %s\n", + parser.error().c_str(), + expression_list[i].c_str()); + + failed = true; + continue; + } + + T result = expression.value(); + + if (T(1) != result) + { + printf("run_test10() - swaps[2] evaluation error Expression: %s\n", expression_list[i].c_str()); failed = true;