Parser and ExpressionNodes operate with the 3 types (decimal, string, bool)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace VAR.ExpressionEvaluator.Tests
|
||||
@@ -152,8 +153,8 @@ namespace VAR.ExpressionEvaluator.Tests
|
||||
public void Variables__Var1PlusVar2()
|
||||
{
|
||||
EvaluationContext evaluationContex = new EvaluationContext();
|
||||
evaluationContex.SetVariable("v1", 1m);
|
||||
evaluationContex.SetVariable("v2", 1m);
|
||||
evaluationContex.SetVariable("v1", 1);
|
||||
evaluationContex.SetVariable("v2", 1);
|
||||
string expression = "v1 + v2";
|
||||
object result = Parser.EvaluateString(expression, evaluationContex);
|
||||
Assert.AreEqual(2m, result);
|
||||
@@ -163,8 +164,8 @@ namespace VAR.ExpressionEvaluator.Tests
|
||||
public void Variables__Var1MultiplyVar2()
|
||||
{
|
||||
EvaluationContext evaluationContex = new EvaluationContext();
|
||||
evaluationContex.SetVariable("v1", 10m);
|
||||
evaluationContex.SetVariable("v2", 5m);
|
||||
evaluationContex.SetVariable("v1", 10);
|
||||
evaluationContex.SetVariable("v2", 5);
|
||||
string expression = "v1 * v2";
|
||||
object result = Parser.EvaluateString(expression, evaluationContex);
|
||||
Assert.AreEqual(50m, result);
|
||||
@@ -189,5 +190,71 @@ namespace VAR.ExpressionEvaluator.Tests
|
||||
|
||||
#endregion Functions
|
||||
|
||||
#region Strings
|
||||
|
||||
[TestMethod()]
|
||||
public void Strings__Contatenate_Hello_World()
|
||||
{
|
||||
string expression = "\"Hello\" + ' ' +\"World\"";
|
||||
object result = Parser.EvaluateString(expression);
|
||||
Assert.AreEqual("Hello World", result);
|
||||
}
|
||||
|
||||
[TestMethod()]
|
||||
public void Strings__Contatenate_Hello_World_WithVariables()
|
||||
{
|
||||
EvaluationContext evaluationContex = new EvaluationContext();
|
||||
evaluationContex.SetVariable("v1", "Hello");
|
||||
evaluationContex.SetVariable("v2", " ");
|
||||
evaluationContex.SetVariable("v3", "World");
|
||||
string expression = "v1 + v2 + v3";
|
||||
object result = Parser.EvaluateString(expression, evaluationContex);
|
||||
Assert.AreEqual("Hello World", result);
|
||||
}
|
||||
|
||||
[TestMethod()]
|
||||
public void Strings__Fail_Minus()
|
||||
{
|
||||
string expression = "'Hello' - 'World'";
|
||||
try
|
||||
{
|
||||
object result = Parser.EvaluateString(expression);
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod()]
|
||||
public void Strings__Fail_Multiply()
|
||||
{
|
||||
string expression = "'Hello' * 'World'";
|
||||
try
|
||||
{
|
||||
object result = Parser.EvaluateString(expression);
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod()]
|
||||
public void Strings__Fail_Division()
|
||||
{
|
||||
string expression = "'Hello' / 'World'";
|
||||
try
|
||||
{
|
||||
object result = Parser.EvaluateString(expression);
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Strings
|
||||
|
||||
}
|
||||
}
|
||||
17
VAR.ExpressionEvaluator/ExpressionBooleanNode.cs
Normal file
17
VAR.ExpressionEvaluator/ExpressionBooleanNode.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace VAR.ExpressionEvaluator
|
||||
{
|
||||
public class ExpressionBooleanNode : IExpressionNode
|
||||
{
|
||||
private bool _value;
|
||||
|
||||
public ExpressionBooleanNode(bool value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public object Eval(IEvaluationContext evaluationContext)
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace VAR.ExpressionEvaluator
|
||||
using System;
|
||||
|
||||
namespace VAR.ExpressionEvaluator
|
||||
{
|
||||
public class ExpressionDivisionNode : ExpressionBinaryNode
|
||||
{
|
||||
@@ -9,6 +11,27 @@
|
||||
|
||||
private static object DivisionOp(object leftValue, object rightValue)
|
||||
{
|
||||
if (leftValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)leftValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)leftValue));
|
||||
}
|
||||
leftValue = dec;
|
||||
}
|
||||
if (rightValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)rightValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)rightValue));
|
||||
}
|
||||
rightValue = dec;
|
||||
}
|
||||
|
||||
if ((leftValue is decimal) == false || (rightValue is decimal) == false)
|
||||
{
|
||||
throw new Exception("Can't divive non decimal values");
|
||||
}
|
||||
return (decimal)leftValue / (decimal)rightValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace VAR.ExpressionEvaluator
|
||||
using System;
|
||||
|
||||
namespace VAR.ExpressionEvaluator
|
||||
{
|
||||
public class ExpressionMinusNode : ExpressionBinaryNode
|
||||
{
|
||||
@@ -9,6 +11,27 @@
|
||||
|
||||
private static object MinusOp(object leftValue, object rightValue)
|
||||
{
|
||||
if (leftValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)leftValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)leftValue));
|
||||
}
|
||||
leftValue = dec;
|
||||
}
|
||||
if (rightValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)rightValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)rightValue));
|
||||
}
|
||||
rightValue = dec;
|
||||
}
|
||||
|
||||
if ((leftValue is decimal) == false || (rightValue is decimal) == false)
|
||||
{
|
||||
throw new Exception("Can't substract non decimal values");
|
||||
}
|
||||
return (decimal)leftValue - (decimal)rightValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace VAR.ExpressionEvaluator
|
||||
using System;
|
||||
|
||||
namespace VAR.ExpressionEvaluator
|
||||
{
|
||||
public class ExpressionMultiplyNode : ExpressionBinaryNode
|
||||
{
|
||||
@@ -9,6 +11,27 @@
|
||||
|
||||
private static object MultiplyOp(object leftValue, object rightValue)
|
||||
{
|
||||
if (leftValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)leftValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)leftValue));
|
||||
}
|
||||
leftValue = dec;
|
||||
}
|
||||
if (rightValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)rightValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)rightValue));
|
||||
}
|
||||
rightValue = dec;
|
||||
}
|
||||
|
||||
if ((leftValue is decimal) == false || (rightValue is decimal) == false)
|
||||
{
|
||||
throw new Exception("Can't multiply non decimal values");
|
||||
}
|
||||
return (decimal)leftValue * (decimal)rightValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace VAR.ExpressionEvaluator
|
||||
using System;
|
||||
|
||||
namespace VAR.ExpressionEvaluator
|
||||
{
|
||||
public class ExpressionNumberNegateNode : ExpressionUnaryNode
|
||||
{
|
||||
@@ -9,7 +11,20 @@
|
||||
|
||||
private static object NumberNegateOp(object value)
|
||||
{
|
||||
return - (decimal)value;
|
||||
if (value is string)
|
||||
{
|
||||
if (decimal.TryParse((string)value, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)value));
|
||||
}
|
||||
value = dec;
|
||||
}
|
||||
|
||||
if ((value is decimal) == false)
|
||||
{
|
||||
throw new Exception("Can't negate non decimal values");
|
||||
}
|
||||
return -(decimal)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace VAR.ExpressionEvaluator
|
||||
using System;
|
||||
|
||||
namespace VAR.ExpressionEvaluator
|
||||
{
|
||||
public class ExpressionPlusNode : ExpressionBinaryNode
|
||||
{
|
||||
@@ -9,6 +11,15 @@
|
||||
|
||||
private static object PlusOp(object leftValue, object rightValue)
|
||||
{
|
||||
if (leftValue is string || rightValue is string)
|
||||
{
|
||||
return string.Concat(Convert.ToString(leftValue), Convert.ToString(rightValue));
|
||||
}
|
||||
|
||||
if ((leftValue is decimal) == false || (rightValue is decimal) == false)
|
||||
{
|
||||
throw new Exception("Can't sum non decimal values");
|
||||
}
|
||||
return (decimal)leftValue + (decimal)rightValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,20 +99,27 @@ namespace VAR.ExpressionEvaluator
|
||||
return node;
|
||||
}
|
||||
|
||||
if (_tokenizer.Token == Token.ParenthesisStart)
|
||||
if (_tokenizer.Token == Token.String)
|
||||
{
|
||||
_tokenizer.NextToken();
|
||||
IExpressionNode node = ParsePlusAndMinus();
|
||||
if (_tokenizer.Token != Token.ParenthesisEnd)
|
||||
{
|
||||
throw new Exception("Missing close parenthesis");
|
||||
}
|
||||
IExpressionNode node = new ExpressionStringNode(_tokenizer.Text);
|
||||
_tokenizer.NextToken();
|
||||
return node;
|
||||
}
|
||||
|
||||
if (_tokenizer.Token == Token.Identifier)
|
||||
{
|
||||
string identifierToLower = _tokenizer.Text.ToLower();
|
||||
if (identifierToLower == "true")
|
||||
{
|
||||
_tokenizer.NextToken();
|
||||
return new ExpressionBooleanNode(true);
|
||||
}
|
||||
if (identifierToLower == "false")
|
||||
{
|
||||
_tokenizer.NextToken();
|
||||
return new ExpressionBooleanNode(false);
|
||||
}
|
||||
|
||||
string identifier = _tokenizer.Text;
|
||||
_tokenizer.NextToken();
|
||||
if (_tokenizer.Token != Token.ParenthesisStart)
|
||||
@@ -145,6 +152,18 @@ namespace VAR.ExpressionEvaluator
|
||||
}
|
||||
}
|
||||
|
||||
if (_tokenizer.Token == Token.ParenthesisStart)
|
||||
{
|
||||
_tokenizer.NextToken();
|
||||
IExpressionNode node = ParsePlusAndMinus();
|
||||
if (_tokenizer.Token != Token.ParenthesisEnd)
|
||||
{
|
||||
throw new Exception("Missing close parenthesis");
|
||||
}
|
||||
_tokenizer.NextToken();
|
||||
return node;
|
||||
}
|
||||
|
||||
throw new Exception(string.Format("Unexpected token: {0}", _tokenizer.Token.ToString()));
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="EvaluationContext.cs" />
|
||||
<Compile Include="ExpressionBooleanNode.cs" />
|
||||
<Compile Include="ExpressionDivisionNode.cs" />
|
||||
<Compile Include="ExpressionFunctionNode.cs" />
|
||||
<Compile Include="ExpressionMultiplyNode.cs" />
|
||||
|
||||
Reference in New Issue
Block a user