private static Expression ToOperandExpression(ParameterExpression Pr, BExpr bExpr, object paramsObject) { if (bExpr.Operator == "=" || bExpr.Operator == "==") { Expression left = ToExpression(Pr, bExpr.Left, paramsObject); Expression right = ToExpression(Pr, bExpr.Right, paramsObject); return(Expression.Equal(left, right)); } if (bExpr.Operator == "+") { Expression left = ToExpression(Pr, bExpr.Left, paramsObject); Expression right = ToExpression(Pr, bExpr.Right, paramsObject); MakeSureLeftAndRighIsTheSameType(ref left, ref right); if (left.Type == typeof(string) && right.Type == typeof(string)) { var mc = BuilinFuncsMap.Concat; var arr = Expression.NewArrayInit(typeof(string), left, right); return(Expression.Call(mc, arr)); } return(Expression.Add(left, right)); } if (bExpr.Operator == "-") { Expression left = ToExpression(Pr, bExpr.Left, paramsObject); Expression right = ToExpression(Pr, bExpr.Right, paramsObject); MakeSureLeftAndRighIsTheSameType(ref left, ref right); return(Expression.Subtract(left, right)); } if (bExpr.Operator == "*") { Expression left = ToExpression(Pr, bExpr.Left, paramsObject); Expression right = ToExpression(Pr, bExpr.Right, paramsObject); MakeSureLeftAndRighIsTheSameType(ref left, ref right); return(Expression.Multiply(left, right)); } if (bExpr.Operator == "/") { Expression left = ToExpression(Pr, bExpr.Left, paramsObject); Expression right = ToExpression(Pr, bExpr.Right, paramsObject); MakeSureLeftAndRighIsTheSameType(ref left, ref right); return(Expression.Divide(left, right)); } if (bExpr.Operator == "%") { Expression left = ToExpression(Pr, bExpr.Left, paramsObject); Expression right = ToExpression(Pr, bExpr.Right, paramsObject); MakeSureLeftAndRighIsTheSameType(ref left, ref right); return(Expression.Modulo(left, right)); } if (bExpr.Operator == "^") { Expression left = ToExpression(Pr, bExpr.Left, paramsObject); Expression right = ToExpression(Pr, bExpr.Right, paramsObject); left = Expression.Convert(left, typeof(double)); MakeSureLeftAndRighIsTheSameType(ref left, ref right); var mc = typeof(Math).GetMethod("Pow"); return(Expression.Call(mc, left, right)); } if (bExpr.Operator == "&") { Expression left = ToExpression(Pr, bExpr.Left, paramsObject); Expression right = ToExpression(Pr, bExpr.Right, paramsObject); var mci = typeof(String).GetMethods().FirstOrDefault(p => p.Name == "Concat"); return(Expression.Call(mci, left, right)); } if (bExpr.Operator.ToLower() == "and" || bExpr.Operator == "&&") { Expression left = ToExpression(Pr, bExpr.Left, paramsObject); Expression right = ToExpression(Pr, bExpr.Right, paramsObject); return(Expression.AndAlso(left, right)); } throw new NotImplementedException(); }
public FXExpr Eval(string expression) { List <string> tokens = TokenParsers.GetTokens(expression); Stack <FXExpr> operandStack = new Stack <FXExpr>(); Stack <string> operatorStack = new Stack <string>(); int tokenIndex = 0; while (tokenIndex < tokens.Count) { string token = tokens[tokenIndex]; FXExpr preOperand = null; if (token[0] == '{' && token[token.Length - 1] == '}') { operandStack.Push(new PExpr(token)); tokenIndex += 1; continue; } if (token == "(") { if (operandStack.Count > 0) { preOperand = operandStack.Pop(); } if (preOperand is NExpr) { string subExpr = getSubExpression(tokens, ref tokenIndex); var fx = new StrParser(); var indexOfCom = -1; List <FXExpr> _args = null; if ((indexOfCom = subExpr.IndexOf(",")) > -1) { var left = (new StrParser()).Eval(subExpr.Split(',')[0]); var rStr = subExpr.Substring(indexOfCom + 1, subExpr.Length - indexOfCom - 1); var right = (new StrParser()).Eval(subExpr.Substring(indexOfCom + 1, subExpr.Length - indexOfCom - 1)); _args = ParseArgs(right); _args.Insert(0, left); } var args = fx.Eval(subExpr); var ret = new FExpr() { Name = (preOperand as NExpr).Value, Args = _args ?? (new FXExpr[] { args }).ToList() }; //var args = Eval(subExpr); operandStack.Push(ret); } else { string subExpr = getSubExpression(tokens, ref tokenIndex); if (preOperand != null) { operandStack.Push(preOperand); } operandStack.Push(Eval(subExpr)); } continue; } if (token == ")") { throw new ArgumentException("Mis-matched parentheses in expression"); } //If this is an operator if (Array.IndexOf(TokenParsers._operators, token) >= 0) { while (operatorStack.Count > 0 && Array.IndexOf(TokenParsers._operators, token) < Array.IndexOf(TokenParsers._operators, operatorStack.Peek())) { string op = operatorStack.Pop(); var arg2 = operandStack.Pop(); var arg1 = operandStack.Pop(); var BExpr = new BExpr { Operator = TokenParsers._operators[Array.IndexOf(TokenParsers._operators, op)], Left = arg1, Right = arg2 }; operandStack.Push(BExpr); } operatorStack.Push(token); } else { operandStack.Push(new NExpr(token)); } tokenIndex += 1; } while (operatorStack.Count > 0) { string op = operatorStack.Pop(); var arg2 = operandStack.Pop(); var arg1 = operandStack.Pop(); var ret = new BExpr { Left = arg1, Right = arg2, Operator = TokenParsers._operators[Array.IndexOf(TokenParsers._operators, op)] }; operandStack.Push(ret); } return(operandStack.Pop()); }