diff --git a/exprtk.hpp b/exprtk.hpp index 3f49ae5..9faebf0 100644 --- a/exprtk.hpp +++ b/exprtk.hpp @@ -10290,10 +10290,12 @@ namespace exprtk typedef expression_node* expression_ptr; typedef results_context results_context_t; - return_envelope_node(expression_ptr body, results_context_t& rc) + return_envelope_node(expression_ptr body, + results_context_t& rc, bool& rtrn_invoked) : results_context_(&rc), - body_(body), - body_deletable_(branch_deletable(body_)) + return_invoked_ (rtrn_invoked), + body_ (body), + body_deletable_ (branch_deletable(body_)) {} ~return_envelope_node() @@ -10308,12 +10310,14 @@ namespace exprtk { try { + return_invoked_ = false; results_context_->clear(); return body_->value(); } catch(const return_exception&) { + return_invoked_ = true; return std::numeric_limits::quiet_NaN(); } } @@ -10326,6 +10330,7 @@ namespace exprtk private: results_context_t* results_context_; + bool& return_invoked_; expression_ptr body_; bool body_deletable_; }; @@ -13598,6 +13603,13 @@ namespace exprtk return new node_type(t1,t2); } + template + inline expression_node* allocate_crr(const T1& t1, T2& t2, T3& t3) const + { + return new node_type(t1,t2,t3); + } + template inline expression_node* allocate_rc(T1& t1, const T2& t2) const @@ -15411,14 +15423,16 @@ namespace exprtk expression_holder() : ref_count(0), - expr(0), - results_(0) + expr (0), + results (0), + return_invoked(false) {} expression_holder(expression_ptr e) : ref_count(1), - expr(e), - results_(0) + expr (e), + results (0), + return_invoked(false) {} ~expression_holder() @@ -15454,16 +15468,17 @@ namespace exprtk } } - if (results_) + if (results) { - delete results_; + delete results; } } std::size_t ref_count; expression_ptr expr; local_data_list_t local_data_list; - results_context_t* results_; + results_context_t* results; + bool return_invoked; friend class function_compositor; }; @@ -15583,8 +15598,8 @@ namespace exprtk inline const results_context_t& results() const { - if (expression_holder_->results_) - return (*expression_holder_->results_); + if (expression_holder_->results) + return (*expression_holder_->results); else { static const results_context_t null_results; @@ -15592,6 +15607,11 @@ namespace exprtk } } + inline bool return_invoked() const + { + return (expression_holder_->return_invoked); + } + private: inline symtab_list_t get_symbol_table_list() const @@ -15685,10 +15705,15 @@ namespace exprtk { if (rc) { - expression_holder_->results_ = rc; + expression_holder_->results = rc; } } + inline bool& rtrn_invk_ref() + { + return expression_holder_->return_invoked; + } + expression_holder* expression_holder_; symtab_list_t symbol_table_list_; @@ -16780,7 +16805,8 @@ namespace exprtk : options_(options), collect_variables_ ((options_ & e_ct_variables ) == e_ct_variables ), collect_functions_ ((options_ & e_ct_functions ) == e_ct_functions ), - collect_assignments_((options_ & e_ct_assignments) == e_ct_assignments) + collect_assignments_((options_ & e_ct_assignments) == e_ct_assignments), + return_present_(false) {} template alloc_type; - return node_allocator_->allocate_cr(body,(*rc)); + return node_allocator_->allocate_crr(body,(*rc),return_invoked); } inline expression_node_ptr vector_element(const std::string& symbol, diff --git a/exprtk_test.cpp b/exprtk_test.cpp index 950a063..58521f2 100644 --- a/exprtk_test.cpp +++ b/exprtk_test.cpp @@ -6774,12 +6774,28 @@ inline bool run_test21() failure = true; continue; } + else if (!parser.dec().return_present()) + { + printf("run_test21() - Expected a return statement Expression: %s [1]\n", + expression_list[i].c_str()); + + failure = true; + continue; + } expression.value(); std::string pattern = results_to_string(expression.results()); - if (result_list[i] != pattern) + if (!expression.return_invoked()) + { + printf("run_test21() - Invalid return invoke state [1] Expression: %s\n", + expression_list[i].c_str()); + + failure = true; + continue; + } + else if (result_list[i] != pattern) { printf("run_test21() - Invalid return results [1] Expected %s Got: %s Expression: %s\n", result_list[i].c_str(), @@ -6840,12 +6856,28 @@ inline bool run_test21() failure = true; continue; } + else if (!parser.dec().return_present()) + { + printf("run_test21() - Expected a return statement Expression: %s [2]\n", + expression_list[i].c_str()); + + failure = true; + continue; + } expression.value(); std::string pattern = results_to_string(expression.results()); - if (result_list[i] != pattern) + if (!expression.return_invoked()) + { + printf("run_test21() - Invalid return invoke state [2] Expression: %s\n", + expression_list[i].c_str()); + + failure = true; + continue; + } + else if (result_list[i] != pattern) { printf("run_test21() - Invalid return results [2] Expected %s Got: %s Expression: %s\n", result_list[i].c_str(),