diff --git a/MathEngine/EngineTests/Parser Tests/Nodes/NodeFactoryTests.cs b/MathEngine/EngineTests/Parser Tests/Nodes/NodeFactoryTests.cs
index 9fbd311..51e1b2b 100644
--- a/MathEngine/EngineTests/Parser Tests/Nodes/NodeFactoryTests.cs
+++ b/MathEngine/EngineTests/Parser Tests/Nodes/NodeFactoryTests.cs
@@ -78,10 +78,8 @@ namespace EngineTests.Parser_Tests.Nodes
[TestMethod]
public void TestNodeFactoryNumericNodesOnDefinedTypes()
{
- Token test_token1 = new("100", Token.Type.Numeric, Token.NumericType.Integer, 0);
Token test_token2 = new("100.5", Token.Type.Numeric, Token.NumericType.Decimal, 0);
- BaseNode testNode1 = NodeFactory.CreateNumericNode(test_token1);
BaseNode testNode2 = NodeFactory.CreateNumericNode(test_token2);
}
diff --git a/MathEngine/MathEngine/MathEngine.csproj b/MathEngine/MathEngine/MathEngine.csproj
index 7824531..ba38089 100644
--- a/MathEngine/MathEngine/MathEngine.csproj
+++ b/MathEngine/MathEngine/MathEngine.csproj
@@ -8,6 +8,7 @@
+
diff --git a/MathEngine/MathEngine/Parser/Nodes/BaseNode.cs b/MathEngine/MathEngine/Parser/Nodes/BaseNode.cs
index 2390a8e..af77f73 100644
--- a/MathEngine/MathEngine/Parser/Nodes/BaseNode.cs
+++ b/MathEngine/MathEngine/Parser/Nodes/BaseNode.cs
@@ -105,6 +105,28 @@ namespace MathEngine.Parser.Parser
return lhs.Divide(rhs);
}
+ ///
+ /// Base method for exponentiating two nodes, returning another BaseNode object
+ ///
+ /// The node which will be the power to raise the current instance to
+ ///
+ ///
+ protected virtual BaseNode Exponentiate(BaseNode otherNode)
+ {
+ throw new InvalidOperationException("Attempted to call BaseNode _exponentiate, which is invalid!");
+ }
+
+ ///
+ /// Base operator for exponentiating two Base Nodes
+ ///
+ /// The left BaseNode
+ /// The right BaseNode
+ /// The exponentiating of the two BaseNodes, as defined by the calling type
+ public static BaseNode operator ^(BaseNode lhs, BaseNode rhs)
+ {
+ return lhs.Exponentiate(rhs);
+ }
+
///
/// Abstract Base method that evaluates the current Node
///
diff --git a/MathEngine/MathEngine/Parser/Nodes/NodeFactory.cs b/MathEngine/MathEngine/Parser/Nodes/NodeFactory.cs
index d631bc1..cf3cff6 100644
--- a/MathEngine/MathEngine/Parser/Nodes/NodeFactory.cs
+++ b/MathEngine/MathEngine/Parser/Nodes/NodeFactory.cs
@@ -27,7 +27,7 @@ namespace MathEngine.Parser.Parser
case Token.Type.Division:
return new BinaryNode(LeftBranch, RightBranch, (a, b) => a / b);
case Token.Type.Exponentiation:
- throw new NotImplementedException("Exponentiation is not implemented at this time");
+ return new BinaryNode(LeftBranch, RightBranch, (a, b) => a ^ b);
default:
throw new NotImplementedException("Attempted to create a BinaryNode with an invalid operation!");
}
@@ -43,11 +43,11 @@ namespace MathEngine.Parser.Parser
switch (CurrentToken.NumericalType)
{
case Token.NumericType.Integer:
- return new NumericNode(Int64.Parse(CurrentToken.TokenValue));
+ throw new NotImplementedException("Integer Numbers are not implemented at this time");
case Token.NumericType.Decimal:
- return new NumericNode(Decimal.Parse(CurrentToken.TokenValue));
+ return new NumericNode(Decimal.Parse(CurrentToken.TokenValue));
case Token.NumericType.Complex:
- throw new NotImplementedException("Complex Numbers are not implemented at this time");
+ throw new NotImplementedException("Complex Numbers are not implemented at this time");
default:
throw new InvalidDataException("Attempted to create a NumericNode with non numeric data!");
}
diff --git a/MathEngine/MathEngine/Parser/Nodes/NumericIntegerNode.cs b/MathEngine/MathEngine/Parser/Nodes/NumericIntegerNode.cs
new file mode 100644
index 0000000..ff72f69
--- /dev/null
+++ b/MathEngine/MathEngine/Parser/Nodes/NumericIntegerNode.cs
@@ -0,0 +1,90 @@
+using MathEngine.Parser.Parser;
+using MathEngine.Parser.Parser.Nodes;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MathEngine.Parser.Nodes
+{
+ internal class NumericIntegerNode: BaseNode
+ {
+ private readonly decimal Value;
+
+ ///
+ /// Initialises a new instance of a NumericNode with a given Token
+ ///
+ /// The token for the nodes value
+ public NumericIntegerNode(decimal value)
+ {
+ this.Children = null;
+ this.Value = value;
+ }
+
+ protected override BaseNode Add(BaseNode otherNode)
+ {
+ if (otherNode is NumericIntegerNode)
+ {
+ NumericIntegerNode rhs = (NumericIntegerNode)otherNode;
+ return new NumericIntegerNode(Value + rhs.Value);
+ }
+ throw new InvalidOperationException("Attempted Invalid operation");
+ }
+
+ protected override BaseNode Subtract(BaseNode otherNode)
+ {
+ if (otherNode is NumericIntegerNode)
+ {
+ NumericIntegerNode rhs = (NumericIntegerNode)otherNode;
+ return new NumericIntegerNode(Value - rhs.Value);
+ }
+ throw new InvalidOperationException("Attempted Invalid operation");
+ }
+
+ protected override BaseNode Multiply(BaseNode otherNode)
+ {
+ if (otherNode is NumericIntegerNode)
+ {
+ NumericIntegerNode rhs = (NumericIntegerNode)otherNode;
+ return new NumericIntegerNode(Value * rhs.Value);
+ }
+ throw new InvalidOperationException("Attempted Invalid operation");
+ }
+
+ protected override BaseNode Divide(BaseNode otherNode)
+ {
+ if (otherNode is NumericIntegerNode)
+ {
+ NumericIntegerNode rhs = (NumericIntegerNode)otherNode;
+ return new NumericIntegerNode(Value / rhs.Value);
+ }
+ throw new InvalidOperationException("Attempted Invalid operation");
+ }
+
+ protected override BaseNode Exponentiate(BaseNode otherNode)
+ {
+ if (otherNode is NumericIntegerNode)
+ {
+ NumericIntegerNode rhs = (NumericIntegerNode)otherNode;
+ return new NumericIntegerNode((Int64)(Math.Pow((double)(Value), (double)rhs.Value)));
+ }
+ throw new InvalidOperationException("Attempted Invalid operation");
+ }
+
+ ///
+ /// Evaluates the Numeric Node by simply returning the current instance
+ ///
+ ///
+ public override BaseNode Evaluate()
+ {
+ return this;
+ }
+
+ public override string ToString()
+ {
+ return Value.ToString();
+ }
+
+ }
+}
diff --git a/MathEngine/MathEngine/Parser/Nodes/NumericNode.cs b/MathEngine/MathEngine/Parser/Nodes/NumericNode.cs
index 0319948..259fac8 100644
--- a/MathEngine/MathEngine/Parser/Nodes/NumericNode.cs
+++ b/MathEngine/MathEngine/Parser/Nodes/NumericNode.cs
@@ -5,15 +5,15 @@ namespace MathEngine.Parser.Parser.Nodes
///
/// Represents a Tree node that can store a numeric value
///
- internal class NumericNode : BaseNode where T: INumber
+ internal class NumericNode : BaseNode where T: INumber
{
- private readonly T Value;
+ private readonly decimal Value;
///
/// Initialises a new instance of a NumericNode with a given Token
///
/// The token for the nodes value
- public NumericNode(T value)
+ public NumericNode(decimal value)
{
this.Children = null;
this.Value = value;
@@ -21,40 +21,50 @@ namespace MathEngine.Parser.Parser.Nodes
protected override BaseNode Add(BaseNode otherNode)
{
- if (otherNode is NumericNode)
+ if (otherNode is NumericNode)
{
- NumericNode rhs = (NumericNode)otherNode;
- return new NumericNode(Value + rhs.Value);
+ NumericNode rhs = (NumericNode)otherNode;
+ return new NumericNode(Value + rhs.Value);
}
throw new InvalidOperationException("Attempted Invalid operation");
}
protected override BaseNode Subtract(BaseNode otherNode)
{
- if (otherNode is NumericNode)
+ if (otherNode is NumericNode)
{
- NumericNode rhs = (NumericNode)otherNode;
- return new NumericNode(Value - rhs.Value);
+ NumericNode rhs = (NumericNode)otherNode;
+ return new NumericNode(Value - rhs.Value);
}
throw new InvalidOperationException("Attempted Invalid operation");
}
protected override BaseNode Multiply(BaseNode otherNode)
{
- if (otherNode is NumericNode)
+ if (otherNode is NumericNode)
{
- NumericNode rhs = (NumericNode)otherNode;
- return new NumericNode(Value * rhs.Value);
+ NumericNode rhs = (NumericNode)otherNode;
+ return new NumericNode(Value * rhs.Value);
}
throw new InvalidOperationException("Attempted Invalid operation");
}
protected override BaseNode Divide(BaseNode otherNode)
{
- if (otherNode is NumericNode)
+ if (otherNode is NumericNode)
{
- NumericNode rhs = (NumericNode)otherNode;
- return new NumericNode(Value / rhs.Value);
+ NumericNode rhs = (NumericNode)otherNode;
+ return new NumericNode(Value / rhs.Value);
+ }
+ throw new InvalidOperationException("Attempted Invalid operation");
+ }
+
+ protected override BaseNode Exponentiate(BaseNode otherNode)
+ {
+ if (otherNode is NumericNode)
+ {
+ NumericNode rhs = (NumericNode)otherNode;
+ return new NumericNode((decimal)(Math.Pow((double)Value, (double)(rhs.Value))));
}
throw new InvalidOperationException("Attempted Invalid operation");
}
diff --git a/MathEngine/MathEngine/Parser/Parser/Parser.cs b/MathEngine/MathEngine/Parser/Parser/Parser.cs
index b45ae77..45160d5 100644
--- a/MathEngine/MathEngine/Parser/Parser/Parser.cs
+++ b/MathEngine/MathEngine/Parser/Parser/Parser.cs
@@ -119,6 +119,7 @@ namespace MathEngine.Parser.Parser
case Token.Type.Subtraction:
case Token.Type.Multiplication:
case Token.Type.Division:
+ case Token.Type.Exponentiation:
while ((OperatorStack.Count != 0 && ((((OperatorStack.Peek().Token_Type == Token.Type.Function) | (OperatorPrecedence(OperatorStack.Peek()) > OperatorPrecedence(CurrentToken)) | ((OperatorPrecedence(OperatorStack.Peek()) == OperatorPrecedence(CurrentToken)) & (IsLeftAssociatve(CurrentToken)))) && !(OperatorStack.Peek().Token_Type == Token.Type.LeftParenthesis)))))
{
OutputStack.Push(OperatorStack.Pop());
diff --git a/MathEngine/MathEngine/Parser/Tokeniser/Token.cs b/MathEngine/MathEngine/Parser/Tokeniser/Token.cs
index 52ae344..8f6ede4 100644
--- a/MathEngine/MathEngine/Parser/Tokeniser/Token.cs
+++ b/MathEngine/MathEngine/Parser/Tokeniser/Token.cs
@@ -25,6 +25,11 @@
///
public static readonly Token Divide = new("/", Type.Division, NumericType.NaN, 0);
+ ///
+ /// Represents the token for ^
+ ///
+ public static readonly Token Exponentiation = new("^", Type.Exponentiation, NumericType.NaN, 0);
+
///
/// Enum representing the token type
///
diff --git a/MathEngine/MathEngine/Parser/Tokeniser/Tokeniser.cs b/MathEngine/MathEngine/Parser/Tokeniser/Tokeniser.cs
index 827c30c..0a3b57f 100644
--- a/MathEngine/MathEngine/Parser/Tokeniser/Tokeniser.cs
+++ b/MathEngine/MathEngine/Parser/Tokeniser/Tokeniser.cs
@@ -31,6 +31,7 @@
'-' => Token.Minus,
'*' => Token.Multiply,
'/' => Token.Divide,
+ '^' => Token.Exponentiation,
_ => throw new Exception(String.Format("Character {0} is not a defined operator", curChar)),
};
}