Skip to content
Merged

Dev #171

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Newtonsoft.Json;
using Microsoft.CSharp.RuntimeBinder;
using Newtonsoft.Json;
using NUnit.Framework;
using Shouldly;
using System;
Expand Down Expand Up @@ -1837,6 +1838,15 @@ public void Evaluate_DoubleDoubleQuotesInEscapedStringThrowException()

evaluator.Evaluate("@\"Hello \"\" Joe\"").ShouldBe(@"Hello "" Joe");
}

[Test]
[Category("Bug")]
public void Evaluate_NullAdditionShouldThrowExceptionNotReturnString()
{
var evaluator = new ExpressionEvaluator();

Should.Throw<RuntimeBinderException>(() => evaluator.Evaluate("(null + null) + null"));
}

//[Test]
//[Category("Bug")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<Product>CodingSeb.ExpressionEvaluator</Product>
<Description>A Simple Math and Pseudo C# Expression Evaluator in One C# File. Can also execute small C# like scripts</Description>
<Copyright>Copyright © Coding Seb 2017</Copyright>
<Version>1.4.40.0</Version>
<AssemblyVersion>1.4.40.0</AssemblyVersion>
<FileVersion>1.4.40.0</FileVersion>
<Version>1.4.41.0</Version>
<AssemblyVersion>1.4.41.0</AssemblyVersion>
<FileVersion>1.4.41.0</FileVersion>
<OutputPath>bin\$(Configuration)\</OutputPath>
<Authors>Coding Seb</Authors>
<PackageId>CodingSeb.ExpressionEvaluator</PackageId>
Expand All @@ -20,9 +20,7 @@
<PackageIconUrl>https://github.com/codingseb/ExpressionEvaluator/blob/master/Icon.png?raw=true</PackageIconUrl>
<PackageIcon>Icon.png</PackageIcon>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageReleaseNotes>* Make shared cache for types resolution thread safe
* Add ScriptEvaluating and ScriptEvaluated events
* Add unaryOperatorsDictionary to manage custom operators that are both unaries and binaries better</PackageReleaseNotes>
<PackageReleaseNotes>* fix: addition of null and bubble container</PackageReleaseNotes>
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
<RepositoryUrl>https://github.com/codingseb/ExpressionEvaluator</RepositoryUrl>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand Down
60 changes: 30 additions & 30 deletions CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/******************************************************************************************************
Title : ExpressionEvaluator (https://github.com/codingseb/ExpressionEvaluator)
Version : 1.4.40.0
Version : 1.4.41.0
(if last digit (the forth) is not a zero, the version is an intermediate version and can be unstable)

Author : Coding Seb
Expand Down Expand Up @@ -242,56 +242,56 @@ protected enum TryBlockEvaluatedState
{
new Dictionary<ExpressionOperator, Func<dynamic, dynamic, object>>()
{
{ExpressionOperator.UnaryPlus, (dynamic _, dynamic right) => +right },
{ExpressionOperator.UnaryMinus, (dynamic _, dynamic right) => -right },
{ExpressionOperator.LogicalNegation, (dynamic _, dynamic right) => !right },
{ExpressionOperator.BitwiseComplement, (dynamic _, dynamic right) => ~right },
{ExpressionOperator.Cast, (dynamic left, dynamic right) => ChangeType(right, left) },
{ExpressionOperator.UnaryPlus, (_, right) => +right },
{ExpressionOperator.UnaryMinus, (_, right) => -right },
{ExpressionOperator.LogicalNegation, (_, right) => !right },
{ExpressionOperator.BitwiseComplement, (_, right) => ~right },
{ExpressionOperator.Cast, (left, right) => ChangeType(right, left) },
},
new Dictionary<ExpressionOperator, Func<dynamic, dynamic, object>>()
{
{ExpressionOperator.Multiply, (dynamic left, dynamic right) => left * right },
{ExpressionOperator.Divide, (dynamic left, dynamic right) => left / right },
{ExpressionOperator.Modulo, (dynamic left, dynamic right) => left % right },
{ExpressionOperator.Multiply, (left, right) => left * right },
{ExpressionOperator.Divide, (left, right) => left / right },
{ExpressionOperator.Modulo, (left, right) => left % right },
},
new Dictionary<ExpressionOperator, Func<dynamic, dynamic, object>>()
{
{ExpressionOperator.Plus, (dynamic left, dynamic right) => left + right },
{ExpressionOperator.Minus, (dynamic left, dynamic right) => left - right },
{ExpressionOperator.Plus, (left, right) => left + right },
{ExpressionOperator.Minus, (left, right) => left - right },
},
new Dictionary<ExpressionOperator, Func<dynamic, dynamic, object>>()
{
{ExpressionOperator.ShiftBitsLeft, (dynamic left, dynamic right) => left << right },
{ExpressionOperator.ShiftBitsRight, (dynamic left, dynamic right) => left >> right },
{ExpressionOperator.ShiftBitsLeft, (left, right) => left << right },
{ExpressionOperator.ShiftBitsRight, (left, right) => left >> right },
},
new Dictionary<ExpressionOperator, Func<dynamic, dynamic, object>>()
{
{ExpressionOperator.Lower, (dynamic left, dynamic right) => left < right },
{ExpressionOperator.Greater, (dynamic left, dynamic right) => left > right },
{ExpressionOperator.LowerOrEqual, (dynamic left, dynamic right) => left <= right },
{ExpressionOperator.GreaterOrEqual, (dynamic left, dynamic right) => left >= right },
{ExpressionOperator.Is, (dynamic left, dynamic right) => left != null && (((ClassOrEnumType)right).Type).IsAssignableFrom(left.GetType()) },
{ExpressionOperator.Lower, (left, right) => left < right },
{ExpressionOperator.Greater, (left, right) => left > right },
{ExpressionOperator.LowerOrEqual, (left, right) => left <= right },
{ExpressionOperator.GreaterOrEqual, (left, right) => left >= right },
{ExpressionOperator.Is, (left, right) => left != null && (((ClassOrEnumType)right).Type).IsAssignableFrom(left.GetType()) },
},
new Dictionary<ExpressionOperator, Func<dynamic, dynamic, object>>()
{
{ExpressionOperator.Equal, (dynamic left, dynamic right) => left == right },
{ExpressionOperator.NotEqual, (dynamic left, dynamic right) => left != right },
{ExpressionOperator.Equal, (left, right) => left == right },
{ExpressionOperator.NotEqual, (left, right) => left != right },
},
new Dictionary<ExpressionOperator, Func<dynamic, dynamic, object>>()
{
{ExpressionOperator.LogicalAnd, (dynamic left, dynamic right) => left & right },
{ExpressionOperator.LogicalAnd, (left, right) => left & right },
},
new Dictionary<ExpressionOperator, Func<dynamic, dynamic, object>>()
{
{ExpressionOperator.LogicalXor, (dynamic left, dynamic right) => left ^ right },
{ExpressionOperator.LogicalXor, (left, right) => left ^ right },
},
new Dictionary<ExpressionOperator, Func<dynamic, dynamic, object>>()
{
{ExpressionOperator.LogicalOr, (dynamic left, dynamic right) => left | right },
{ExpressionOperator.LogicalOr, (left, right) => left | right },
},
new Dictionary<ExpressionOperator, Func<dynamic, dynamic, object>>()
{
{ExpressionOperator.ConditionalAnd, (dynamic left, dynamic right) => {
{ExpressionOperator.ConditionalAnd, (left, right) => {
if ( left is BubbleExceptionContainer leftExceptionContainer)
{
leftExceptionContainer.Throw();
Expand All @@ -314,7 +314,7 @@ protected enum TryBlockEvaluatedState
},
new Dictionary<ExpressionOperator, Func<dynamic, dynamic, object>>()
{
{ExpressionOperator.ConditionalOr, (dynamic left, dynamic right) => {
{ExpressionOperator.ConditionalOr, (left, right) => {
if ( left is BubbleExceptionContainer leftExceptionContainer)
{
leftExceptionContainer.Throw();
Expand All @@ -337,7 +337,7 @@ protected enum TryBlockEvaluatedState
},
new Dictionary<ExpressionOperator, Func<dynamic, dynamic, object>>()
{
{ExpressionOperator.NullCoalescing, (dynamic left, dynamic right) => left ?? right },
{ExpressionOperator.NullCoalescing, (left, right) => left ?? right },
},
};

Expand Down Expand Up @@ -3206,7 +3206,7 @@ protected virtual object ProcessStack(Stack<object> stack)
.Select(e => e is NullConditionalNullValue ? null : e)
.ToList();

OperatorsEvaluations.ToList().ForEach((IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>> operatorEvalutationsDict) =>
OperatorsEvaluations.ToList().ForEach(operatorEvalutationsDict =>
{
for (int i = list.Count - 1; i >= 0; i--)
{
Expand Down Expand Up @@ -3296,11 +3296,11 @@ void EvaluateFirstPreviousUnaryOp(int j)
{
list[i] = operatorEvalutationsDict[eOp](left, right);

if (left is BubbleExceptionContainer && right is string)
if (left is BubbleExceptionContainer && (right == null || right is string))
{
list[i] = left; //Bubble up the causing error
}
else if (right is BubbleExceptionContainer && left is string)
else if (right is BubbleExceptionContainer && (left is string || left is null))
{
list[i] = right; //Bubble up the causing error
}
Expand Down Expand Up @@ -3481,7 +3481,7 @@ protected virtual bool GetLambdaExpression(string expression, Stack<object> stac

bool inScriptAtDeclaration = inScript;

stack.Push(new InternalDelegate((object[] args) =>
stack.Push(new InternalDelegate(args =>
{
var vars = new Dictionary<string, object>(variables);

Expand Down