Skip to content

Commit 5f17d98

Browse files
author
Sébastien Geiser
committed
Operators by sub types with virtual props that redirect static fields
1 parent b9a932b commit 5f17d98

File tree

4 files changed

+74
-24
lines changed

4 files changed

+74
-24
lines changed

CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,7 +1526,6 @@ public static IEnumerable<TestCaseData> TestCasesEvaluateWithSpecificEvaluator
15261526
.SetCategory("Options")
15271527
.SetCategory("Integer Numbers default types");
15281528

1529-
15301529
yield return new TestCaseData(new ExpressionEvaluator
15311530
{
15321531
OptionForceIntegerNumbersEvaluationsAsDoubleByDefault = false
@@ -1604,9 +1603,13 @@ public static IEnumerable<TestCaseData> TestCasesEvaluateWithSpecificEvaluator
16041603
void VariableEval(object sender, VariableEvaluationEventArg e)
16051604
{
16061605
if (e.Name.Equals("GetSpecifiedGenericTypesVar"))
1606+
{
16071607
e.Value = e.EvaluateGenericTypes();
1608+
}
16081609
else if (e.Name.Equals("myvar2"))
1610+
{
16091611
e.Value = 50;
1612+
}
16101613
else if (e.This is ClassOrEnumType classOrTypeName && classOrTypeName.Type == typeof(ClassForTest1) && e.Name.Equals("OnTheFlyStaticVar"))
16111614
{
16121615
e.Value = 10;
@@ -1616,7 +1619,9 @@ void VariableEval(object sender, VariableEvaluationEventArg e)
16161619
void FunctionEval(object sender, FunctionEvaluationEventArg e)
16171620
{
16181621
if (e.Name.Equals("GetSpecifiedGenericTypesFunc"))
1622+
{
16191623
e.Value = e.EvaluateGenericTypes();
1624+
}
16201625
else if (e.This is ClassOrEnumType classOrTypeName && classOrTypeName.Type == typeof(ClassForTest1) && e.Name.Equals("OnTheFlyStaticFunc"))
16211626
{
16221627
e.Value = 8;
@@ -1814,7 +1819,6 @@ void Evaluator_PreEvaluateVariable(object sender, VariablePreEvaluationEventArg
18141819
.SetCategory("inherits ExpressionEvaluator")
18151820
.SetCategory("Custom operators");
18161821

1817-
18181822
yield return new TestCaseData(xExpressionEvaluator1
18191823
, "true || true"
18201824
, new Func<Exception, object> (exception =>
@@ -1828,7 +1832,6 @@ void Evaluator_PreEvaluateVariable(object sender, VariablePreEvaluationEventArg
18281832
.SetCategory("inherits ExpressionEvaluator")
18291833
.SetCategory("Custom operators");
18301834

1831-
XExpressionEvaluator2.StaticInit();
18321835
ExpressionEvaluator xExpressionEvaluator2 = new XExpressionEvaluator2();
18331836

18341837
yield return new TestCaseData(xExpressionEvaluator2
@@ -1866,7 +1869,6 @@ void Evaluator_PreEvaluateVariable(object sender, VariablePreEvaluationEventArg
18661869
.SetCategory("inherits ExpressionEvaluator")
18671870
.SetCategory("Custom operators");
18681871

1869-
18701872
#endregion
18711873

18721874
#region bug resolution
@@ -1883,7 +1885,6 @@ void Evaluator_PreEvaluateVariable(object sender, VariablePreEvaluationEventArg
18831885

18841886
#endregion
18851887

1886-
18871888
[TestCaseSource(nameof(TestCasesEvaluateWithSpecificEvaluator))]
18881889
public object EvaluateWithSpecificEvaluator(ExpressionEvaluator evaluator, string expression, Func<Exception, object> inCaseOfException)
18891890
{

CodingSeb.ExpressionEvaluator.Tests/TestsUtils/XExpressionEvaluator2.cs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
24

35
namespace CodingSeb.ExpressionEvaluator.Tests
46
{
57
public class XExpressionEvaluator2 : ExpressionEvaluator
68
{
7-
public static void StaticInit()
8-
{
9-
leftOperandOnlyOperatorsEvaluationDictionary.Add(XExpressionOperator2.Sharp);
9+
protected new static readonly IList<ExpressionOperator> leftOperandOnlyOperatorsEvaluationDictionary =
10+
ExpressionEvaluator.leftOperandOnlyOperatorsEvaluationDictionary
11+
.ToList()
12+
.FluidAdd(XExpressionOperator2.Sharp);
13+
14+
//protected new static readonly IList<ExpressionOperator> rightOperandOnlyOperatorsEvaluationDictionary = new List<ExpressionOperator>(ExpressionEvaluator.rightOperandOnlyOperatorsEvaluationDictionary);
1015

11-
operatorsEvaluations
16+
protected new static readonly IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> operatorsEvaluations =
17+
ExpressionEvaluator.operatorsEvaluations
18+
.Copy()
1219
.AddOperatorEvaluationAtNewLevelAfter(XExpressionOperator2.Sharp, (left, _) => Math.Pow(left, -left), ExpressionOperator.UnaryPlus)
1320
.AddOperatorEvaluationAtLevelOf(XExpressionOperator2.Love, (left, right) => (left | right) << 1, ExpressionOperator.ShiftBitsLeft);
14-
}
21+
22+
protected override IList<ExpressionOperator> LeftOperandOnlyOperatorsEvaluationDictionary => leftOperandOnlyOperatorsEvaluationDictionary;
23+
protected override IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> OperatorsEvaluations => operatorsEvaluations;
1524

1625
protected override void Init()
1726
{

CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,10 @@ private enum TryBlockEvaluatedState
208208
ExpressionOperator.UnaryMinus
209209
};
210210

211+
protected virtual IList<ExpressionOperator> LeftOperandOnlyOperatorsEvaluationDictionary => leftOperandOnlyOperatorsEvaluationDictionary;
212+
protected virtual IList<ExpressionOperator> RightOperandOnlyOperatorsEvaluationDictionary => rightOperandOnlyOperatorsEvaluationDictionary;
213+
protected virtual IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> OperatorsEvaluations => operatorsEvaluations;
214+
211215
protected static readonly IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> operatorsEvaluations =
212216
new List<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>>()
213217
{
@@ -1287,7 +1291,6 @@ void forAction(int index)
12871291
if (isContinue)
12881292
{
12891293
isContinue = false;
1290-
continue;
12911294
}
12921295
}
12931296
}
@@ -1305,9 +1308,7 @@ void forAction(int index)
13051308
}
13061309
else
13071310
{
1308-
dynamic collection = Evaluate(foreachParenthisEvaluationMatch.Groups["collection"].Value);
1309-
1310-
foreach (dynamic foreachValue in collection)
1311+
foreach (dynamic foreachValue in (dynamic)Evaluate(foreachParenthisEvaluationMatch.Groups["collection"].Value))
13111312
{
13121313
Variables[foreachParenthisEvaluationMatch.Groups["variableName"].Value] = foreachValue;
13131314

@@ -1847,7 +1848,9 @@ protected virtual bool EvaluateVarOrFunc(string expr, string restOfExpression, S
18471848
stack.Push(functionEvaluationEventArg.Value);
18481849
}
18491850
else
1851+
{
18501852
throw new ExpressionEvaluatorSyntaxErrorException($"[{objType}] object has no Method named \"{varFuncName}\".");
1853+
}
18511854
}
18521855
}
18531856
}
@@ -2029,7 +2032,7 @@ protected virtual bool EvaluateVarOrFunc(string expr, string restOfExpression, S
20292032
{
20302033
ExpressionOperator op = operatorsDictionary[varFuncMatch.Groups["assignmentPrefix"].Value];
20312034

2032-
varValue = operatorsEvaluations.ToList().Find(dict => dict.ContainsKey(op))[op](varValue, Evaluate(rightExpression));
2035+
varValue = OperatorsEvaluations.ToList().Find(dict => dict.ContainsKey(op))[op](varValue, Evaluate(rightExpression));
20332036
}
20342037
else
20352038
{
@@ -2137,7 +2140,7 @@ protected virtual bool EvaluateVarOrFunc(string expr, string restOfExpression, S
21372140

21382141
ExpressionOperator op = operatorsDictionary[varFuncMatch.Groups["assignmentPrefix"].Value];
21392142

2140-
cusVarValueToPush = operatorsEvaluations.ToList().Find(dict => dict.ContainsKey(op))[op](cusVarValueToPush, Evaluate(rightExpression));
2143+
cusVarValueToPush = OperatorsEvaluations.ToList().Find(dict => dict.ContainsKey(op))[op](cusVarValueToPush, Evaluate(rightExpression));
21412144
}
21422145
else
21432146
{
@@ -2455,9 +2458,9 @@ protected virtual bool EvaluateIndexing(string expr, string s, Stack<object> sta
24552458
{
24562459
ExpressionOperator prefixOp = operatorsDictionary[assignationOrPostFixOperatorMatch.Groups["assignmentPrefix"].Value];
24572460

2458-
valueToPush = operatorsEvaluations[0][op](left, right);
2461+
valueToPush = OperatorsEvaluations[0][op](left, right);
24592462

2460-
valueToPush = operatorsEvaluations.ToList().Find(dict => dict.ContainsKey(prefixOp))[prefixOp](valueToPush, Evaluate(rightExpression));
2463+
valueToPush = OperatorsEvaluations.ToList().Find(dict => dict.ContainsKey(prefixOp))[prefixOp](valueToPush, Evaluate(rightExpression));
24612464
}
24622465
else
24632466
{
@@ -2474,7 +2477,7 @@ protected virtual bool EvaluateIndexing(string expr, string s, Stack<object> sta
24742477
}
24752478
else
24762479
{
2477-
valueToPush = operatorsEvaluations[0][op](left, right);
2480+
valueToPush = OperatorsEvaluations[0][op](left, right);
24782481
}
24792482

24802483
stack.Push(valueToPush);
@@ -2621,7 +2624,7 @@ protected virtual object ProcessStack(Stack<object> stack)
26212624
.Select(e => e is ValueTypeNestingTrace valueTypeNestingTrace ? valueTypeNestingTrace.Value : e)
26222625
.ToList();
26232626

2624-
operatorsEvaluations.ToList().ForEach((IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>> operatorEvalutationsDict) =>
2627+
OperatorsEvaluations.ToList().ForEach((IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>> operatorEvalutationsDict) =>
26252628
{
26262629
for (int i = list.Count - 1; i >= 0; i--)
26272630
{
@@ -2631,13 +2634,13 @@ protected virtual object ProcessStack(Stack<object> stack)
26312634

26322635
if ((list[i] as ExpressionOperator) == eOp)
26332636
{
2634-
if (rightOperandOnlyOperatorsEvaluationDictionary.Contains(eOp))
2637+
if (RightOperandOnlyOperatorsEvaluationDictionary.Contains(eOp))
26352638
{
26362639
list[i] = operatorEvalutationsDict[eOp](null, (dynamic)list[i - 1]);
26372640
list.RemoveAt(i - 1);
26382641
break;
26392642
}
2640-
else if (leftOperandOnlyOperatorsEvaluationDictionary.Contains(eOp))
2643+
else if (LeftOperandOnlyOperatorsEvaluationDictionary.Contains(eOp))
26412644
{
26422645
list[i] = operatorEvalutationsDict[eOp]((dynamic)list[i + 1], null);
26432646
list.RemoveAt(i + 1);
@@ -2708,6 +2711,7 @@ public string RemoveComments(string scriptWithComments)
27082711
#region Utils methods for parsing and interpretation
27092712

27102713
private delegate dynamic InternalDelegate(params dynamic[] args);
2714+
27112715
private bool GetLambdaExpression(string expr, Stack<object> stack)
27122716
{
27132717
Match lambdaExpressionMatch = lambdaExpressionRegex.Match(expr);
@@ -3264,6 +3268,7 @@ public DelegateEncaps(InternalDelegate lambda)
32643268
{
32653269
this.lambda = lambda;
32663270
}
3271+
32673272
public DelegateEncaps(object target, MethodInfo methodInfo)
32683273
{
32693274
this.target = target;
@@ -3280,66 +3285,82 @@ public TResult Func0<TResult>()
32803285
{
32813286
return (TResult)lambda();
32823287
}
3288+
32833289
public TResult Func1<T, TResult>(T arg)
32843290
{
32853291
return (TResult)lambda(arg);
32863292
}
3293+
32873294
public TResult Func2<T1, T2, TResult>(T1 arg1, T2 arg2)
32883295
{
32893296
return (TResult)lambda(arg1, arg2);
32903297
}
3298+
32913299
public TResult Func3<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3)
32923300
{
32933301
return (TResult)lambda(arg1, arg2, arg3);
32943302
}
3303+
32953304
public TResult Func4<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
32963305
{
32973306
return (TResult)lambda(arg1, arg2, arg3, arg4);
32983307
}
3308+
32993309
public TResult Func5<T1, T2, T3, T4, T5, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
33003310
{
33013311
return (TResult)lambda(arg1, arg2, arg3, arg4, arg5);
33023312
}
3313+
33033314
public TResult Func6<T1, T2, T3, T4, T5, T6, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
33043315
{
33053316
return (TResult)lambda(arg1, arg2, arg3, arg4, arg5, arg6);
33063317
}
3318+
33073319
public TResult Func7<T1, T2, T3, T4, T5, T6, T7, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
33083320
{
33093321
return (TResult)lambda(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
33103322
}
3323+
33113324
public TResult Func8<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
33123325
{
33133326
return (TResult)lambda(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
33143327
}
3328+
33153329
public TResult Func9<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9)
33163330
{
33173331
return (TResult)lambda(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
33183332
}
3333+
33193334
public TResult Func10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10)
33203335
{
33213336
return (TResult)lambda(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
33223337
}
3338+
33233339
public TResult Func11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11)
33243340
{
33253341
return (TResult)lambda(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11);
33263342
}
3343+
33273344
public TResult Func12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12)
33283345
{
33293346
return (TResult)lambda(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
33303347
}
3348+
33313349
public TResult Func13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13)
33323350
{
33333351
return (TResult)lambda(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13);
33343352
}
3353+
33353354
public TResult Func14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14)
33363355
{
33373356
return (TResult)lambda(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14);
33383357
}
3358+
33393359
public TResult Func15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15)
33403360
{
33413361
return (TResult)lambda(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15);
33423362
}
3363+
33433364
public TResult Func16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16)
33443365
{
33453366
return (TResult)lambda(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16);
@@ -3425,6 +3446,13 @@ public bool Equals(ExpressionOperator otherOperator)
34253446

34263447
public static partial class OperatorsEvaluationsExtensions
34273448
{
3449+
public static IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> Copy(this IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> operatorsEvaluations)
3450+
{
3451+
return (IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>>)operatorsEvaluations
3452+
.Select(dic => (IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>)new Dictionary<ExpressionOperator, Func<dynamic, dynamic, object>>(dic))
3453+
.ToList();
3454+
}
3455+
34283456
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)
34293457
{
34303458
operatorsEvaluations
@@ -3478,6 +3506,20 @@ public static IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, objec
34783506

34793507
return operatorsEvaluations;
34803508
}
3509+
3510+
public static IList<ExpressionOperator> FluidAdd(this IList<ExpressionOperator> listOfOperator, ExpressionOperator operatorToAdd)
3511+
{
3512+
listOfOperator.Add(operatorToAdd);
3513+
3514+
return listOfOperator;
3515+
}
3516+
3517+
public static IList<ExpressionOperator> FluidRemove(this IList<ExpressionOperator> listOfOperator, ExpressionOperator operatorToRemove)
3518+
{
3519+
listOfOperator.Remove(operatorToRemove);
3520+
3521+
return listOfOperator;
3522+
}
34813523
}
34823524

34833525
#endregion

TryWindow/Properties/AssemblyInfo.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030

3131
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
3232

33-
3433
[assembly: ThemeInfo(
3534
ResourceDictionaryLocation.None, //où se trouvent les dictionnaires de ressources spécifiques à un thème
3635
//(utilisé si une ressource est introuvable dans la page,
@@ -40,7 +39,6 @@
4039
// dans l'application ou dans l'un des dictionnaires de ressources spécifiques à un thème)
4140
)]
4241

43-
4442
// Les informations de version pour un assembly se composent des quatre valeurs suivantes :
4543
//
4644
// Version principale

0 commit comments

Comments
 (0)