예제 #1
0
 internal static Expression ToExpression(ParameterExpression Pr, FXExpr Expr, object paramsObject)
 {
     if (Expr is NExpr)
     {
         var nExpr = Expr as NExpr;
         if (nExpr.ValueType != ConstTypeEnum.None)
         {
             var Cx = Expression.Constant(nExpr.GetValue());
             return(Expression.Convert(Cx, typeof(object)));
         }
         else
         {
             var mb = Pr.Type.GetProperties().FirstOrDefault(p => p.Name.ToLower() == nExpr.Value.ToLower());
             if (mb == null)
             {
                 throw new Exception($"'{nExpr.Value}' was not found in ${Pr.Type.FullName}");
             }
             var ret = Expression.MakeMemberAccess(Pr, mb);
             return(ret);
         }
     }
     if (Expr is BExpr)
     {
         return(ToOperandExpression(Pr, Expr as BExpr, paramsObject));
     }
     if (Expr is PExpr)
     {
         return(ToConstExpression(Expr as PExpr, paramsObject));
     }
     if (Expr is FExpr)
     {
         return(ToCallExpression(Pr, Expr as FExpr, paramsObject));
     }
     throw new NotImplementedException();
 }
예제 #2
0
 private List <FXExpr> ParseArgs(FXExpr Expr)
 {
     if (Expr is NExpr)
     {
         var vExpr = Expr as NExpr;
         return
             (vExpr.Value.Split(',')
              .Select(p => (new StrParser()).Eval(p))
              .ToList());
     }
     if (Expr is BExpr)
     {
         var bExpr  = Expr as BExpr;
         var lItems = ParseArgs(bExpr.Left);
         var lX     = lItems[lItems.Count - 1];
         var rItems = ParseArgs(bExpr.Right);
         var rX     = rItems[0];
         var ret    = new List <FXExpr>();
         ret.AddRange(lItems.Where(p => p != lX));
         ret.Add(new BExpr {
             Left     = lX,
             Right    = rX,
             Operator = bExpr.Operator
         });
         ret.AddRange(rItems.Where(p => p != rX));
         return(ret);
     }
     if (Expr is FExpr)
     {
         return((new FXExpr[] { Expr }).ToList());
     }
     if (Expr is PExpr)
     {
         return((new FXExpr[] { Expr }).ToList());
     }
     throw new NotImplementedException();
 }
예제 #3
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());
        }