ParseTreeNode FunctionCall() { FunctionParseTreeNode node = new FunctionParseTreeNode(); if (!tokens.HasNext()) { throw new Exception("Synax error: Expecting function identifieri at token " + tokens.Position); } node.Token = tokens.Forward(); if (!tokens.HasNext() || tokens.PeekForward().TokenType != TokenIdentifier.TokenType.LeftParenthesis) { throw new Exception("Synax error: Expecting function identifieri at token " + tokens.Position); } tokens.Forward(); bool expect = false; while (tokens.HasNext()) { if (tokens.PeekForward().TokenType == TokenIdentifier.TokenType.RightParenthesis) { tokens.Forward(); return(node); } if (expect && tokens.PeekForward().TokenType == TokenIdentifier.TokenType.ParamSeparator) { tokens.Forward(); expect = false; } else { node.Parameters.Add(Expr()); expect = true; } } throw new Exception("Syntax error: Expecting function end ')' at token " + tokens.Position); }
private double Evaluate(ParseTreeNode node) { if (node is LeftOperatorNode) { // left operators if (node.Token.TokenType == TokenIdentifier.TokenType.MinusOperator) { // minus return(-Evaluate(((LeftOperatorNode)node).Next)); } else if (node.Token.TokenType == TokenIdentifier.TokenType.NegationOperator) { // negation return(~(long)Evaluate(((LeftOperatorNode)node).Next)); } else { // factorial double value = Evaluate(((LeftOperatorNode)node).Next); double newValue = 1; while (value > 1) { newValue *= value--; } return(newValue); } } else if (node is FunctionParseTreeNode) { // we have a function FunctionParseTreeNode n = (FunctionParseTreeNode)node; string name = ((IdentifierToken)n.Token).Identifier; if (functions.ContainsKey(name)) { if (n.Parameters.Count < functions[name].MinArgs) { throw new Exception("The function needs at least " + functions[name].MinArgs + " argument(s)."); } double[] parValues = new double[n.Parameters.Count]; for (int i = 0; i < n.Parameters.Count; i++) { parValues[i] = Evaluate(n.Parameters[i]); } return(functions[name].FunctionCallback(parValues)); } else { throw new Exception("The function '" + name + "' does not exist."); } } else { if (node.Left != null) { // we have an operator double first = Evaluate(node.Left); double second = Evaluate(node.Right); switch (node.Token.TokenType) { case TokenIdentifier.TokenType.MinusOperator: return(first - second); case TokenIdentifier.TokenType.PlussOperator: return(first + second); case TokenIdentifier.TokenType.MultiplicationOperator: return(first * second); case TokenIdentifier.TokenType.DivisionOperator: return(first / second); case TokenIdentifier.TokenType.ModuloOperator: return(first % second); case TokenIdentifier.TokenType.AndOperator: return((int)first & (int)second); case TokenIdentifier.TokenType.XorOperator: return((int)first ^ (int)second); case TokenIdentifier.TokenType.OrOperator: return((int)first | (int)second); case TokenIdentifier.TokenType.ShiftLeftOperator: return((int)first << (int)second); case TokenIdentifier.TokenType.ShiftRightOperator: return((int)first >> (int)second); case TokenIdentifier.TokenType.PowerOperator: return(Math.Pow(first, int.Parse(second.ToString()))); } } else if (node.Token.TokenType == TokenIdentifier.TokenType.Identifier) { // we have a variable name string name = ((IdentifierToken)node.Token).Identifier; if (variables.ContainsKey(name)) { return(variables[name]); } else { throw new Exception("There exists no variables with the name '" + name + "'."); } } return(((NumberToken)node.Token).Value); } }