예제 #1
0
        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();
        }
예제 #2
0
        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());
        }