WIP: Implemented a rough system for function evaluation

This commit is contained in:
Jim
2025-10-29 22:32:22 +00:00
parent c527e59b57
commit 16c27a0070
17 changed files with 1147 additions and 86 deletions

View File

@@ -1,4 +1,5 @@
using MathEngine.Tokenizer;
using MathEngine.Functions.BuiltIns;
using MathEngine.Tokenizer;
using System.Security;
using static MathEngine.Tokenizer.Token;
@@ -155,8 +156,10 @@ namespace MathEngine.Parser
Stack<Token> OperatorStack = new(Expression.Count/2);
//The final stack to return
Queue<Token> rpnQueue = new(Expression.Count);
//Stack used to hold the number of input params to a function
//Stack<uint> ArityStack = new Stack<uint>();
// Stack that is used to handle nested function argument counts
Stack<UInt32> arityStack = new();
Token PreviousToken = Token.None;
Token CurrentToken;
@@ -179,8 +182,33 @@ namespace MathEngine.Parser
PopOperatorsToQueue(OperatorStack, rpnQueue, CurrentToken);
OperatorStack.Push(CurrentToken);
break;
case TokenType.Function:
OperatorStack.Push(CurrentToken);
case TokenType.GenericIdentifier:
// few things to consider
// 1 Check built-ins
if (i + 1 < Expression.Count && Expression[i + 1].Type == TokenType.LeftParenthesis && BuiltIns.IsFunction(CurrentToken.Value))
{
OperatorStack.Push(CurrentToken with { Type = Token.TokenType.Function });
arityStack.Push(1); // at least one arg must be present
break;
}
// 2 check user defined functions
// TODO: Implement User definable functions
// 3 check to see if it is a user defined variable
// TODO: Implement user definable variables
// 4 assume it is an implict multiplication
// TODO: Split identifier into letters and insert implicit multiplication
break;
case TokenType.FunctionArgumentSeparator:
if (arityStack.Count == 0)
throw new ParserException("Unexpected function arguement separator");
// Pop operators until the last LeftParenthesis
while (OperatorStack.Count > 0 && OperatorStack.Peek().Type != TokenType.LeftParenthesis)
rpnQueue.Enqueue(OperatorStack.Pop());
// increment the argument counter
arityStack.Push(arityStack.Pop() + 1);
break;
case TokenType.LeftParenthesis:
OperatorStack.Push(CurrentToken);
@@ -198,7 +226,7 @@ namespace MathEngine.Parser
if (OperatorStack.Count > 0 && (OperatorStack.Peek().Type == TokenType.Function))
{
rpnQueue.Enqueue(OperatorStack.Pop());
rpnQueue.Enqueue(OperatorStack.Pop() with { Arity = arityStack.Pop()});
}
break;
}