diff --git a/VAR.ExpressionEvaluator.Tests/ParserTests.cs b/VAR.ExpressionEvaluator.Tests/ParserTests.cs
index 2f49d42..eaa747f 100644
--- a/VAR.ExpressionEvaluator.Tests/ParserTests.cs
+++ b/VAR.ExpressionEvaluator.Tests/ParserTests.cs
@@ -5,6 +5,8 @@ namespace VAR.ExpressionEvaluator.Tests
[TestClass()]
public class ParserTests
{
+ #region Plus and Minus
+
[TestMethod()]
public void ParseString__Ten_EqualsTen()
{
@@ -37,6 +39,10 @@ namespace VAR.ExpressionEvaluator.Tests
Assert.AreEqual(900000m, result);
}
+ #endregion Plus and minus
+
+ #region Number signs
+
[TestMethod()]
public void ParseString__MinusTen()
{
@@ -77,5 +83,67 @@ namespace VAR.ExpressionEvaluator.Tests
Assert.AreEqual(-40m, result);
}
+ #endregion Number signs
+
+ #region Multiplication and division
+
+ [TestMethod()]
+ public void ParseString__10MutiplyBy2()
+ {
+ string expression = "10 * 2";
+ object result = Parser.EvaluateString(expression);
+ Assert.AreEqual(20m, result);
+ }
+
+ [TestMethod()]
+ public void ParseString__10DividedBy2()
+ {
+ string expression = "10 / 2";
+ object result = Parser.EvaluateString(expression);
+ Assert.AreEqual(5m, result);
+ }
+
+ [TestMethod()]
+ public void ParseString__5DividedBy2()
+ {
+ string expression = "5 / 2";
+ object result = Parser.EvaluateString(expression);
+ Assert.AreEqual(2.5m, result);
+ }
+
+ [TestMethod()]
+ public void ParseString__5DividedBy2Plus1()
+ {
+ string expression = "5 / 2 + 1";
+ object result = Parser.EvaluateString(expression);
+ Assert.AreEqual(3.5m, result);
+ }
+
+ [TestMethod()]
+ public void ParseString__1Plus5DividedBy2()
+ {
+ string expression = "1 + 5 / 2";
+ object result = Parser.EvaluateString(expression);
+ Assert.AreEqual(3.5m, result);
+ }
+
+ [TestMethod()]
+ public void ParseString__5DividedByParen1Plus1()
+ {
+ string expression = "5 / (1 + 1)";
+ object result = Parser.EvaluateString(expression);
+ Assert.AreEqual(2.5m, result);
+ }
+
+ [TestMethod()]
+ public void ParseString__Paren2Plus2DividedByParen1Plus1()
+ {
+ string expression = "(2 + 2) / (1 + 1)";
+ object result = Parser.EvaluateString(expression);
+ Assert.AreEqual(2m, result);
+ }
+
+ #endregion Multiplication and division
+
}
}
\ No newline at end of file
diff --git a/VAR.ExpressionEvaluator.Tests/TokenizerTests.cs b/VAR.ExpressionEvaluator.Tests/TokenizerTests.cs
index fc6205b..24224c3 100644
--- a/VAR.ExpressionEvaluator.Tests/TokenizerTests.cs
+++ b/VAR.ExpressionEvaluator.Tests/TokenizerTests.cs
@@ -120,7 +120,7 @@ namespace VAR.ExpressionEvaluator.Tests
var t = new Tokenizer(new StringReader(testString));
// "("
- Assert.AreEqual(t.Token, Token.ParentesisStart);
+ Assert.AreEqual(t.Token, Token.ParenthesisStart);
t.NextToken();
// "10"
@@ -138,7 +138,7 @@ namespace VAR.ExpressionEvaluator.Tests
t.NextToken();
// ")"
- Assert.AreEqual(t.Token, Token.ParentesisEnd);
+ Assert.AreEqual(t.Token, Token.ParenthesisEnd);
t.NextToken();
// "*"
diff --git a/VAR.ExpressionEvaluator/ExpressionDivisionNode.cs b/VAR.ExpressionEvaluator/ExpressionDivisionNode.cs
new file mode 100644
index 0000000..babf853
--- /dev/null
+++ b/VAR.ExpressionEvaluator/ExpressionDivisionNode.cs
@@ -0,0 +1,15 @@
+namespace VAR.ExpressionEvaluator
+{
+ public class ExpressionDivisionNode : ExpressionBinaryNode
+ {
+ public ExpressionDivisionNode(IExpressionNode leftNode, IExpressionNode rightNode) :
+ base(leftNode, rightNode, DivisionOp)
+ {
+ }
+
+ private static object DivisionOp(object leftValue, object rightValue)
+ {
+ return (decimal)leftValue / (decimal)rightValue;
+ }
+ }
+}
diff --git a/VAR.ExpressionEvaluator/ExpressionMultiplyNode.cs b/VAR.ExpressionEvaluator/ExpressionMultiplyNode.cs
new file mode 100644
index 0000000..fed99db
--- /dev/null
+++ b/VAR.ExpressionEvaluator/ExpressionMultiplyNode.cs
@@ -0,0 +1,15 @@
+namespace VAR.ExpressionEvaluator
+{
+ public class ExpressionMultiplyNode : ExpressionBinaryNode
+ {
+ public ExpressionMultiplyNode(IExpressionNode leftNode, IExpressionNode rightNode) :
+ base(leftNode, rightNode, MultiplyOp)
+ {
+ }
+
+ private static object MultiplyOp(object leftValue, object rightValue)
+ {
+ return (decimal)leftValue * (decimal)rightValue;
+ }
+ }
+}
diff --git a/VAR.ExpressionEvaluator/Parser.cs b/VAR.ExpressionEvaluator/Parser.cs
index e1088db..dbf6f4b 100644
--- a/VAR.ExpressionEvaluator/Parser.cs
+++ b/VAR.ExpressionEvaluator/Parser.cs
@@ -26,19 +26,19 @@ namespace VAR.ExpressionEvaluator
public IExpressionNode ParsePlusAndMinus()
{
- IExpressionNode leftNode = ParseUnary();
+ IExpressionNode leftNode = ParseMultiplyDivision();
while (true)
{
if (_tokenizer.Token == Token.Plus)
{
_tokenizer.NextToken();
- IExpressionNode rightNode = ParseUnary();
+ IExpressionNode rightNode = ParseMultiplyDivision();
leftNode = new ExpressionPlusNode(leftNode, rightNode);
}
else if (_tokenizer.Token == Token.Minus)
{
_tokenizer.NextToken();
- IExpressionNode rightNode = ParseUnary();
+ IExpressionNode rightNode = ParseMultiplyDivision();
leftNode = new ExpressionMinusNode(leftNode, rightNode);
}
else
@@ -48,6 +48,31 @@ namespace VAR.ExpressionEvaluator
}
}
+ private IExpressionNode ParseMultiplyDivision()
+ {
+ IExpressionNode lhs = ParseUnary();
+ while (true)
+ {
+ if (_tokenizer.Token == Token.Multiply)
+ {
+ _tokenizer.NextToken();
+ IExpressionNode rhs = ParseUnary();
+ lhs = new ExpressionMultiplyNode(lhs, rhs);
+
+ }
+ else if (_tokenizer.Token == Token.Division)
+ {
+ _tokenizer.NextToken();
+ IExpressionNode rhs = ParseUnary();
+ lhs = new ExpressionDivisionNode(lhs, rhs);
+ }
+ else
+ {
+ return lhs;
+ }
+ }
+ }
+
private IExpressionNode ParseUnary()
{
if (_tokenizer.Token == Token.Plus)
@@ -73,6 +98,18 @@ namespace VAR.ExpressionEvaluator
return node;
}
+ if (_tokenizer.Token == Token.ParenthesisStart)
+ {
+ _tokenizer.NextToken();
+ var 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()));
}
diff --git a/VAR.ExpressionEvaluator/Token.cs b/VAR.ExpressionEvaluator/Token.cs
index abc5f1b..0f58508 100644
--- a/VAR.ExpressionEvaluator/Token.cs
+++ b/VAR.ExpressionEvaluator/Token.cs
@@ -13,8 +13,8 @@
GreaterOrEqualThan,
LessThan,
LessOrEqualThan,
- ParentesisStart,
- ParentesisEnd,
+ ParenthesisStart,
+ ParenthesisEnd,
Keyword,
String,
Number,
diff --git a/VAR.ExpressionEvaluator/Tokenizer.cs b/VAR.ExpressionEvaluator/Tokenizer.cs
index 57f9e8b..8f942c3 100644
--- a/VAR.ExpressionEvaluator/Tokenizer.cs
+++ b/VAR.ExpressionEvaluator/Tokenizer.cs
@@ -93,12 +93,12 @@ namespace VAR.ExpressionEvaluator
case '(':
NextChar();
- _currentToken = Token.ParentesisStart;
+ _currentToken = Token.ParenthesisStart;
return;
case ')':
NextChar();
- _currentToken = Token.ParentesisEnd;
+ _currentToken = Token.ParenthesisEnd;
return;
case '=':
diff --git a/VAR.ExpressionEvaluator/VAR.ExpressionEvaluator.csproj b/VAR.ExpressionEvaluator/VAR.ExpressionEvaluator.csproj
index 02cb27b..95f1893 100644
--- a/VAR.ExpressionEvaluator/VAR.ExpressionEvaluator.csproj
+++ b/VAR.ExpressionEvaluator/VAR.ExpressionEvaluator.csproj
@@ -41,6 +41,8 @@
+
+