Exemplo n.º 1
0
 private static Expression GetUnaryAST(ParseNode @operator, ParseNode target, Expression context)
 {
     //NOTE:unary expressions are unchainable without grouping
     return(Expression.Dynamic(DLRUtil.GetUnaryBinder(@operator.Token.Type),
                               typeof(object),
                               target.GetAST(context)));
 }
Exemplo n.º 2
0
        private static Expression GetCompareAST(IList <ParseNode> nodes, int start, Expression context, Expression chain = null)
        {
            //Rewrite chained compare expressions to chained AND expressions, e.g. 5>4>3> --> 5>4 AND 4>3
            Debug.Assert(nodes.Count >= 3 && nodes.Count % 2 == 1);
            Expression result;

            if (start == 0)
            {
                result = chain;
            }
            else
            {
                var link = Expression.Dynamic(DLRUtil.GetBinaryBinder(nodes[start - 1].Token.Type),
                                              typeof(object),
                                              nodes[start - 2].GetAST(context),
                                              nodes[start].GetAST(context));
                chain = chain != null
                            ? Expression.Dynamic(DLRUtil.GetBinaryBinder(TokenType.AND),
                                                 typeof(object),
                                                 link,
                                                 chain)
                            : link;

                result = GetCompareAST(nodes, start - 2, context, chain);
            }
            return(result);
        }
Exemplo n.º 3
0
 private static Expression GetBinaryAST(IList <ParseNode> nodes, int start, Expression context)
 {
     //chain from left to right
     //2 + 3 + 4 is calculated as (2+3)+4, 15%12%5 as (15%12)%5
     Debug.Assert(nodes.Count >= 3 && nodes.Count % 2 == 1);
     return(start == 0
                ? nodes[start].GetAST(context)
                : Expression.Dynamic(DLRUtil.GetBinaryBinder(nodes[start - 1].Token.Type),
                                     typeof(object),
                                     GetBinaryAST(nodes, start - 2, context),
                                     nodes[start].GetAST(context)));
 }
Exemplo n.º 4
0
        private static CallSiteBinder GetFunctionCallBinder(IList <ParseNode> nodes, int argCount, bool isStatic)
        {
            var funcText = nodes[0].Token.Text;

            Debug.Assert(funcText.Length >= 2 && funcText.EndsWith("("));
            var funcName = funcText.Substring(0, funcText.Length - 1);

            if (isStatic)
            {
                funcName = funcName.ToUpperInvariant();
            }
            return(DLRUtil.GetFunctionCallBinder(funcName, argCount, isStatic));
        }
Exemplo n.º 5
0
 private static Expression GetPowerAST(IList <ParseNode> nodes, int start, Expression context)
 {
     //Have to rewrite power expressions to Math.Pow function calls because C# runtime does not support the ^ operator like VB
     //a^b^c is rewritten as Math.Pow(Math.Pow(a, b), c) and calculated as (a^b)^c
     Debug.Assert(nodes.Count >= 3 && nodes.Count % 2 == 1);
     return(start == 0
                ? nodes[start].GetAST(context)
                : Expression.Dynamic(DLRUtil.GetFunctionCallBinder("Pow", 2),
                                     typeof(object),
                                     Expression.Constant(typeof(Math)),
                                     GetPowerAST(nodes, start - 2, context),
                                     nodes[start].GetAST(context)));
 }
Exemplo n.º 6
0
        private static Expression GetMemberExpression(IList <ParseNode> nodes, int start, Expression context)
        {
            Debug.Assert(nodes.Count >= 3 && nodes.Count % 2 == 1);
            Expression result;

            if (start == 0)
            {
                result = GetInnerAST(nodes, context);
            }
            else
            {
                var @operator = nodes[start - 1].Token;
                var baseExpr  = GetMemberExpression(nodes, start - 2, context);
                if (@operator.Type == TokenType.DOT)
                {
                    var child = nodes[start].Nodes[0];
                    if (child.Token.Type == TokenType.FunctionCall)
                    {
                        result = GetFunctionAST(child.Nodes, baseExpr, false, context);
                    }
                    else if (child.Token.Type == TokenType.IDENTIFIER)
                    {
                        var fieldName = nodes[start].Nodes[0].Token.Text;
                        result = Expression.Dynamic(DLRUtil.GetFieldPropertyBinder(fieldName), typeof(object), baseExpr);
                    }
                    else
                    {
                        throw new InvalidOperationException("Invalid children, expect either Property or Method call at this point");
                    }
                }
                else if (@operator.Type == TokenType.LBRACKET)
                {
                    var indexExpr = nodes[start].GetAST(context);
                    result = Expression.Dynamic(DLRUtil.GetIndexBinder(),
                                                typeof(object),
                                                baseExpr,
                                                indexExpr);
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
            return(result);
        }
        private static Expression GetBinaryAST(IList <ParseNode> nodes, int start, Expression context)
        {
            //chain from left to right
            //2 + 3 + 4 is calculated as (2+3)+4, 15%12%5 as (15%12)%5
            Debug.Assert(nodes.Count >= 3 && nodes.Count % 2 == 1);

            Expression result;

            if (start == 0)
            {
                result = nodes[start].GetAST(context);
            }
            else
            {
                var tokenType = nodes[start - 1].Token.Type;
                var left      = GetBinaryAST(nodes, start - 2, context);
                var right     = nodes[start].GetAST(context);

                if (tokenType == TokenType.AND)
                {
                    result = Expression.AndAlso(
                        Expression.Convert(left, typeof(bool)),
                        Expression.Convert(right, typeof(bool)));
                }
                else if (tokenType == TokenType.OR)
                {
                    result = Expression.OrElse(
                        Expression.Convert(left, typeof(bool)),
                        Expression.Convert(right, typeof(bool)));
                }
                else
                {
                    result = Expression.Dynamic(
                        DLRUtil.GetBinaryBinder(tokenType),
                        typeof(object),
                        left,
                        right);
                }
            }

            return(result);
        }