internal static bool IsFunction(Evaluatable evaluatable, out FunctionComponent function) { var component = Componentizer.ToComponent(evaluatable); if (component is FunctionComponent) { function = (FunctionComponent)component; return true; } function = null; return false; }
private static Expression ParsePostfix(IEnumerable<Token> tokens, Dictionary<string, Expression> variableMap) { var stack = new Stack<Evaluatable>(); foreach (var token in tokens) { if (token.Type.IsOperand()) { if (token is ExpressionListToken) { stack.Push(((ExpressionListToken)token).List); } else { stack.Push(new SingleFactorComponent(ParseOperand(token, variableMap))); } } else if (token.Type == TokenType.Function) { var operands = new List<Expression>(); var operatorCount = FunctionRepository.Get(token.Value).ArgumentCount; for (var i = 0; i < operatorCount; i++) { operands.Add(Expressionizer.ToExpression(stack.Pop())); } operands.Reverse(); stack.Push(new FunctionComponent(token.Value, operands)); } else if (token.Type.IsOperator()) { Evaluatable parent; if (token.Type == TokenType.Factorial || token.Type == TokenType.Negate) { var argument = stack.Pop(); parent = new FunctionComponent(token.Value, new List<Expression> { Expressionizer.ToExpression(argument) }); } else if (token.Type == TokenType.Root) { var argument = stack.Pop(); parent = new FunctionComponent("√", new List<Expression> { Expressionizer.ToExpression(argument) }); } else { var right = stack.Pop(); var left = stack.Pop(); switch (token.Type) { case TokenType.Plus: case TokenType.Minus: parent = new DualComponentExpression(Componentizer.ToComponent(left), Componentizer.ToComponent(right), token.Type == TokenType.Plus); break; case TokenType.Multiply: case TokenType.Divide: parent = new DualFactorComponent(Factorizer.ToFactor(left), Factorizer.ToFactor(right), token.Type == TokenType.Multiply); break; case TokenType.Assign: parent = new FunctionComponent(new Assign(variableMap), new List<Expression> { Expressionizer.ToExpression(left), Expressionizer.ToExpression(right) }); break; default: throw new SyntaxErrorException("Token {0} not expected", token.Value); } } stack.Push(parent); } } if (stack.Count != 1) { throw new SyntaxErrorException("Stack not parseable"); } var result = stack.Pop(); if (result is Expression) { return (Expression)result; } if (result is Component) { return new SingleComponentExpression((Component)result); } if (result is Factor) { return new SingleComponentExpression(new SingleFactorComponent((Factor)result)); } throw new SyntaxErrorException("Expression tree not parseable"); }