public static Expression ToCallExpression(ParameterExpression Pr, FExpr fx, object paramsObject) { if (fx.Name == nameof(BuilinFuncsMap.Left)) { if (fx.Args.Count < 2) { throw new ArgumentException($"'{nameof(BuilinFuncs.Left)} require 2 params'"); } var mc = BuilinFuncsMap.Left; var mx = ToExpression(Pr, fx.Args[0], paramsObject); var len = ToExpression(Pr, fx.Args[1], paramsObject); if (len is UnaryExpression) { if (((UnaryExpression)len).Operand is ConstantExpression) { var val = ((ConstantExpression)(((UnaryExpression)len).Operand)).Value; val = Convert.ChangeType(val, typeof(int)); len = Expression.Constant(val); } } return(Expression.Call(mc, mx, len)); } if (fx.Name == nameof(BuilinFuncsMap.Concat)) { var args = new List <Expression>(); foreach (var x in fx.Args) { var FX = ToExpression(Pr, x, paramsObject); if (FX is UnaryExpression && ((UnaryExpression)FX).Operand is ConstantExpression) { args.Add(((UnaryExpression)FX).Operand); } else { args.Add(FX); } } var axs = Expression.NewArrayInit(typeof(string), args); var mc = BuilinFuncsMap.Concat; return(Expression.Call(mc, axs)); } 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()); }