public decimal Evaluate() { try { if (Value is VariableReference) { return((Value as VariableReference).Variable.Value); } if (Value is AssignmentOperator) { IVariable var = Children[0].Value as IVariable; if (var == null) { throw new InvalidOperationException("The left-hand side of an assignment must be a variable."); } return((Value as AssignmentOperator).Invoke(var, Children[1].Evaluate())); } if (Value is ILiteral) { return((Value as ILiteral).Value); } if (Value is IConstant) { return((Value as IConstant).Value); } if (Value is UnknownVariable) { if (_parsedExpression.EvaluateUndefinedVariable == null) { throw new InvalidOperationException(string.Format("Cannot evaluate the value of ‘{0}’ variable.", Value.Name)); } return((Value as UnknownVariable).Value = _parsedExpression.EvaluateUndefinedVariable(Value.Name)); } if (Value is IVariable) { return((Value as IVariable).Value); } if (Value is IUnaryOperator) { return((Value as IUnaryOperator).Invoke(Children[0].Evaluate())); } if (Value is IBinaryOperator) { return((Value as IBinaryOperator).Invoke(Children[0].Evaluate(), Children[1].Evaluate())); } if (Value is UnknownFunction) { if (_parsedExpression.EvaluateUndefinedFunction == null) { throw new InvalidOperationException(string.Format("Cannot evaluate the value of ‘{0}’ function.", Value.Name)); } IFunction func = Value as IFunction; if (Children.Count != func.ParametersCount) { throw new ArgumentException(string.Format("There is no function ‘{0}’ with {1} parameters defined.", func.Name, func.ParametersCount)); } return(_parsedExpression.EvaluateUndefinedFunction(Value.Name, Children.Select(node => node.Evaluate()).ToArray())); } if (Value is IStatement) { IStatement statement = Value as IStatement; if (Children.Count != statement.ParametersCount) { throw new ArgumentException(string.Format("There is no statement ‘{0}’ with {1} parameters defined.", statement.Name, statement.ParametersCount)); } return(statement.Invoke(Children.Cast <IEvaluableElement>().ToArray())); } if (Value is IFunction) { IFunction func = Value as IFunction; if (Children.Count != func.ParametersCount) { throw new ArgumentException(string.Format("There is no function ‘{0}’ with {1} parameters defined.", func.Name, func.ParametersCount)); } return(func.Invoke(Children.Select(node => node.Evaluate()).ToArray())); } throw new ArgumentException(string.Format("Unexpected element: ‘{0}’.", Value.Name)); } catch (ArithmeticException) { if (_parsedExpression.ZeroOnError) { return(0m); } throw; } }