From 433ee2bb2eb6dc4d2e7ed83775f03dfee908f2f8 Mon Sep 17 00:00:00 2001 From: hasslesstech Date: Wed, 14 Oct 2026 15:16:08 +0300 Subject: [PATCH] lab2 feat: add constant folding --- inc/expression.hpp | 7 ++- src/syntaxer.cpp | 133 +++++++++++++++++++++++++++------------------ 2 files changed, 87 insertions(+), 53 deletions(-) diff --git a/inc/expression.hpp b/inc/expression.hpp index 811ae8c..6b90fcf 100644 --- a/inc/expression.hpp +++ b/inc/expression.hpp @@ -186,17 +186,22 @@ public: std::shared_ptr to_math_str(void) const { + char buffer[128] = {0}; + switch (t) { case VAR: return v.s; case CONST: { - char buffer[128] = {0}; return std::make_shared((std::ostringstream() << v.d).str()); } case OPERATOR: return std::make_shared(op_math_str()); + case CV: + return std::make_shared((std::ostringstream() << "t" << v.cv.i).str()); + case NAT: + return std::make_shared(""); default: return std::make_shared("Not a valid token!"); } diff --git a/src/syntaxer.cpp b/src/syntaxer.cpp index 56153bb..d166f52 100644 --- a/src/syntaxer.cpp +++ b/src/syntaxer.cpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace Syntax { @@ -439,7 +440,7 @@ static int get_max_index(const std::vector& v) static void write_operation( std::vector& ov, - const std::vector& tv, + std::vector& cv, std::vector& mv, std::vector& mp, int position) @@ -448,30 +449,77 @@ static void write_operation( int left_location = get_left_location(mv, location); int right_location = get_right_location(mv, location); + std::vector hl; + hl.emplace_back(left_location); + hl.emplace_back(location); + hl.emplace_back(right_location); + Parser::print_math_vector(mv, hl); + Expression::Token &o = mv[location], &l = mv[left_location], &r = mv[right_location]; - int this_op_weight = get_operator_weight(mv, location) + 1; +#if LAB2_EXCLUDE_COMPTIME_OP_WRITES == 1 + if (l.t == Expression::Token::CONST && r.t == Expression::Token::CONST) + { + pr_debug("CONST folding"); - int il = l.t == Expression::Token::CV ? l.v.cv.i : left_location; - int ir = r.t == Expression::Token::CV ? r.v.cv.i : right_location; + switch (o.v.o) + { + case Expression::Token::ADD: + o.v.d = l.v.d + r.v.d; + break; + case Expression::Token::SUB: + o.v.d = l.v.d - r.v.d; + break; + case Expression::Token::MUL: + o.v.d = l.v.d * r.v.d; + break; + case Expression::Token::DIV: + o.v.d = l.v.d / r.v.d; + break; + case Expression::Token::POW: + o.v.d = std::pow(l.v.d, r.v.d); + break; + default: + pr_warn("Impossible operator, this is a bug!"); + break; + } - // write new operation - int this_ov_index = ov.size(); - ov.emplace_back(o.v.o, - l.t == Expression::Token::CV ? Expression::Operation::DERIVED : Expression::Operation::NORMAL, - il, - r.t == Expression::Token::CV ? Expression::Operation::DERIVED : Expression::Operation::NORMAL, - ir, - this_op_weight); + l.t = Expression::Token::NAT; + r.t = Expression::Token::NAT; + o.t = Expression::Token::CONST; - // update mv - l.t = Expression::Token::NAT; - r.t = Expression::Token::NAT; - o.t = Expression::Token::CV; - o.v.cv.w = this_op_weight; - o.v.cv.i = this_ov_index; + // sync &cv operator + cv[location].t = Expression::Token::CONST; + cv[location].v.d = o.v.d; + } + else + { +#endif + int this_op_weight = get_operator_weight(mv, location) + 1; + + int il = l.t == Expression::Token::CV ? l.v.cv.i : left_location; + int ir = r.t == Expression::Token::CV ? r.v.cv.i : right_location; + + // write new operation + int this_ov_index = ov.size(); + ov.emplace_back(o.v.o, + l.t == Expression::Token::CV ? Expression::Operation::DERIVED : Expression::Operation::NORMAL, + il, + r.t == Expression::Token::CV ? Expression::Operation::DERIVED : Expression::Operation::NORMAL, + ir, + this_op_weight); + + // update mv + l.t = Expression::Token::NAT; + r.t = Expression::Token::NAT; + o.t = Expression::Token::CV; + o.v.cv.w = this_op_weight; + o.v.cv.i = this_ov_index; +#if LAB2_EXCLUDE_COMPTIME_OP_WRITES == 1 + } +#endif // update mp mp.erase(mp.begin() + position, mp.begin() + position + 1); @@ -789,15 +837,14 @@ std::vector build_op_vector(const std::vector g_prios; create_prios_vector(tv, g_prios); - for (int i = 0, l = g_prios.size(); i < l; i++) - { - pr_debug("prio=" << g_prios[i]); - } + pr_debug("Building operation vector"); + + std::vector cv = tv; // Constant sync Vector // build operation vector std::vector ov; { - std::vector mv = tv; + std::vector mv = tv; // Modifiable Vector std::vector mp = g_prios; while (mp.size()) @@ -814,15 +861,20 @@ std::vector build_op_vector(const std::vector operator_weights; weight_operators(operator_weights, mv, inner_top_ops, start); - write_operation(ov, tv, mv, mp, start + inner_top_ops[get_min_index(operator_weights)]); + write_operation(ov, cv, mv, mp, start + inner_top_ops[get_min_index(operator_weights)]); finish--; } // process final operation w/out running selection algorithm - write_operation(ov, tv, mv, mp, start); + write_operation(ov, cv, mv, mp, start); } + + pr_debug("Final value:"); + Parser::print_math_vector(mv); } + pr_debug("Resulting operation vector:"); + for (int i = 0, l = ov.size(); i < l; i++) { const Expression::Operation &o = ov[i]; @@ -831,16 +883,8 @@ std::vector build_op_vector(const std::vector build_op_vector(const std::vector tv, const s return root; } -#if 0 -static int get_tree_depth(const Expression::TreeNode& root) -{ - retur -} -#endif - void print_op_tree(const Expression::TreeNode& root) { std::vector> items_to_display;