mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-10-26 22:10:45 +00:00
[Rules] Calculation: operators get lost or are applied to the wrong operands #5660
Fixes: #5660 Credits to @mschlenstedt
This commit is contained in:
1 parent
12af5cd8e4
commit
755d357694
1 file changed
+31
-2
@@ -495,7 +495,15 @@ CalculateReturnCode RulesCalculate_t::RPNCalculate(char *token)
|
||||
// 1 + - left to right
|
||||
int RulesCalculate_t::op_preced(const char c)
|
||||
{
|
||||
if (is_unary_operator(c)) { return 4; // right to left
|
||||
// All function tokens (unary, binary and quinary) must have the highest precedence,
|
||||
// or a pending operator in front of a function call is applied before the function is evaluated.
|
||||
if (is_unary_operator(c) ||
|
||||
#if !defined(LIMIT_BUILD_SIZE) && FEATURE_TRIGONOMETRIC_FUNCTIONS_RULES
|
||||
is_binary_operator(c) ||
|
||||
#endif // if !defined(LIMIT_BUILD_SIZE) && FEATURE_TRIGONOMETRIC_FUNCTIONS_RULES
|
||||
is_quinary_operator(c))
|
||||
{
|
||||
return 4; // right to left
|
||||
}
|
||||
|
||||
switch (c)
|
||||
@@ -653,7 +661,22 @@ CalculateReturnCode RulesCalculate_t::doCalculate(const char *input, ESPEASY_RUL
|
||||
*(TokenPos) = 0; // Mark end of token string
|
||||
error = RPNCalculate(token);
|
||||
TokenPos = token;
|
||||
c = 0; // reset
|
||||
if (isError(error)) { return error; }
|
||||
|
||||
// Finish the previous argument: pop all operators off the stack onto the token queue
|
||||
// until the left parenthesis of the function call (which stays on the stack).
|
||||
while (sl > 0 && stack[sl - 1] != '(')
|
||||
{
|
||||
*TokenPos = stack[sl - 1];
|
||||
++TokenPos;
|
||||
*(TokenPos) = 0; // Mark end of token string
|
||||
error = RPNCalculate(token);
|
||||
TokenPos = token;
|
||||
|
||||
if (isError(error)) { return error; }
|
||||
sl--;
|
||||
}
|
||||
c = 0; // reset
|
||||
}
|
||||
|
||||
// If the token is a left parenthesis, then push it onto the stack.
|
||||
@@ -750,6 +773,12 @@ CalculateReturnCode RulesCalculate_t::doCalculate(const char *input, ESPEASY_RUL
|
||||
sl--;
|
||||
}
|
||||
|
||||
// Also remove the function token that has just been processed (marked '\0' above),
|
||||
// otherwise it blocks the operators below it and operator precedence is lost.
|
||||
if ((sl > 0) && (stack[sl - 1] == '\0')) {
|
||||
sl--;
|
||||
}
|
||||
|
||||
// If the token at the top of the stack is a function token, pop it onto the token queue.
|
||||
// FIXME TD-er: This sc value is never used, it is re-assigned a new value before it is being checked.
|
||||
// if ((sl > 0) && (sl < OPERATOR_STACK_SIZE)) {
|
||||
|
||||
Reference in new issue
Block a user