mirror of
https://github.com/0xJ1M/MathsEngine.git
synced 2026-06-05 01:00:06 +00:00
95 lines
4.0 KiB
C#
95 lines
4.0 KiB
C#
using MathEngine.Functions.BuiltIns;
|
|
using MathEngine.Tokenizer;
|
|
using MathEngine.Types;
|
|
using MathEngine.Types.Interfaces;
|
|
using System.Runtime.Intrinsics.X86;
|
|
using Xunit.Sdk;
|
|
using static MathEngine.Tokenizer.Token;
|
|
|
|
namespace MathEngine.AST.Nodes
|
|
{
|
|
/// <summary>
|
|
/// Factory that creates a TreeNode
|
|
/// </summary>
|
|
internal class NodeFactory
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
/// Creates a binary TreeNode, that is a node with a root value and two children
|
|
/// </summary>
|
|
/// <param name="CurrentToken">The token to be the root node of the TreeNode</param>
|
|
/// <param name="LeftToken">TreeNode that is the left branch of the current node</param>
|
|
/// <param name="RightToken">TreeNode that is the right branch of the current node</param>
|
|
/// <returns>A TreeNode with CurrentToken as the root value and LeftBranch and RightBranch as Children</returns>
|
|
public static BaseNode CreateBinaryNode(Token CurrentToken, BaseNode LeftBranch, BaseNode RightBranch)
|
|
{
|
|
switch (CurrentToken.Type)
|
|
{
|
|
case TokenType.Addition:
|
|
return new BinaryNode(LeftBranch, RightBranch, (a, b) => a + b);
|
|
case TokenType.Subtraction:
|
|
return new BinaryNode(LeftBranch, RightBranch, (a, b) => a - b);
|
|
case TokenType.Multiplication:
|
|
return new BinaryNode(LeftBranch, RightBranch, (a, b) => a * b);
|
|
case TokenType.Division:
|
|
return new BinaryNode(LeftBranch, RightBranch, (a, b) => a / b);
|
|
case TokenType.Exponentiation:
|
|
throw new NotImplementedException("Exponentiation is not supported 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!");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a Function Node, that is a node that operates a number of arguments
|
|
/// </summary>
|
|
/// <param name="FunctionToken">The function to create the node for</param>
|
|
/// <param name="ArgumentStack">Reference to Stack of BaseNode objects to take the arguments from</param>
|
|
/// <returns></returns>
|
|
public static BaseNode CreateFunctionNode(Token FunctionToken, Stack<BaseNode> ArgumentStack)
|
|
{
|
|
int argc = (int)FunctionToken.Arity;
|
|
|
|
INumericNode[] argsv = new INumericNode[argc];
|
|
|
|
for (int i = argc; i > 0; i--)
|
|
{
|
|
// TODO: Update so either INumeric or function nodes are allowed
|
|
// this will enable nested functions
|
|
if (ArgumentStack.Peek() is INumericNode numericNode)
|
|
{
|
|
argsv[i - 1] = numericNode;
|
|
ArgumentStack.Pop();
|
|
}
|
|
else
|
|
{
|
|
throw new InvalidOperationException("Function arguments implement INumericNode.");
|
|
}
|
|
}
|
|
return new FunctionNode(BuiltIns.GetFunction(FunctionToken.Value), argsv);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a Function Node, that is a node that operates a number of arguments
|
|
/// </summary>
|
|
/// <param name="FunctionToken">The function to create the node for</param>
|
|
/// <param name="ArgumentStack">Reference to Stack of BaseNode objects to take the arguments from</param>
|
|
/// <returns></returns>
|
|
public static BaseNode CreateNumericNode(Token NumericToken)
|
|
{
|
|
if (NumericToken.Type != TokenType.Numeric)
|
|
{
|
|
throw new ArgumentException("Token is not of a numeric type");
|
|
}
|
|
if (!(decimal.TryParse(NumericToken.Value, out decimal res)))
|
|
{
|
|
throw new ArgumentException("Failure to parse number");
|
|
}
|
|
return new NumericallyOrderableNode<DecimalValue>(new DecimalValue(res));
|
|
}
|
|
|
|
}
|
|
}
|