From bf2882e1acf69329ef23d153a45509fdbd4b924b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Johansson?= Date: Thu, 12 Jun 2025 16:15:56 +0200 Subject: [PATCH] Support for nested ternary --- .../ExpressionEvaluatorTests.cs | 4 ++++ .../ExpressionEvaluator.cs | 24 +++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs b/CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs index 2f857bd..3282dae 100644 --- a/CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs +++ b/CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs @@ -621,6 +621,10 @@ public void TypeTesting(string expression, Type type) [TestCase("Abs(-4) > 10 / 2 ? (true ? 6 : 3+2) : (false ? Abs(-18) : 100 / 2)", ExpectedResult = 50, Category = "Conditional Operator t ? x : y")] [TestCase("Abs(-4) > 10 / 2?(true ? 6 : 3+2):(false?Abs(-18):100 / 2)", ExpectedResult = 50, Category = "Conditional Operator t ? x : y")] [TestCase("1==1?true:false", ExpectedResult = true, Category = "Conditional Operator t ? x : y")] + [TestCase("1 == 2 ? 3 == 4 ? 1 : 0 : 0", ExpectedResult = 0, Category = "Conditional Operator t ? x : y")] + [TestCase("1 == 1 ? 3 == 3 ? 1 : 0 : 0", ExpectedResult = 1, Category = "Conditional Operator t ? x : y")] + [TestCase("false ? true ? 10 : 20 : 30", ExpectedResult = 30, Category = "Conditional Operator t ? x : y")] + [TestCase("true ? false ? 10 : 20 : 30", ExpectedResult = 20, Category = "Conditional Operator t ? x : y")] #endregion #region Math Constants diff --git a/CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs b/CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs index dfa1fd9..62e65f3 100644 --- a/CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs +++ b/CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs @@ -2808,6 +2808,8 @@ protected virtual bool EvaluateTernaryConditionalOperator(string expression, Sta bool condition = (bool)ProcessStack(stack); string restOfExpression = expression.Substring(i + 1); + // Track nesting level of ternary operators + int ternaryNestingLevel = 0; for (int j = 0; j < restOfExpression.Length; j++) { @@ -2825,15 +2827,29 @@ protected virtual bool EvaluateTernaryConditionalOperator(string expression, Sta j++; GetExpressionsBetweenParenthesesOrOtherImbricableBrackets(restOfExpression, ref j, false); } + else if (s2.Equals("?")) + { + // Found nested ternary operator, increase nesting level + ternaryNestingLevel++; + } else if (s2.Equals(":")) { - stack.Clear(); + if (ternaryNestingLevel == 0) + { + // This colon belongs to our ternary operator + stack.Clear(); - stack.Push(condition ? Evaluate(restOfExpression.Substring(0, j)) : Evaluate(restOfExpression.Substring(j + 1))); + stack.Push(condition ? Evaluate(restOfExpression.Substring(0, j)) : Evaluate(restOfExpression.Substring(j + 1))); - i = expression.Length; + i = expression.Length; - return true; + return true; + } + else + { + // This colon belongs to a nested ternary operator, decrease nesting level + ternaryNestingLevel--; + } } } }