From 0c27d03e0b14ecd813a852de6523699b26a4128f Mon Sep 17 00:00:00 2001 From: Neeraj Date: Thu, 7 Nov 2024 14:02:35 +0530 Subject: [PATCH] BugFix3301: Precedence of % (mod) is higher than * and / --- docs/expressions/syntax.md | 3 +- test/unit-tests/expression/parse.test.js | 51 ++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/docs/expressions/syntax.md b/docs/expressions/syntax.md index 07a081a228..0ff0d21b0e 100644 --- a/docs/expressions/syntax.md +++ b/docs/expressions/syntax.md @@ -114,9 +114,8 @@ Operators | Description `!` | Factorial `^`, `.^` | Exponentiation `+`, `-`, `~`, `not` | Unary plus, unary minus, bitwise not, logical not -`%`, `mod` | percentage, modulus See section below | Implicit multiplication -`*`, `/`, `.*`, `./` | Multiply, divide +`*`, `/`, `.*`, `./`,`%`, `mod` | Multiply, divide , percentage, modulus `+`, `-` | Add, subtract `:` | Range `to`, `in` | Unit conversion diff --git a/test/unit-tests/expression/parse.test.js b/test/unit-tests/expression/parse.test.js index a08bc574bb..501e535434 100644 --- a/test/unit-tests/expression/parse.test.js +++ b/test/unit-tests/expression/parse.test.js @@ -1375,6 +1375,57 @@ describe('parse', function () { approxEqual(parseAndEval('8 mod 3'), 2) }) + it('should give equal precedence to % and * operators', function () { + approxEqual(parseAndEval('10 % 3 * 2'), 2) // Expected as (10 % 3) * 2 = 1 * 2 = 2 + approxEqual(parseAndEval('10 * 3 % 4'), 2) // Expected as (10 * 3) % 4 = 30 % 4 = 2 + }) + + it('should give equal precedence to % and / operators', function () { + approxEqual(parseAndEval('10 % 4 / 2'), 1) // Expected as (10 % 4) / 2 = 2 / 2 = 1 + approxEqual(parseAndEval('10 / 2 % 3'), 2) // Expected as (10 / 2) % 3 = 5 % 3 = 2 + }) + + it('should give equal precedence to mod and * operators', function () { + approxEqual(parseAndEval('8 mod 3 * 2'), 4) // Expected as (8 mod 3) * 2 = 2 * 2 = 4 + approxEqual(parseAndEval('8 * 3 mod 5'), 4) // Expected as (8 * 3) mod 5 = 24 mod 5 = 4 + }) + + it('should give equal precedence to mod and / operators', function () { + approxEqual(parseAndEval('8 mod 3 / 2'), 1) // Expected as (8 mod 3) / 2 = 2 / 2 = 1 + approxEqual(parseAndEval('8 / 3 mod 2'), 0.6666666666666667) // Expected as (8 / 3) mod 2 = 2.6666666666666665 % 2 = 0.6666666666666667 + }) + + it('should give equal precedence to % and .* operators', function () { + approxEqual(parseAndEval('10 % 3 .* 2'), 2) // Expected as (10 % 3) .* 2 = 1 .* 2 = 2 + approxEqual(parseAndEval('10 .* 3 % 4'), 2) // Expected as (10 .* 3) % 4 = 30 % 4 = 2 + }) + + it('should give equal precedence to % and ./ operators', function () { + approxEqual(parseAndEval('10 % 4 ./ 2'), 1) // Expected as (10 % 4) ./ 2 = 2 ./ 2 = 1 + approxEqual(parseAndEval('10 ./ 2 % 3'), 2) // Expected as (10 ./ 2) % 3 = 5 % 3 = 2 + }) + + it('should give equal precedence to mod and .* operators', function () { + approxEqual(parseAndEval('8 mod 3 .* 2'), 4) // Expected as (8 mod 3) .* 2 = 2 .* 2 = 4 + approxEqual(parseAndEval('8 .* 3 mod 5'), 4) // Expected as (8 .* 3) mod 5 = 24 mod 5 = 4 + }) + + it('should give equal precedence to mod and ./ operators', function () { + approxEqual(parseAndEval('8 mod 3 ./ 2'), 1) // Expected as (8 mod 3) ./ 2 = 2 ./ 2 = 1 + approxEqual(parseAndEval('8 ./ 3 mod 2'), 0.6666666666666667) // Expected as (8 ./ 3) mod 2 = 2.6666666666666665 % 2 = 0.6666666666666667 + }) + + it('should evaluate complex expressions with mixed precedence equally', function () { + approxEqual(parseAndEval('10 % 3 * 2 + 4 / 2'), 4) // Expected as (10 % 3) * 2 + (4 / 2) = 1 * 2 + 2 = 4 + approxEqual(parseAndEval('8 mod 3 + 2 * 4 - 5'), 5) // Expected as (8 mod 3) + (2 * 4) - 5 = 2 + 8 - 5 = 5 + approxEqual(parseAndEval('12 / 4 % 2 .* 5'), 5) // Expected as ((12 / 4) % 2) .* 5 = (3 % 2) .* 5 = 1 * 5 = 5 + }) + + it('should handle cases with equal precedence among all operators', function () { + approxEqual(parseAndEval('10 % 3 .* 2 ./ 2'), 1) // Expected as ((10 % 3) .* 2) ./ 2 = (1 .* 2) ./ 2 = 2 / 2 = 1 + approxEqual(parseAndEval('10 ./ 2 % 3 * 2'), 4) // Expected as ((10 ./ 2) % 3) * 2 = (5 % 3) * 2 = 2 * 2 = 4 + }) + it('should parse multiply *', function () { approxEqual(parseAndEval('4 * 2'), 8) approxEqual(parseAndEval('8 * 2 * 2'), 32)