private Expression ParseUnaryExpression(string s) { var relevantParser = UnaryExpressionParser.For(s); if (relevantParser == null) { throw new Exception($"Unrecognized expression {s}."); } var expression = relevantParser.Parse(s); var parameterExpression = expression as ParameterExpression; if (parameterExpression != null) { Parameters.Add(parameterExpression); } else if (expression.NodeType == ExpressionType.Not) { Parameters.Add(((UnaryExpression)expression).Operand as ParameterExpression); } else if (expression.NodeType == ExpressionType.Call) { var methodCallExpression = expression as MethodCallExpression; foreach (var param in methodCallExpression.Arguments) { var paramExpression = ((UnaryExpression)param).Operand as ParameterExpression ?? param as ParameterExpression; Parameters.Add(paramExpression); } } return(expression); }
public Expression Parse(string s) { s = s.Trim(); var fullName = s.Substring(0, s.IndexOf("(")); var dotIndex = fullName.LastIndexOf("."); if (dotIndex == -1) { throw new Exception($"You have to specify static type for function {fullName}, for example Math.Sin(30)."); } var typeName = fullName.Substring(0, dotIndex); var staticType = Type.GetType(typeName); if (staticType == null) { throw new Exception($"Could not find type {typeName}."); } var methodName = fullName.Substring(dotIndex + 1, fullName.Length - dotIndex - 1); var method = staticType.GetTypeInfo().GetDeclaredMethod(methodName); if (method == null) { throw new Exception($"Could not find metehod {methodName} in type {typeName}."); } var unparsedParameters = s.Replace(fullName, "").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(up => up.Trim()).ToArray(); var methodParameters = method.GetParameters(); var paramIndex = 0; var parameters = unparsedParameters.Select(up => { var parser = UnaryExpressionParser.For(up); if (up == null) { throw new Exception($"Unrecognized expression {up} in parameters of function {fullName}."); } var parameterExpression = parser.Parse(up); return(Expression.Convert(parameterExpression, methodParameters[paramIndex++].ParameterType)); } ).ToArray(); return(Expression.Call(method, parameters)); }