From 72feefe709283fe2bc347997462c33ff53b5fb54 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 8 Mar 2025 16:50:12 +0100 Subject: [PATCH] allow brackets in conditions (idea from philwingfield) --- src/core/shuntingYard.hpp | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/core/shuntingYard.hpp b/src/core/shuntingYard.hpp index 3448fa1fc..b631d896b 100644 --- a/src/core/shuntingYard.hpp +++ b/src/core/shuntingYard.hpp @@ -93,6 +93,9 @@ std::deque exprToTokens(const std::string & expr) { } else if (strncmp(p, "pow", 3) == 0) { p += 2; tokens.emplace_back(Token::Type::Unary, "p", 5); + } else if (strncmp(p, "hex", 3) == 0) { + p += 2; + tokens.emplace_back(Token::Type::Unary, "h", 5); } else if (*p >= 'a' && *p <= 'z') { const auto * b = p; while ((*p >= 'a' && *p <= 'z') || (*p == '_')) { @@ -490,6 +493,9 @@ std::string calculate(const std::string & expr) { case 'p': stack.push_back(to_string(std::pow(std::stod(rhs), 2))); break; + case 'h': + stack.push_back(to_string(std::stoi(rhs, 0, 16))); + break; } } break; case Token::Type::Compare: { @@ -694,14 +700,29 @@ std::string compute(const std::string & expr) { if (c1 == std::string::npos) { return ""; // error: missing colon } - std::string cond = calculate(expr_new.substr(0, q)); + auto s = q; // start search brackets + int br = 0; // count brackets + while (s > 0 && (br || expr_new[s - 1] != '(')) { + s--; + br += (expr_new[s] == '(' ? -1 : expr_new[s] == ')' ? 1 : 0); + } + std::string cond = calculate(expr_new.substr(s, q - s)); if (cond.length() == 0) { return ""; } else if (cond[0] == '1') { - expr_new.erase(c1); // remove second expression after colon - expr_new.erase(0, q + 1); // remove condition before questionmark + auto e = expr_new.length(); // end + if (s) { // there was a opening bracket, find the closing one + e = c1; + br = 0; + while (e < expr_new.length() && (br || expr_new[e + 1] != ')')) { + e++; + br += (expr_new[e] == ')' ? -1 : expr_new[e] == '(' ? 1 : 0); + } + } + expr_new.erase(c1, e + 1 - c1); // remove second expression after colon + expr_new.erase(s, q + 1 - s); // remove condition before questionmark } else if (cond[0] == '0') { - expr_new.erase(0, c1 + 1); // remove condition and first expression + expr_new.erase(s, c1 + 1 - s); // remove condition and first expression } else { return ""; // error }