Skip to content

Commit b9a932b

Browse files
author
Sébastien Geiser
committed
Easilly adding Operators with priorities
1 parent 5c9de53 commit b9a932b

File tree

3 files changed

+116
-9
lines changed

3 files changed

+116
-9
lines changed

CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,7 +1828,43 @@ void Evaluator_PreEvaluateVariable(object sender, VariablePreEvaluationEventArg
18281828
.SetCategory("inherits ExpressionEvaluator")
18291829
.SetCategory("Custom operators");
18301830

1831+
XExpressionEvaluator2.StaticInit();
1832+
ExpressionEvaluator xExpressionEvaluator2 = new XExpressionEvaluator2();
18311833

1834+
yield return new TestCaseData(xExpressionEvaluator2
1835+
, "1#", null)
1836+
.Returns(1)
1837+
.SetCategory("ExpressionEvaluator extend")
1838+
.SetCategory("inherits ExpressionEvaluator")
1839+
.SetCategory("Custom operators");
1840+
1841+
yield return new TestCaseData(xExpressionEvaluator2
1842+
, "2#", null)
1843+
.Returns(0.25)
1844+
.SetCategory("ExpressionEvaluator extend")
1845+
.SetCategory("inherits ExpressionEvaluator")
1846+
.SetCategory("Custom operators");
1847+
1848+
yield return new TestCaseData(xExpressionEvaluator2
1849+
, "-4# - 6", null)
1850+
.Returns(250)
1851+
.SetCategory("ExpressionEvaluator extend")
1852+
.SetCategory("inherits ExpressionEvaluator")
1853+
.SetCategory("Custom operators");
1854+
1855+
yield return new TestCaseData(xExpressionEvaluator2
1856+
, "1 love 2", null)
1857+
.Returns(6)
1858+
.SetCategory("ExpressionEvaluator extend")
1859+
.SetCategory("inherits ExpressionEvaluator")
1860+
.SetCategory("Custom operators");
1861+
1862+
yield return new TestCaseData(xExpressionEvaluator2
1863+
, "1 love 2 >> 1", null)
1864+
.Returns(3)
1865+
.SetCategory("ExpressionEvaluator extend")
1866+
.SetCategory("inherits ExpressionEvaluator")
1867+
.SetCategory("Custom operators");
18321868

18331869

18341870
#endregion

CodingSeb.ExpressionEvaluator.Tests/TestsUtils/XExpressionEvaluator2.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
1-
namespace CodingSeb.ExpressionEvaluator.Tests
1+
using System;
2+
3+
namespace CodingSeb.ExpressionEvaluator.Tests
24
{
35
public class XExpressionEvaluator2 : ExpressionEvaluator
46
{
7+
public static void StaticInit()
8+
{
9+
leftOperandOnlyOperatorsEvaluationDictionary.Add(XExpressionOperator2.Sharp);
10+
11+
operatorsEvaluations
12+
.AddOperatorEvaluationAtNewLevelAfter(XExpressionOperator2.Sharp, (left, _) => Math.Pow(left, -left), ExpressionOperator.UnaryPlus)
13+
.AddOperatorEvaluationAtLevelOf(XExpressionOperator2.Love, (left, right) => (left | right) << 1, ExpressionOperator.ShiftBitsLeft);
14+
}
15+
516
protected override void Init()
617
{
718
operatorsDictionary.Add("#", XExpressionOperator2.Sharp);

CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -198,14 +198,14 @@ private enum TryBlockEvaluatedState
198198
{ "??", ExpressionOperator.NullCoalescing },
199199
};
200200

201-
protected static readonly IDictionary<ExpressionOperator, bool> leftOperandOnlyOperatorsEvaluationDictionary = new Dictionary<ExpressionOperator, bool>();
201+
protected static readonly IList<ExpressionOperator> leftOperandOnlyOperatorsEvaluationDictionary = new List<ExpressionOperator>();
202202

203-
protected static readonly IDictionary<ExpressionOperator, bool> rightOperandOnlyOperatorsEvaluationDictionary = new Dictionary<ExpressionOperator, bool>()
203+
protected static readonly IList<ExpressionOperator> rightOperandOnlyOperatorsEvaluationDictionary = new List<ExpressionOperator>()
204204
{
205-
{ExpressionOperator.LogicalNegation, true },
206-
{ExpressionOperator.BitwiseComplement, true },
207-
{ExpressionOperator.UnaryPlus, true },
208-
{ExpressionOperator.UnaryMinus, true }
205+
ExpressionOperator.LogicalNegation,
206+
ExpressionOperator.BitwiseComplement,
207+
ExpressionOperator.UnaryPlus,
208+
ExpressionOperator.UnaryMinus
209209
};
210210

211211
protected static readonly IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> operatorsEvaluations =
@@ -2631,13 +2631,13 @@ protected virtual object ProcessStack(Stack<object> stack)
26312631

26322632
if ((list[i] as ExpressionOperator) == eOp)
26332633
{
2634-
if (rightOperandOnlyOperatorsEvaluationDictionary.ContainsKey(eOp))
2634+
if (rightOperandOnlyOperatorsEvaluationDictionary.Contains(eOp))
26352635
{
26362636
list[i] = operatorEvalutationsDict[eOp](null, (dynamic)list[i - 1]);
26372637
list.RemoveAt(i - 1);
26382638
break;
26392639
}
2640-
else if (leftOperandOnlyOperatorsEvaluationDictionary.ContainsKey(eOp))
2640+
else if (leftOperandOnlyOperatorsEvaluationDictionary.Contains(eOp))
26412641
{
26422642
list[i] = operatorEvalutationsDict[eOp]((dynamic)list[i + 1], null);
26432643
list.RemoveAt(i + 1);
@@ -3362,6 +3362,8 @@ public enum OptionOnNoReturnKeywordFoundInScriptAction
33623362

33633363
#region ExpressionEvaluator linked public classes (specific Exceptions, EventArgs and Operators)
33643364

3365+
#region Operators Management
3366+
33653367
public partial class ExpressionOperator : IEquatable<ExpressionOperator>
33663368
{
33673369
protected static uint indexer = 0;
@@ -3421,6 +3423,64 @@ public bool Equals(ExpressionOperator otherOperator)
34213423
}
34223424
}
34233425

3426+
public static partial class OperatorsEvaluationsExtensions
3427+
{
3428+
public static IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> AddOperatorEvaluationAtLevelOf(this IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> operatorsEvaluations, ExpressionOperator operatorToAdd, Func<dynamic, dynamic, object> evaluation, ExpressionOperator levelOfThisOperator)
3429+
{
3430+
operatorsEvaluations
3431+
.First(dict => dict.ContainsKey(levelOfThisOperator))
3432+
.Add(operatorToAdd, evaluation);
3433+
3434+
return operatorsEvaluations;
3435+
}
3436+
3437+
public static IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> AddOperatorEvaluationAtLevel(this IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> operatorsEvaluations, ExpressionOperator operatorToAdd, Func<dynamic, dynamic, object> evaluation, int level)
3438+
{
3439+
operatorsEvaluations[level]
3440+
.Add(operatorToAdd, evaluation);
3441+
3442+
return operatorsEvaluations;
3443+
}
3444+
3445+
public static IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> AddOperatorEvaluationAtNewLevelAfter(this IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> operatorsEvaluations, ExpressionOperator operatorToAdd, Func<dynamic, dynamic, object> evaluation, ExpressionOperator levelOfThisOperator)
3446+
{
3447+
int level = operatorsEvaluations
3448+
.IndexOf(operatorsEvaluations.First(dict => dict.ContainsKey(levelOfThisOperator)));
3449+
3450+
operatorsEvaluations
3451+
.Insert(level + 1, new Dictionary<ExpressionOperator, Func<dynamic, dynamic, object>> { { operatorToAdd, evaluation } });
3452+
3453+
return operatorsEvaluations;
3454+
}
3455+
3456+
public static IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> AddOperatorEvaluationAtNewLevelBefore(this IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> operatorsEvaluations, ExpressionOperator operatorToAdd, Func<dynamic, dynamic, object> evaluation, ExpressionOperator levelOfThisOperator)
3457+
{
3458+
int level = operatorsEvaluations
3459+
.IndexOf(operatorsEvaluations.First(dict => dict.ContainsKey(levelOfThisOperator)));
3460+
3461+
operatorsEvaluations
3462+
.Insert(level, new Dictionary<ExpressionOperator, Func<dynamic, dynamic, object>> { { operatorToAdd, evaluation } });
3463+
3464+
return operatorsEvaluations;
3465+
}
3466+
3467+
public static IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> AddOperatorEvaluationAtNewLevel(this IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> operatorsEvaluations, ExpressionOperator operatorToAdd, Func<dynamic, dynamic, object> evaluation, int level)
3468+
{
3469+
operatorsEvaluations
3470+
.Insert(level, new Dictionary<ExpressionOperator, Func<dynamic, dynamic, object>> { { operatorToAdd, evaluation } });
3471+
3472+
return operatorsEvaluations;
3473+
}
3474+
3475+
public static IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> RemoveOperatorEvaluation(this IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> operatorsEvaluations, ExpressionOperator operatorToRemove)
3476+
{
3477+
operatorsEvaluations.First(dict => dict.ContainsKey(operatorToRemove)).Remove(operatorToRemove);
3478+
3479+
return operatorsEvaluations;
3480+
}
3481+
}
3482+
3483+
#endregion
34243484

34253485
public partial class ClassOrEnumType
34263486
{

0 commit comments

Comments
 (0)