From 49941a78614132602d624ba098fc26c3a0e0bd28 Mon Sep 17 00:00:00 2001 From: "Valeriano A.R" Date: Sun, 1 Dec 2019 13:59:46 +0100 Subject: [PATCH] Parser: Parse number negation. --- VAR.ExpressionEvaluator.Tests/ParserTests.cs | 41 +++++++++++++++++++ .../ExpressionNumberNegateNode.cs | 15 +++++++ .../ExpressionUnaryNode.cs | 24 +++++++++++ VAR.ExpressionEvaluator/Parser.cs | 22 ++++++++-- .../VAR.ExpressionEvaluator.csproj | 2 + 5 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 VAR.ExpressionEvaluator/ExpressionNumberNegateNode.cs create mode 100644 VAR.ExpressionEvaluator/ExpressionUnaryNode.cs diff --git a/VAR.ExpressionEvaluator.Tests/ParserTests.cs b/VAR.ExpressionEvaluator.Tests/ParserTests.cs index e2b348b..2f49d42 100644 --- a/VAR.ExpressionEvaluator.Tests/ParserTests.cs +++ b/VAR.ExpressionEvaluator.Tests/ParserTests.cs @@ -36,5 +36,46 @@ namespace VAR.ExpressionEvaluator.Tests object result = Parser.EvaluateString(expression); Assert.AreEqual(900000m, result); } + + [TestMethod()] + public void ParseString__MinusTen() + { + string expression = "-10"; + object result = Parser.EvaluateString(expression); + Assert.AreEqual(-10m, result); + } + + [TestMethod()] + public void ParseString__PlusTen() + { + string expression = "+10"; + object result = Parser.EvaluateString(expression); + Assert.AreEqual(10m, result); + } + + [TestMethod()] + public void ParseString__MinusMinusTen() + { + string expression = "--10"; + object result = Parser.EvaluateString(expression); + Assert.AreEqual(10m, result); + } + + [TestMethod()] + public void ParseString__MinusPlusChainTen() + { + string expression = "--++-+-10"; + object result = Parser.EvaluateString(expression); + Assert.AreEqual(10m, result); + } + + [TestMethod()] + public void ParseString__10Minus20Minus30() + { + string expression = "10 + -20 - +30"; + object result = Parser.EvaluateString(expression); + Assert.AreEqual(-40m, result); + } + } } \ No newline at end of file diff --git a/VAR.ExpressionEvaluator/ExpressionNumberNegateNode.cs b/VAR.ExpressionEvaluator/ExpressionNumberNegateNode.cs new file mode 100644 index 0000000..4dc3aef --- /dev/null +++ b/VAR.ExpressionEvaluator/ExpressionNumberNegateNode.cs @@ -0,0 +1,15 @@ +namespace VAR.ExpressionEvaluator +{ + public class ExpressionNumberNegateNode : ExpressionUnaryNode + { + public ExpressionNumberNegateNode(IExpressionNode node) : + base(node, NumberNegateOp) + { + } + + private static object NumberNegateOp(object value) + { + return - (decimal)value; + } + } +} diff --git a/VAR.ExpressionEvaluator/ExpressionUnaryNode.cs b/VAR.ExpressionEvaluator/ExpressionUnaryNode.cs new file mode 100644 index 0000000..e975ec0 --- /dev/null +++ b/VAR.ExpressionEvaluator/ExpressionUnaryNode.cs @@ -0,0 +1,24 @@ +using System; + +namespace VAR.ExpressionEvaluator +{ + public class ExpressionUnaryNode : IExpressionNode + { + private IExpressionNode _node; + private readonly Func _operation; + + public ExpressionUnaryNode(IExpressionNode node, Func operation) + { + _node = node; + _operation = operation; + } + + public object Eval() + { + object value = _node.Eval(); + + object result = _operation(value); + return result; + } + } +} diff --git a/VAR.ExpressionEvaluator/Parser.cs b/VAR.ExpressionEvaluator/Parser.cs index 922f3fd..e1088db 100644 --- a/VAR.ExpressionEvaluator/Parser.cs +++ b/VAR.ExpressionEvaluator/Parser.cs @@ -26,19 +26,19 @@ namespace VAR.ExpressionEvaluator public IExpressionNode ParsePlusAndMinus() { - IExpressionNode leftNode = ParseTerminus(); + IExpressionNode leftNode = ParseUnary(); while (true) { if (_tokenizer.Token == Token.Plus) { _tokenizer.NextToken(); - IExpressionNode rightNode = ParseTerminus(); + IExpressionNode rightNode = ParseUnary(); leftNode = new ExpressionPlusNode(leftNode, rightNode); } else if (_tokenizer.Token == Token.Minus) { _tokenizer.NextToken(); - IExpressionNode rightNode = ParseTerminus(); + IExpressionNode rightNode = ParseUnary(); leftNode = new ExpressionMinusNode(leftNode, rightNode); } else @@ -48,6 +48,22 @@ namespace VAR.ExpressionEvaluator } } + private IExpressionNode ParseUnary() + { + if (_tokenizer.Token == Token.Plus) + { + _tokenizer.NextToken(); + return ParseUnary(); + } + if (_tokenizer.Token == Token.Minus) + { + _tokenizer.NextToken(); + var node = ParseUnary(); + return new ExpressionNumberNegateNode(node); + } + return ParseTerminus(); + } + private IExpressionNode ParseTerminus() { if (_tokenizer.Token == Token.Number) diff --git a/VAR.ExpressionEvaluator/VAR.ExpressionEvaluator.csproj b/VAR.ExpressionEvaluator/VAR.ExpressionEvaluator.csproj index cbd95dd..02cb27b 100644 --- a/VAR.ExpressionEvaluator/VAR.ExpressionEvaluator.csproj +++ b/VAR.ExpressionEvaluator/VAR.ExpressionEvaluator.csproj @@ -41,8 +41,10 @@ + +