From 9c655a93ce8b30c24b02c0e193b957ffea2989eb Mon Sep 17 00:00:00 2001 From: youngwolf Date: Thu, 8 Feb 2024 10:34:51 +0800 Subject: [PATCH] Code refactoring. --- question_exp.h | 165 ++++++++++++++++++++----------------------------- 1 file changed, 67 insertions(+), 98 deletions(-) diff --git a/question_exp.h b/question_exp.h index e1590d3..1c479e3 100644 --- a/question_exp.h +++ b/question_exp.h @@ -118,8 +118,8 @@ public: virtual bool merge_with(char, data_exp_ctype&) {return false;} virtual bool merge_with(data_exp_ctype&, char) {return false;} virtual data_exp_type trim_myself() {return data_exp_type();} - virtual data_exp_type final_optimize() {return data_exp_type();} virtual data_exp_type to_negative() const = 0; + virtual data_exp_type final_optimize() const {return data_exp_type();} virtual T operator()(const std::function&) const = 0; //used in qme::safe_execute function, do not call it directly @@ -195,8 +195,8 @@ private: T value; }; -template inline data_exp_type merge_data_exp(data_exp_ctype&, data_exp_ctype&, char); template class composite_variable_data_exp; +template inline data_exp_type merge_data_exp(data_exp_ctype&, data_exp_ctype&, char); template class binary_data_exp : public data_exp { protected: @@ -231,10 +231,9 @@ public: case '/': return dexp_l->is_negative() || dexp_r->is_negative(); break; - default: - return false; - break; } + + return false; } virtual int get_depth() const {return 1 + std::max(dexp_l->get_depth(), dexp_r->get_depth());} virtual char get_operator() const {return op;} @@ -382,26 +381,6 @@ public: return data_exp_type(); } - virtual data_exp_type final_optimize() - { - auto changed = false; - auto data = dexp_l->final_optimize(); - if (data) - { - changed = true; - dexp_l = data; - } - - data = dexp_r->final_optimize(); - if (data) - { - changed = true; - dexp_r = data; - } - - return changed ? merge_data_exp(dexp_l, dexp_r, op) : data_exp_type(); - } - virtual data_exp_type to_negative() const { switch (op) @@ -441,10 +420,17 @@ public: return merge_data_exp(dexp_l, dexp_r->to_negative(), op); } break; - default: - throw("undefined operator " + std::string(1, op)); - break; } + + return data_exp_type(); + } + + virtual data_exp_type final_optimize() const + { + auto l = dexp_l->final_optimize(); + auto r = dexp_r->final_optimize(); + + return (l || r) ? merge_data_exp(l ? l : dexp_l, r ? r : dexp_r, op) : data_exp_type(); } virtual T safe_execute(const std::function&) const {throw("unsupported safe execute operation!");} @@ -610,33 +596,36 @@ public: else if (!is_same_composite_variable(variable_name, other_exp)) return false; else + { + auto other_exponent = other_exp->get_exponent(); + auto other_multiplier = other_exp->get_multiplier(); switch (other_op) { case '+': - if ((O::level() < 3 && exponent < 0) || exponent != other_exp->get_exponent()) + if ((O::level() < 3 && exponent < 0) || exponent != other_exponent) return false; - multiplier += other_exp->get_multiplier(); + multiplier += other_multiplier; break; case '-': - if ((O::level() < 3 && exponent < 0) || exponent != other_exp->get_exponent()) + if ((O::level() < 3 && exponent < 0) || exponent != other_exponent) return false; - multiplier -= other_exp->get_multiplier(); + multiplier -= other_multiplier; break; case '*': - if (O::level() > 2 || (exponent >= 0 && other_exp->get_exponent() >= 0)) + if (O::level() > 2 || (exponent >= 0 && other_exponent >= 0)) { - multiplier *= other_exp->get_multiplier(); - exponent += other_exp->get_exponent(); + multiplier *= other_multiplier; + exponent += other_exponent; } else return false; break; case '/': - if (O::level() > 2 || (other_exp->get_exponent() >= 0 && //for this exponent, negative is also okay - (other_exp->get_exponent() >= exponent || is_divisible(multiplier, other_exp->get_multiplier())))) + if (O::level() > 2 || (other_exponent >= 0 && //for this exponent, negative is also okay + (other_exponent >= exponent || is_divisible(multiplier, other_multiplier)))) { - multiplier /= other_exp->get_multiplier(); - exponent -= other_exp->get_exponent(); + multiplier /= other_multiplier; + exponent -= other_exponent; } else return false; @@ -645,6 +634,7 @@ public: throw("undefined operator " + std::string(1, other_op)); break; } + } return true; } @@ -665,8 +655,8 @@ public: exponent = -exponent; return true; } - else - return false; + + return false; } virtual data_exp_type trim_myself() @@ -676,7 +666,10 @@ public: return data_exp_type(); } - virtual data_exp_type final_optimize() + virtual data_exp_type to_negative() const + {return std::make_shared>(variable_name, -multiplier, exponent);} + + virtual data_exp_type final_optimize() const { data_exp_type data = std::make_shared>(multiplier); if (0 == multiplier || 0 == exponent) @@ -687,22 +680,20 @@ public: return std::make_shared>(variable_name, exponent); else if (-1 == multiplier && exponent < 0) return std::make_shared>(variable_name, exponent); - else if (1 == exponent) - data = std::make_shared>(data, std::make_shared>(variable_name)); else if (-1 == exponent) return std::make_shared>(data, std::make_shared>(variable_name)); - else if (exponent > 1) - data = std::make_shared>(data, std::make_shared>(variable_name, exponent)); - else // < -1 + else if (exponent < -1) return std::make_shared>(data, std::make_shared>(variable_name, -exponent)); + if (1 == exponent) + data = std::make_shared>(data, std::make_shared>(variable_name)); + else // > 1 + data = std::make_shared>(data, std::make_shared>(variable_name, exponent)); + auto re = data->trim_myself(); return re ? re : data; } - virtual data_exp_type to_negative() const - {return std::make_shared>(variable_name, -multiplier, exponent);} - virtual T operator()(const std::function& cb) const { #ifdef DEBUG @@ -932,7 +923,7 @@ public: virtual judge_exp_ctype& get_left_item() const {throw("unsupported get left item operation!");} virtual judge_exp_ctype& get_right_item() const {throw("unsupported get right item operation!");} - virtual judge_exp_type final_optimize() = 0; + virtual void final_optimize() = 0; virtual bool operator()(const std::function&) const = 0; //is recursion fully eliminated or not depends on the data_exp(s) this judge_exp holds @@ -962,13 +953,11 @@ protected: public: virtual int get_depth() const {return 1 + dexp->get_depth();} virtual void show_immediate_value() const {dexp->show_immediate_value();} - virtual judge_exp_type final_optimize() + virtual void final_optimize() { auto data = dexp->final_optimize(); if (data) dexp = data; - - return judge_exp_type(); } virtual void safe_delete() const {qme::safe_delete(dexp);} @@ -1003,7 +992,7 @@ protected: public: virtual int get_depth() const {return 1 + std::max(dexp_l->get_depth(), dexp_r->get_depth());} virtual void show_immediate_value() const {dexp_l->show_immediate_value(); dexp_r->show_immediate_value();} - virtual judge_exp_type final_optimize() + virtual void final_optimize() { auto data = dexp_l->final_optimize(); if (data) @@ -1012,8 +1001,6 @@ public: data = dexp_r->final_optimize(); if (data) dexp_r = data; - - return judge_exp_type(); } virtual void safe_delete() const {qme::safe_delete(dexp_l); qme::safe_delete(dexp_r);} @@ -1109,7 +1096,7 @@ public: virtual int get_depth() const {return 1 + jexp->get_depth();} virtual void show_immediate_value() const {jexp->show_immediate_value();} - virtual judge_exp_type final_optimize() {return jexp->final_optimize();} + virtual void final_optimize() {jexp->final_optimize();} virtual bool operator()(const std::function& cb) const {return !(*jexp)(cb);} virtual bool safe_execute(const std::function& cb) const {return !qme::safe_execute(jexp, cb);} @@ -1133,13 +1120,7 @@ public: virtual int get_depth() const {return 1 + std::max(jexp_l->get_depth(), jexp_l->get_depth());} virtual void show_immediate_value() const {jexp_l->show_immediate_value(); jexp_r->show_immediate_value();} - virtual judge_exp_type final_optimize() - { - jexp_l->final_optimize(); - jexp_r->final_optimize(); - - return judge_exp_type(); - } + virtual void final_optimize() {jexp_l->final_optimize(); jexp_r->final_optimize();} virtual bool safe_execute(const std::function&) const {throw("unsupported safe execute operation!");} virtual void clear() {jexp_l.reset(); jexp_r.reset();} @@ -1191,19 +1172,13 @@ public: virtual void show_immediate_value() const {jexp->show_immediate_value(); dexp_l->show_immediate_value(); dexp_r->show_immediate_value();} - virtual data_exp_type final_optimize() + virtual data_exp_type final_optimize() const { jexp->final_optimize(); + auto l = dexp_l->final_optimize(); + auto r = dexp_r->final_optimize(); - auto data = dexp_l->final_optimize(); - if (data) - dexp_l = data; - - data = dexp_r->final_optimize(); - if (data) - dexp_r = data; - - return data_exp_type(); + return std::make_shared>(jexp, l ? l : dexp_l, r ? r : dexp_r); } virtual data_exp_type to_negative() const {return std::make_shared>(jexp, dexp_l, dexp_r);} @@ -1231,6 +1206,7 @@ public: virtual bool is_easy_to_negative() const {return true;} virtual bool is_negative() const {return true;} + virtual data_exp_type final_optimize() const {return question_exp::final_optimize()->to_negative();} virtual data_exp_type to_negative() const {return question_exp::clone();} virtual T operator()(const std::function& cb) const {return -question_exp::operator()(cb);} @@ -1238,25 +1214,6 @@ public: }; ///////////////////////////////////////////////////////////////////////////////////////// -template class Exp> -inline std::shared_ptr> final_optimize(const std::shared_ptr>& exp) -{ - if (O::level() < 2) - return exp; - - auto re = exp->final_optimize(); - if (!re) - re = exp; - -#ifdef DEBUG - printf(" max depth: %d\n immediate values:", re->get_depth()); - re->show_immediate_value(); - putchar('\n'); -#endif - - return re; -} - using exp_type = std::shared_ptr; template class compiler { @@ -1346,10 +1303,22 @@ public: auto re = compile(split(expression), sub_exps); if (!re) throw("incomplete expression!"); - else if (re->is_data()) - re = final_optimize(std::dynamic_pointer_cast>(re)); - else - re = final_optimize(std::dynamic_pointer_cast>(re)); + else if (O::level() > 1) + { + if (re->is_data()) + { + auto final_re = std::dynamic_pointer_cast>(re)->final_optimize(); + if (final_re) + re = final_re; + } + else + std::dynamic_pointer_cast>(re)->final_optimize(); +#ifdef DEBUG + printf(" max depth: %d\n immediate values:", re->get_depth()); + re->show_immediate_value(); + putchar('\n'); +#endif + } return re; } -- GitLab