Example #1
0
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     // This can be used for a denial of service
     // Write-Output (((((("AAAAAAAAAAAAAAAAAAAAAA"*2)*2)*2)*2)*2)*2)
     // Keep on going with that pattern, and we're generating gigabytes of strings.
     throw PSTraceSource.NewArgumentException("ast");
 }
Example #2
0
        private static bool IsNullDivisor(ExpressionAst operand)
        {
            VariableExpressionAst ast = operand as VariableExpressionAst;

            if (ast != null)
            {
                BinaryExpressionAst parent = operand.Parent as BinaryExpressionAst;
                if ((parent == null) || (parent.Right != operand))
                {
                    return(false);
                }
                switch (parent.Operator)
                {
                case TokenKind.Divide:
                case TokenKind.Rem:
                case TokenKind.DivideEquals:
                case TokenKind.RemainderEquals:
                {
                    string unqualifiedPath = ast.VariablePath.UnqualifiedPath;
                    if (!unqualifiedPath.Equals("false", StringComparison.OrdinalIgnoreCase))
                    {
                        return(unqualifiedPath.Equals("null", StringComparison.OrdinalIgnoreCase));
                    }
                    return(true);
                }
                }
            }
            return(false);
        }
        private bool IncorrectComparisonWithNull(BinaryExpressionAst binExpressionAst, Ast ast)
        {
            if ((binExpressionAst.Operator.Equals(TokenKind.Equals) || binExpressionAst.Operator.Equals(TokenKind.Ceq) 
                || binExpressionAst.Operator.Equals(TokenKind.Cne) || binExpressionAst.Operator.Equals(TokenKind.Ine) || binExpressionAst.Operator.Equals(TokenKind.Ieq))
                && binExpressionAst.Right.Extent.Text.Equals("$null", StringComparison.OrdinalIgnoreCase)) 
            {
                if (binExpressionAst.Left.StaticType.IsArray)
                {
                    return true;
                }
                else if (binExpressionAst.Left is VariableExpressionAst)
                {
                    // ignores if the variable is a special variable
                    if (!Helper.Instance.HasSpecialVars((binExpressionAst.Left as VariableExpressionAst).VariablePath.UserPath))
                    {
                        Type lhsType = Helper.Instance.GetTypeFromAnalysis(binExpressionAst.Left as VariableExpressionAst, ast);
                        if (lhsType == null)
                        {
                            return true;
                        }
                        else if (lhsType.IsArray || lhsType == typeof(object) || lhsType == typeof(Undetermined) || lhsType == typeof(Unreached))
                        {
                            return true;
                        }
                    }
                }
                else if (binExpressionAst.Left.StaticType == typeof(object))
                {
                    return true;
                }
            }

            return false;
        }
Example #4
0
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     // This can be used for a denial of service
     // Write-Output (((((("AAAAAAAAAAAAAAAAAAAAAA"*2)*2)*2)*2)*2)*2)
     // Keep on going with that pattern, and we're generating gigabytes of strings.
     return(false);
 }
Example #5
0
 public override AstVisitAction VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     if ((binaryExpressionAst.Operator == TokenKind.AndAnd) || (binaryExpressionAst.Operator == TokenKind.OrOr))
     {
         this._parser.ReportError(binaryExpressionAst.ErrorPosition, ParserStrings.InvalidEndOfLine, new object[] { binaryExpressionAst.Operator.Text() });
     }
     return(AstVisitAction.Continue);
 }
 public override AstVisitAction VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     if (binaryExpressionAst.Operator.HasTrait(TokenFlags.DisallowedInRestrictedMode))
     {
         this.ReportError(binaryExpressionAst.ErrorPosition, () => ParserStrings.OperatorNotSupportedInDataSection, new object[] { binaryExpressionAst.Operator.Text() });
     }
     return(AstVisitAction.Continue);
 }
Example #7
0
 public override AstVisitAction VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     // Important: never enumerate when writing to pipeline
     // Array replication is a binary expression. Replicated arrays might be huge, writing all
     // elements to pipeline can cause crucial performance issues if the array is needed again
     this._pipelineCommandRuntime.WriteObject(EvaluateBinaryExpression(binaryExpressionAst), false);
     return AstVisitAction.SkipChildren;
 }
Example #8
0
    public System.Object VisitBinaryExpression(System.Management.Automation.Language.BinaryExpressionAst binaryExpressionAst)
    {
        IScriptExtent mappedExtent      = MapExtent(binaryExpressionAst.Extent);
        IScriptExtent mappedErrorExtent = MapExtent(binaryExpressionAst.ErrorPosition);

        ExpressionAst mappedLeft  = _VisitExpression(binaryExpressionAst.Left);
        ExpressionAst mappedRight = _VisitExpression(binaryExpressionAst.Right);

        return(new BinaryExpressionAst(mappedExtent, mappedLeft, binaryExpressionAst.Operator, mappedRight, mappedErrorExtent));
    }
Example #9
0
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     if ((binaryExpressionAst.Operator == TokenKind.And) || (binaryExpressionAst.Operator == TokenKind.Or))
     {
         binaryExpressionAst.Left.Accept(this);
         Block next   = new Block();
         Block block2 = new Block();
         this._currentBlock.FlowsTo(next);
         this._currentBlock.FlowsTo(block2);
         this._currentBlock = block2;
         binaryExpressionAst.Right.Accept(this);
         this._currentBlock.FlowsTo(next);
         this._currentBlock = next;
     }
     else
     {
         binaryExpressionAst.Left.Accept(this);
         binaryExpressionAst.Right.Accept(this);
     }
     return(null);
 }
Example #10
0
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     return CompileAndInvoke(binaryExpressionAst);
 }
Example #11
0
        private ExpressionAst ExpressionRule()
        {
            //G  expression:
            //G      logical-expression
            //G
            //G  logical-expression:
            //G      bitwise-expression
            //G      logical-expression   '-and'   new-lines:opt   bitwise-expression
            //G      logical-expression   '-or'   new-lines:opt   bitwise-expression
            //G      logical-expression   '-xor'   new-lines:opt   bitwise-expression
            //G
            //G  bitwise-expression:
            //G      comparison-expression
            //G      bitwise-expression   '-band'   new-lines:opt   comparison-expression
            //G      bitwise-expression   '-bor'   new-lines:opt   comparison-expression
            //G      bitwise-expression   '-bxor'   new-lines:opt   comparison-expression
            //G
            //G  comparison-expression:
            //G      additive-expression
            //G      comparison-expression   comparison-operator   new-lines:opt   additive-expression
            //G
            //G  additive-expression:
            //G      multiplicative-expression
            //G      additive-expression   '+'   new-lines:opt   multiplicative-expression
            //G      additive-expression   dash   new-lines:opt   multiplicative-expression
            //G
            //G  multiplicative-expression:
            //G      format-expression
            //G      multiplicative-expression   '*'   new-lines:opt   format-expression
            //G      multiplicative-expression   '/'   new-lines:opt   format-expression
            //G      multiplicative-expression   '%'   new-lines:opt   format-expression
            //G
            //G  format-expression:
            //G      range-expression
            //G      format-expression   format-operator    new-lines:opt   range-expression
            //G
            //G  range-expression:
            //G      array-literal-expression
            //G      range-expression   '..'   new-lines:opt   array-literal-expression
            RuntimeHelpers.EnsureSufficientExecutionStack();
            var oldTokenizerMode = _tokenizer.Mode;
            try
            {
                SetTokenizerMode(TokenizerMode.Expression);

                ExpressionAst lhs, rhs;
                ExpressionAst expr = ArrayLiteralRule();

                if (expr == null)
                {
                    return null;
                }

                ParameterToken paramToken;
                Token token = PeekToken();
                if (!token.Kind.HasTrait(TokenFlags.BinaryOperator))
                {
                    paramToken = token as ParameterToken;
                    if (paramToken != null)
                    {
                        return ErrorRecoveryParameterInExpression(paramToken, expr);
                    }
                    return expr;
                }

                SkipToken();

                Stack<ExpressionAst> operandStack = new Stack<ExpressionAst>();
                Stack<Token> operatorStack = new Stack<Token>();

                operandStack.Push(expr);
                operatorStack.Push(token);

                int precedence = token.Kind.GetBinaryPrecedence();
                while (true)
                {
                    SkipNewlines();

                    expr = ArrayLiteralRule();
                    if (expr == null)
                    {
                        // ErrorRecovery: create an error expression to fill out the ast and keep parsing.

                        IScriptExtent extent = After(token);
                        // Use token.Text, not token.Kind.Text() b/c the kind might not match the actual operator used
                        // when a case insensitive operator is used.
                        ReportIncompleteInput(extent, () => ParserStrings.ExpectedValueExpression, token.Text);
                        expr = new ErrorExpressionAst(extent);
                    }
                    operandStack.Push(expr);

                    token = NextToken();

                    if (!token.Kind.HasTrait(TokenFlags.BinaryOperator))
                    {
                        // Remember the token that we stopped on, but only parameters, used for error recovery
                        paramToken = token as ParameterToken;
                        UngetToken(token);
                        break;
                    }

                    int newPrecedence = token.Kind.GetBinaryPrecedence();
                    while (newPrecedence <= precedence)
                    {
                        rhs = operandStack.Pop();
                        lhs = operandStack.Pop();
                        Token op = operatorStack.Pop();
                        operandStack.Push(new BinaryExpressionAst(ExtentOf(lhs, rhs), lhs, op.Kind, rhs, op.Extent));
                        if (operatorStack.Count == 0)
                            break;
                        precedence = operatorStack.Peek().Kind.GetBinaryPrecedence();
                    }
                    operatorStack.Push(token);
                    precedence = newPrecedence;
                }
                rhs = operandStack.Pop();
                Diagnostics.Assert(operandStack.Count == operatorStack.Count, "Stacks out of sync");
                while (operandStack.Count > 0)
                {
                    lhs = operandStack.Pop();
                    token = operatorStack.Pop();
                    rhs = new BinaryExpressionAst(ExtentOf(lhs, rhs), lhs, token.Kind, rhs, token.Extent);
                }

                if (paramToken != null)
                {
                    return ErrorRecoveryParameterInExpression(paramToken, rhs);
                }

                return rhs;
            }
            finally
            {
                SetTokenizerMode(oldTokenizerMode);
            }
        }
Example #12
0
        object EvaluateBinaryExpression(BinaryExpressionAst binaryExpressionAst)
        {
            var leftOperand = EvaluateAst(binaryExpressionAst.Left);
            var rightOperand = EvaluateAst(binaryExpressionAst.Right);

            if (leftOperand is PSObject) leftOperand = ((PSObject)leftOperand).BaseObject;
            if (rightOperand is PSObject) rightOperand = ((PSObject)rightOperand).BaseObject;

            int? leftOperandInt = leftOperand is int ? ((int?)leftOperand) : null;
            int? rightOperandInt = rightOperand is int ? ((int?)rightOperand) : null;

            bool? leftOperandBool = leftOperand is bool ? ((bool?)leftOperand) : null;
            bool? rightOperandBool = rightOperand is bool ? ((bool?)rightOperand) : null;

            switch (binaryExpressionAst.Operator)
            {
                case TokenKind.DotDot:
                    return Range((int)leftOperand, (int)rightOperand);

                case TokenKind.Plus:
                    return Add(leftOperand, rightOperand);

                case TokenKind.Ieq:
                    if (leftOperandInt.HasValue) return leftOperandInt == rightOperandInt;
                    throw new NotImplementedException(binaryExpressionAst.ToString());

                case TokenKind.Ine:
                    if (leftOperandInt.HasValue) return leftOperandInt != rightOperandInt;
                    throw new NotImplementedException(binaryExpressionAst.ToString());

                case TokenKind.Igt:
                    if (leftOperandInt.HasValue) return leftOperandInt > rightOperandInt;
                    throw new NotImplementedException(binaryExpressionAst.ToString());

                case TokenKind.Or:
                    if (leftOperandBool.HasValue) return leftOperandBool.Value || rightOperandBool.Value;
                    throw new NotImplementedException(binaryExpressionAst.ToString());

                case TokenKind.Xor:
                    if (leftOperandBool.HasValue) return leftOperandBool != rightOperandBool;
                    throw new NotImplementedException(binaryExpressionAst.ToString());

                case TokenKind.And:
                    if (leftOperandBool.HasValue) return leftOperandBool.Value && rightOperandBool.Value;
                    throw new NotImplementedException(binaryExpressionAst.ToString());

                case TokenKind.Ilt:
                    if (leftOperandInt.HasValue) return leftOperandInt < rightOperandInt;
                    throw new NotImplementedException(binaryExpressionAst.ToString());

                case TokenKind.Ile:
                    if (leftOperandInt.HasValue) return leftOperandInt <= rightOperandInt;
                    throw new NotImplementedException(binaryExpressionAst.ToString());

                case TokenKind.Multiply:
                case TokenKind.Divide:
                case TokenKind.Minus:
                case TokenKind.Equals:
                case TokenKind.PlusEquals:
                case TokenKind.MinusEquals:
                case TokenKind.MultiplyEquals:
                case TokenKind.DivideEquals:
                case TokenKind.RemainderEquals:
                case TokenKind.Format:
                case TokenKind.Not:
                case TokenKind.Bnot:
                case TokenKind.Band:
                case TokenKind.Bor:
                case TokenKind.Bxor:
                case TokenKind.Join:
                case TokenKind.Ige:
                case TokenKind.Ilike:
                case TokenKind.Inotlike:
                case TokenKind.Imatch:
                case TokenKind.Inotmatch:
                case TokenKind.Ireplace:
                case TokenKind.Icontains:
                case TokenKind.Inotcontains:
                case TokenKind.Iin:
                case TokenKind.Inotin:
                case TokenKind.Isplit:
                case TokenKind.Ceq:
                case TokenKind.Cne:
                case TokenKind.Cge:
                case TokenKind.Cgt:
                case TokenKind.Clt:
                case TokenKind.Cle:
                case TokenKind.Clike:
                case TokenKind.Cnotlike:
                case TokenKind.Cmatch:
                case TokenKind.Cnotmatch:
                case TokenKind.Creplace:
                case TokenKind.Ccontains:
                case TokenKind.Cnotcontains:
                case TokenKind.Cin:
                case TokenKind.Cnotin:
                case TokenKind.Csplit:
                case TokenKind.Is:
                case TokenKind.IsNot:
                case TokenKind.As:
                case TokenKind.Shl:
                case TokenKind.Shr:
                    throw new NotImplementedException(binaryExpressionAst.ToString());

                default:
                    throw new InvalidOperationException(binaryExpressionAst.ToString());
            }
        }
 /// <summary/>
 public virtual object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     return _decorated.VisitBinaryExpression(binaryExpressionAst);
 }
Example #14
0
        object EvaluateBinaryExpression(BinaryExpressionAst binaryExpressionAst)
        {
            var leftOperand = EvaluateAst(binaryExpressionAst.Left);
            var rightOperand = EvaluateAst(binaryExpressionAst.Right);

            if (leftOperand is PSObject) leftOperand = ((PSObject)leftOperand).BaseObject;
            if (rightOperand is PSObject) rightOperand = ((PSObject)rightOperand).BaseObject;

            switch (binaryExpressionAst.Operator)
            {
                case TokenKind.DotDot:
                    return Range(LanguagePrimitives.ConvertTo<int>(leftOperand), LanguagePrimitives.ConvertTo<int>(rightOperand));

                case TokenKind.Plus:
                    return ArithmeticOperations.Add(leftOperand, rightOperand);

                case TokenKind.Ieq:
                case TokenKind.Ceq:
                    if (leftOperand is string || rightOperand is string)
                    {
                        StringComparison ignoreCaseComparision =
                            (TokenKind.Ceq == binaryExpressionAst.Operator)
                            ? StringComparison.CurrentCulture
                            : StringComparison.CurrentCultureIgnoreCase;
                        var left = LanguagePrimitives.ConvertTo<string>(leftOperand);
                        var right = LanguagePrimitives.ConvertTo<string>(rightOperand);
                        return String.Equals(left, right, ignoreCaseComparision);
                    }
                    return Object.Equals(leftOperand, rightOperand);

                case TokenKind.Ine:
                case TokenKind.Cne:
                    if (leftOperand is string || rightOperand is string)
                    {
                        StringComparison ignoreCaseComparision =
                            (TokenKind.Cne == binaryExpressionAst.Operator)
                            ? StringComparison.CurrentCulture
                            : StringComparison.CurrentCultureIgnoreCase;
                        var left = LanguagePrimitives.ConvertTo<string>(leftOperand);
                        var right = LanguagePrimitives.ConvertTo<string>(rightOperand);
                        return !String.Equals(left, right, ignoreCaseComparision);
                    }
                    return !Object.Equals(leftOperand, rightOperand);

                case TokenKind.Igt:
                case TokenKind.Cgt:
                    return ComparisonOperations.GreaterThan(
                            leftOperand,
                            rightOperand,
                            (TokenKind.Cgt != binaryExpressionAst.Operator));

                case TokenKind.Ige:
                case TokenKind.Cge:
                    return ComparisonOperations.GreaterThanEquals(
                            leftOperand,
                            rightOperand,
                            (TokenKind.Cge != binaryExpressionAst.Operator));

                case TokenKind.Or:
                    return LanguagePrimitives.ConvertTo<bool>(leftOperand) || LanguagePrimitives.ConvertTo<bool>(rightOperand);

                case TokenKind.Xor:
                    return LanguagePrimitives.ConvertTo<bool>(leftOperand) != LanguagePrimitives.ConvertTo<bool>(rightOperand);

                case TokenKind.And:
                    return LanguagePrimitives.ConvertTo<bool>(leftOperand) && LanguagePrimitives.ConvertTo<bool>(rightOperand);

                case TokenKind.Ilt:
                case TokenKind.Clt:
                    return ComparisonOperations.LessThan(
                            leftOperand,
                            rightOperand,
                            (TokenKind.Clt != binaryExpressionAst.Operator));

                case TokenKind.Ile:
                case TokenKind.Cle:
                    return ComparisonOperations.LessThanEquals(
                            leftOperand,
                            rightOperand,
                            (TokenKind.Clt != binaryExpressionAst.Operator));

                case TokenKind.Band:
                    return BitwiseOperation.And(leftOperand, rightOperand);
                case TokenKind.Bor:
                    return BitwiseOperation.Or(leftOperand, rightOperand);
                case TokenKind.Bxor:
                    return BitwiseOperation.Xor(leftOperand, rightOperand);

                case TokenKind.Imatch:
                    return Match(leftOperand, rightOperand, RegexOptions.IgnoreCase);
                case TokenKind.Inotmatch:
                    return NotMatch(leftOperand, rightOperand, RegexOptions.IgnoreCase);
                case TokenKind.Cmatch:
                    return Match(leftOperand, rightOperand, RegexOptions.None);
                case TokenKind.Cnotmatch:
                    return NotMatch(leftOperand, rightOperand, RegexOptions.None);

                case TokenKind.Multiply:
                    return ArithmeticOperations.Multiply(leftOperand, rightOperand);

                case TokenKind.Divide:
                    return ArithmeticOperations.Divide(leftOperand, rightOperand);

                case TokenKind.Minus:
                    return ArithmeticOperations.Subtract(leftOperand, rightOperand);

                case TokenKind.Rem:
                    return ArithmeticOperations.Remainder(leftOperand, rightOperand);

                case TokenKind.Format:
                    {
                        var left = LanguagePrimitives.ConvertTo<string>(leftOperand);
                        var right = LanguagePrimitives.ConvertTo<object[]>(rightOperand);
                        return string.Format(left, right);
                    }

                case TokenKind.Equals:
                case TokenKind.PlusEquals:
                case TokenKind.MinusEquals:
                case TokenKind.MultiplyEquals:
                case TokenKind.DivideEquals:
                case TokenKind.RemainderEquals:
                case TokenKind.Not:
                case TokenKind.Bnot:
                case TokenKind.Join:
                case TokenKind.Ilike:
                case TokenKind.Inotlike:
                case TokenKind.Ireplace:
                case TokenKind.Icontains:
                case TokenKind.Inotcontains:
                case TokenKind.Iin:
                case TokenKind.Inotin:
                case TokenKind.Isplit:
                case TokenKind.Clike:
                case TokenKind.Cnotlike:
                case TokenKind.Creplace:
                case TokenKind.Ccontains:
                case TokenKind.Cnotcontains:
                case TokenKind.Cin:
                case TokenKind.Cnotin:
                case TokenKind.Csplit:
                case TokenKind.Is:
                case TokenKind.IsNot:
                case TokenKind.As:
                case TokenKind.Shl:
                case TokenKind.Shr:
                    throw new NotImplementedException(binaryExpressionAst.ToString());

                default:
                    throw new InvalidOperationException(binaryExpressionAst.ToString());
            }
        }
Example #15
0
 public override AstVisitAction VisitBinaryExpression(BinaryExpressionAst ast) { return CheckParent(ast); }
Example #16
0
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     if ((binaryExpressionAst.Operator == TokenKind.And) || (binaryExpressionAst.Operator == TokenKind.Or))
     {
         binaryExpressionAst.Left.Accept(this);
         Block next = new Block();
         Block block2 = new Block();
         this._currentBlock.FlowsTo(next);
         this._currentBlock.FlowsTo(block2);
         this._currentBlock = block2;
         binaryExpressionAst.Right.Accept(this);
         this._currentBlock.FlowsTo(next);
         this._currentBlock = next;
     }
     else
     {
         binaryExpressionAst.Left.Accept(this);
         binaryExpressionAst.Right.Accept(this);
     }
     return null;
 }
Example #17
0
        public override AstVisitAction VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
        {
            if (binaryExpressionAst.Operator == TokenKind.AndAnd
                || binaryExpressionAst.Operator == TokenKind.OrOr)
            {
                _parser.ReportError(binaryExpressionAst.ErrorPosition, () => ParserStrings.InvalidEndOfLine,
                    binaryExpressionAst.Operator.Text());
            }

            return AstVisitAction.Continue;
        }
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     throw new UnexpectedElementException();
 }
Example #19
0
        public override AstVisitAction VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
        {
            // match and notmatch disallowed because they can set $matches
            // -join/-split disallowed because they can be used in tandem to build very large strings, like:
            //    -split (-split ( ('a','a') -join " a a a a a ") -join " a a a a a ")
            // -replace disallowed because it too can be used to build very large strings, like:
            //    ('x' -replace '.','xx') -replace '.','xx'
            // -as disallowed because it can invoke arbitrary code (similar to why some casts are disallowed,
            //    but -as is completely disallowed because in some cases, we don't know the type at parse time.
            // Format disallowed because of unbounded results, like ("{0," + 1MB + ":0}") -f 1
            // Range disallowed because it has iteration semantics.

            if (binaryExpressionAst.Operator.HasTrait(TokenFlags.DisallowedInRestrictedMode))
            {
                ReportError(binaryExpressionAst.ErrorPosition, () => ParserStrings.OperatorNotSupportedInDataSection, binaryExpressionAst.Operator.Text());
            }

            return AstVisitAction.Continue;
        }
Example #20
0
 /// <summary/>
 public virtual AstVisitAction VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst) => DefaultVisit(binaryExpressionAst);
Example #21
0
        public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
        {
            object obj2;
            if (!this.CompilingConstantExpression && IsConstantValueVisitor.IsConstant(binaryExpressionAst, out obj2, false, false))
            {
                return Expression.Constant(obj2);
            }
            Expression expr = this.CompileExpressionOperand(binaryExpressionAst.Left);
            Expression expression2 = this.CompileExpressionOperand(binaryExpressionAst.Right);
            switch (binaryExpressionAst.Operator)
            {
                case TokenKind.DotDot:
                    return Expression.Call(CachedReflectionInfo.IntOps_Range, expr.Convert(typeof(int)), expression2.Convert(typeof(int)));

                case TokenKind.Multiply:
                    if (!expr.Type.Equals(typeof(double)) || !expression2.Type.Equals(typeof(double)))
                    {
                        return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.Multiply, true, false), typeof(object), expr, expression2);
                    }
                    return Expression.Multiply(expr, expression2);

                case TokenKind.Divide:
                    if (!expr.Type.Equals(typeof(double)) || !expression2.Type.Equals(typeof(double)))
                    {
                        return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.Divide, true, false), typeof(object), expr, expression2);
                    }
                    return Expression.Divide(expr, expression2);

                case TokenKind.Rem:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.Modulo, true, false), typeof(object), expr, expression2);

                case TokenKind.Plus:
                    if (!expr.Type.Equals(typeof(double)) || !expression2.Type.Equals(typeof(double)))
                    {
                        return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.Add, true, false), typeof(object), expr, expression2);
                    }
                    return Expression.Add(expr, expression2);

                case TokenKind.Minus:
                    if (!expr.Type.Equals(typeof(double)) || !expression2.Type.Equals(typeof(double)))
                    {
                        return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.Subtract, true, false), typeof(object), expr, expression2);
                    }
                    return Expression.Subtract(expr, expression2);

                case TokenKind.Format:
                    if (!expr.Type.Equals(typeof(string)))
                    {
                        expr = Expression.Dynamic(PSToStringBinder.Get(), typeof(string), expr, _executionContextParameter);
                    }
                    return Expression.Call(CachedReflectionInfo.StringOps_FormatOperator, expr, expression2.Cast(typeof(object)));

                case TokenKind.And:
                    return Expression.AndAlso(expr.Convert(typeof(bool)), expression2.Convert(typeof(bool)));

                case TokenKind.Or:
                    return Expression.OrElse(expr.Convert(typeof(bool)), expression2.Convert(typeof(bool)));

                case TokenKind.Xor:
                    return Expression.NotEqual(expr.Convert(typeof(bool)), expression2.Convert(typeof(bool)));

                case TokenKind.Band:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.And, true, false), typeof(object), expr, expression2);

                case TokenKind.Bor:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.Or, true, false), typeof(object), expr, expression2);

                case TokenKind.Bxor:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.ExclusiveOr, true, false), typeof(object), expr, expression2);

                case TokenKind.Join:
                    return Expression.Call(CachedReflectionInfo.ParserOps_JoinOperator, _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), expr.Cast(typeof(object)), expression2.Cast(typeof(object)));

                case TokenKind.Ieq:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.Equal, true, false), typeof(object), expr, expression2);

                case TokenKind.Ine:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.NotEqual, true, false), typeof(object), expr, expression2);

                case TokenKind.Ige:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.GreaterThanOrEqual, true, false), typeof(object), expr, expression2);

                case TokenKind.Igt:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.GreaterThan, true, false), typeof(object), expr, expression2);

                case TokenKind.Ilt:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.LessThan, true, false), typeof(object), expr, expression2);

                case TokenKind.Ile:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.LessThanOrEqual, true, false), typeof(object), expr, expression2);

                case TokenKind.Ilike:
                    return Expression.Call(CachedReflectionInfo.ParserOps_LikeOperator, new Expression[] { _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), expr.Cast(typeof(object)), expression2.Cast(typeof(object)), ExpressionCache.Constant(false), ExpressionCache.Constant(true) });

                case TokenKind.Inotlike:
                    return Expression.Call(CachedReflectionInfo.ParserOps_LikeOperator, new Expression[] { _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), expr.Cast(typeof(object)), expression2.Cast(typeof(object)), ExpressionCache.Constant(true), ExpressionCache.Constant(true) });

                case TokenKind.Imatch:
                    return Expression.Call(CachedReflectionInfo.ParserOps_MatchOperator, new Expression[] { _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), expr.Cast(typeof(object)), expression2.Cast(typeof(object)), ExpressionCache.Constant(false), ExpressionCache.Constant(true) });

                case TokenKind.Inotmatch:
                    return Expression.Call(CachedReflectionInfo.ParserOps_MatchOperator, new Expression[] { _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), expr.Cast(typeof(object)), expression2.Cast(typeof(object)), ExpressionCache.Constant(true), ExpressionCache.Constant(true) });

                case TokenKind.Ireplace:
                    return Expression.Call(CachedReflectionInfo.ParserOps_ReplaceOperator, _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), expr.Cast(typeof(object)), expression2.Cast(typeof(object)), ExpressionCache.Constant(true));

                case TokenKind.Icontains:
                    return this.GenerateCallContains(expr, expression2, true);

                case TokenKind.Inotcontains:
                    return Expression.Not(this.GenerateCallContains(expr, expression2, true));

                case TokenKind.Iin:
                    return this.GenerateCallContains(expression2, expr, true);

                case TokenKind.Inotin:
                    return Expression.Not(this.GenerateCallContains(expression2, expr, true));

                case TokenKind.Isplit:
                    return Expression.Call(CachedReflectionInfo.ParserOps_SplitOperator, _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), expr.Cast(typeof(object)), expression2.Cast(typeof(object)), ExpressionCache.Constant(true));

                case TokenKind.Ceq:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.Equal, false, false), typeof(object), expr, expression2);

                case TokenKind.Cne:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.NotEqual, false, false), typeof(object), expr, expression2);

                case TokenKind.Cge:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.GreaterThanOrEqual, false, false), typeof(object), expr, expression2);

                case TokenKind.Cgt:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.GreaterThan, false, false), typeof(object), expr, expression2);

                case TokenKind.Clt:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.LessThan, false, false), typeof(object), expr, expression2);

                case TokenKind.Cle:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.LessThanOrEqual, false, false), typeof(object), expr, expression2);

                case TokenKind.Clike:
                    return Expression.Call(CachedReflectionInfo.ParserOps_LikeOperator, new Expression[] { _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), expr.Cast(typeof(object)), expression2.Cast(typeof(object)), ExpressionCache.Constant(false), ExpressionCache.Constant(false) });

                case TokenKind.Cnotlike:
                    return Expression.Call(CachedReflectionInfo.ParserOps_LikeOperator, new Expression[] { _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), expr.Cast(typeof(object)), expression2.Cast(typeof(object)), ExpressionCache.Constant(true), ExpressionCache.Constant(false) });

                case TokenKind.Cmatch:
                    return Expression.Call(CachedReflectionInfo.ParserOps_MatchOperator, new Expression[] { _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), expr.Cast(typeof(object)), expression2.Cast(typeof(object)), ExpressionCache.Constant(false), ExpressionCache.Constant(false) });

                case TokenKind.Cnotmatch:
                    return Expression.Call(CachedReflectionInfo.ParserOps_MatchOperator, new Expression[] { _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), expr.Cast(typeof(object)), expression2.Cast(typeof(object)), ExpressionCache.Constant(true), ExpressionCache.Constant(false) });

                case TokenKind.Creplace:
                    return Expression.Call(CachedReflectionInfo.ParserOps_ReplaceOperator, _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), expr.Cast(typeof(object)), expression2.Cast(typeof(object)), ExpressionCache.Constant(false));

                case TokenKind.Ccontains:
                    return this.GenerateCallContains(expr, expression2, false);

                case TokenKind.Cnotcontains:
                    return Expression.Not(this.GenerateCallContains(expr, expression2, false));

                case TokenKind.Cin:
                    return this.GenerateCallContains(expression2, expr, false);

                case TokenKind.Cnotin:
                    return Expression.Not(this.GenerateCallContains(expression2, expr, false));

                case TokenKind.Csplit:
                    return Expression.Call(CachedReflectionInfo.ParserOps_SplitOperator, _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), expr.Cast(typeof(object)), expression2.Cast(typeof(object)), ExpressionCache.Constant(false));

                case TokenKind.Is:
                case TokenKind.IsNot:
                {
                    if (!(expression2 is ConstantExpression) || !expression2.Type.Equals(typeof(Type)))
                    {
                        break;
                    }
                    Type type = (Type) ((ConstantExpression) expression2).Value;
                    if (type.Equals(typeof(PSCustomObject)) || type.Equals(typeof(PSObject)))
                    {
                        break;
                    }
                    expr = expr.Type.IsValueType ? expr : Expression.Call(CachedReflectionInfo.PSObject_Base, expr);
                    if (binaryExpressionAst.Operator != TokenKind.Is)
                    {
                        return Expression.Not(Expression.TypeIs(expr, type));
                    }
                    return Expression.TypeIs(expr, type);
                }
                case TokenKind.As:
                    return Expression.Call(CachedReflectionInfo.TypeOps_AsOperator, expr.Cast(typeof(object)), expression2.Convert(typeof(Type)));

                case TokenKind.Shl:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.LeftShift, true, false), typeof(object), expr, expression2);

                case TokenKind.Shr:
                    return Expression.Dynamic(PSBinaryOperationBinder.Get(ExpressionType.RightShift, true, false), typeof(object), expr, expression2);

                default:
                    throw new InvalidOperationException("Unknown token in binary operator.");
            }
            Expression expression = Expression.Call(CachedReflectionInfo.TypeOps_IsInstance, expr.Cast(typeof(object)), expression2.Cast(typeof(object)));
            if (binaryExpressionAst.Operator == TokenKind.IsNot)
            {
                expression = Expression.Not(expression);
            }
            return expression;
        }
Example #22
0
 private ExpressionAst ExpressionRule()
 {
     ExpressionAst expressionAst;
     ExpressionAst binaryExpressionAst;
     ParameterToken parameterToken;
     ExpressionAst expressionAst1;
     RuntimeHelpers.EnsureSufficientExecutionStack();
     TokenizerMode mode = this._tokenizer.Mode;
     try
     {
         this.SetTokenizerMode(TokenizerMode.Expression);
         ExpressionAst errorExpressionAst = this.ArrayLiteralRule();
         if (errorExpressionAst != null)
         {
             Token token = this.PeekToken();
             if (token.Kind.HasTrait(TokenFlags.BinaryOperator))
             {
                 this.SkipToken();
                 Stack<ExpressionAst> expressionAsts = new Stack<ExpressionAst>();
                 Stack<Token> tokens = new Stack<Token>();
                 expressionAsts.Push(errorExpressionAst);
                 tokens.Push(token);
                 int binaryPrecedence = token.Kind.GetBinaryPrecedence();
                 while (true)
                 {
                     this.SkipNewlines();
                     errorExpressionAst = this.ArrayLiteralRule();
                     if (errorExpressionAst == null)
                     {
                         IScriptExtent scriptExtent = Parser.After(token);
                         object[] text = new object[1];
                         text[0] = token.Text;
                         this.ReportIncompleteInput(scriptExtent, ParserStrings.ExpectedValueExpression, text);
                         errorExpressionAst = new ErrorExpressionAst(scriptExtent, null);
                     }
                     expressionAsts.Push(errorExpressionAst);
                     token = this.NextToken();
                     if (!token.Kind.HasTrait(TokenFlags.BinaryOperator))
                     {
                         break;
                     }
                     int num = token.Kind.GetBinaryPrecedence();
                     while (num <= binaryPrecedence)
                     {
                         binaryExpressionAst = expressionAsts.Pop();
                         expressionAst = expressionAsts.Pop();
                         Token token1 = tokens.Pop();
                         expressionAsts.Push(new BinaryExpressionAst(Parser.ExtentOf(expressionAst, binaryExpressionAst), expressionAst, token1.Kind, binaryExpressionAst, token1.Extent));
                         if (tokens.Count == 0)
                         {
                             break;
                         }
                         binaryPrecedence = tokens.Peek().Kind.GetBinaryPrecedence();
                     }
                     tokens.Push(token);
                     binaryPrecedence = num;
                 }
                 parameterToken = token as ParameterToken;
                 this.UngetToken(token);
                 binaryExpressionAst = expressionAsts.Pop();
                 while (expressionAsts.Any<ExpressionAst>())
                 {
                     expressionAst = expressionAsts.Pop();
                     token = tokens.Pop();
                     binaryExpressionAst = new BinaryExpressionAst(Parser.ExtentOf(expressionAst, binaryExpressionAst), expressionAst, token.Kind, binaryExpressionAst, token.Extent);
                 }
                 if (parameterToken == null)
                 {
                     expressionAst1 = binaryExpressionAst;
                 }
                 else
                 {
                     expressionAst1 = this.ErrorRecoveryParameterInExpression(parameterToken, binaryExpressionAst);
                 }
             }
             else
             {
                 parameterToken = token as ParameterToken;
                 if (parameterToken == null)
                 {
                     expressionAst1 = errorExpressionAst;
                 }
                 else
                 {
                     expressionAst1 = this.ErrorRecoveryParameterInExpression(parameterToken, errorExpressionAst);
                 }
             }
         }
         else
         {
             expressionAst1 = null;
         }
     }
     finally
     {
         this.SetTokenizerMode(mode);
     }
     return expressionAst1;
 }
Example #23
0
 public override AstVisitAction VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     if ((binaryExpressionAst.Operator == TokenKind.AndAnd) || (binaryExpressionAst.Operator == TokenKind.OrOr))
     {
         this._parser.ReportError(binaryExpressionAst.ErrorPosition, ParserStrings.InvalidEndOfLine, new object[] { binaryExpressionAst.Operator.Text() });
     }
     return AstVisitAction.Continue;
 }
 public override AstVisitAction VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     if (binaryExpressionAst.Operator.HasTrait(TokenFlags.DisallowedInRestrictedMode))
     {
         this.ReportError(binaryExpressionAst.ErrorPosition, () => ParserStrings.OperatorNotSupportedInDataSection, new object[] { binaryExpressionAst.Operator.Text() });
     }
     return AstVisitAction.Continue;
 }
Example #25
0
 public override AstVisitAction VisitBinaryExpression(BinaryExpressionAst ast)
 {
     return this.Check(ast);
 }
        /// <summary>
        /// Visit binary expression
        /// </summary>
        /// <param name="binaryExpressionAst"></param>
        /// <returns></returns>
        public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
        {
            if (binaryExpressionAst == null) return null;

            if (binaryExpressionAst.Operator == TokenKind.And || binaryExpressionAst.Operator == TokenKind.Or)
            {
                // Logical and/or are short circuit operators, so we need to simulate the control flow.  The
                // left operand is always evaluated, visit it's expression in the current block.
                binaryExpressionAst.Left.Visit(this.Decorator);

                // The right operand is conditionally evaluated.  We aren't generating any code here, just
                // modeling the flow graph, so we just visit the right operand in a new block, and have
                // both the current and new blocks both flow to a post-expression block.
                var targetBlock = new Block();
                var nextBlock = new Block();
                _currentBlock.FlowsTo(targetBlock);
                _currentBlock.FlowsTo(nextBlock);
                _currentBlock = nextBlock;

                binaryExpressionAst.Right.Visit(this.Decorator);

                _currentBlock.FlowsTo(targetBlock);
                _currentBlock = targetBlock;
            }
            else
            {
                binaryExpressionAst.Left.Visit(this.Decorator);
                binaryExpressionAst.Right.Visit(this.Decorator);
            }

            return null;
        }
Example #27
0
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     return (!((bool) binaryExpressionAst.Left.Accept(this)) ? ((object) 0) : ((object) ((bool) binaryExpressionAst.Right.Accept(this))));
 }
Example #28
0
        object EvaluateBinaryExpression(BinaryExpressionAst binaryExpressionAst)
        {
            var leftOperand = EvaluateAst(binaryExpressionAst.Left);
            var rightOperand = EvaluateAst(binaryExpressionAst.Right);

            switch (binaryExpressionAst.Operator)
            {
                case TokenKind.DotDot:
                    return Range((int)leftOperand, (int)rightOperand);

                case TokenKind.Plus:
                    return Add(leftOperand, rightOperand);

                case TokenKind.Ieq:
                    if (leftOperand.GetType() == typeof(int)) return ((int)leftOperand) == ((int)rightOperand);
                    throw new NotImplementedException(binaryExpressionAst.ToString());

                case TokenKind.Multiply:
                case TokenKind.Divide:
                case TokenKind.Minus:
                case TokenKind.Equals:
                case TokenKind.PlusEquals:
                case TokenKind.MinusEquals:
                case TokenKind.MultiplyEquals:
                case TokenKind.DivideEquals:
                case TokenKind.RemainderEquals:
                case TokenKind.Format:
                case TokenKind.Not:
                case TokenKind.Bnot:
                case TokenKind.And:
                case TokenKind.Or:
                case TokenKind.Xor:
                case TokenKind.Band:
                case TokenKind.Bor:
                case TokenKind.Bxor:
                case TokenKind.Join:
                case TokenKind.Ine:
                case TokenKind.Ige:
                case TokenKind.Igt:
                case TokenKind.Ilt:
                case TokenKind.Ile:
                case TokenKind.Ilike:
                case TokenKind.Inotlike:
                case TokenKind.Imatch:
                case TokenKind.Inotmatch:
                case TokenKind.Ireplace:
                case TokenKind.Icontains:
                case TokenKind.Inotcontains:
                case TokenKind.Iin:
                case TokenKind.Inotin:
                case TokenKind.Isplit:
                case TokenKind.Ceq:
                case TokenKind.Cne:
                case TokenKind.Cge:
                case TokenKind.Cgt:
                case TokenKind.Clt:
                case TokenKind.Cle:
                case TokenKind.Clike:
                case TokenKind.Cnotlike:
                case TokenKind.Cmatch:
                case TokenKind.Cnotmatch:
                case TokenKind.Creplace:
                case TokenKind.Ccontains:
                case TokenKind.Cnotcontains:
                case TokenKind.Cin:
                case TokenKind.Cnotin:
                case TokenKind.Csplit:
                case TokenKind.Is:
                case TokenKind.IsNot:
                case TokenKind.As:
                case TokenKind.Shl:
                case TokenKind.Shr:
                    throw new NotImplementedException(binaryExpressionAst.ToString());

                default:
                    throw new InvalidOperationException(binaryExpressionAst.ToString());
            }
        }
Example #29
0
 /// <summary/>
 public virtual object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     return(null);
 }
Example #30
0
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     return(CompileAndInvoke(binaryExpressionAst));
 }
Example #31
0
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     return (((!binaryExpressionAst.Operator.HasTrait(TokenFlags.CanConstantFold) || !((bool) binaryExpressionAst.Left.Accept(this))) || !((bool) binaryExpressionAst.Right.Accept(this))) ? ((object) false) : ((object) !IsNullDivisor(binaryExpressionAst.Right)));
 }
Example #32
0
 public override AstVisitAction VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     this._pipelineCommandRuntime.WriteObject(EvaluateBinaryExpression(binaryExpressionAst), true);
     return AstVisitAction.SkipChildren;
 }
Example #33
0
 /// <summary/>
 public virtual object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst) { return null; }
Example #34
0
 public virtual AstVisitAction VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     return AstVisitAction.Continue;
 }
Example #35
0
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     return(binaryExpressionAst.Operator.HasTrait(TokenFlags.CanConstantFold) &&
            (bool)binaryExpressionAst.Left.Accept(this) && (bool)binaryExpressionAst.Right.Accept(this) &&
            !IsNullDivisor(binaryExpressionAst.Right));
 }
Example #36
0
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     return binaryExpressionAst.Operator.HasTrait(TokenFlags.CanConstantFold) &&
         (bool)binaryExpressionAst.Left.Accept(this) && (bool)binaryExpressionAst.Right.Accept(this)
         && !IsNullDivisor(binaryExpressionAst.Right);
 }
Example #37
0
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     return(((!binaryExpressionAst.Operator.HasTrait(TokenFlags.CanConstantFold) || !((bool)binaryExpressionAst.Left.Accept(this))) || !((bool)binaryExpressionAst.Right.Accept(this))) ? ((object)false) : ((object)!IsNullDivisor(binaryExpressionAst.Right)));
 }
Example #38
0
 public override AstVisitAction VisitBinaryExpression(BinaryExpressionAst ast)
 {
     return(Check(ast));
 }
Example #39
0
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     CheckIsConstant(binaryExpressionAst, "Caller to verify ast is constant");
     return CompileAndInvoke(binaryExpressionAst);
 }
Example #40
0
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     // This can be used for a denial of service
     // Write-Output (((((("AAAAAAAAAAAAAAAAAAAAAA"*2)*2)*2)*2)*2)*2)
     // Keep on going with that pattern, and we're generating gigabytes of strings.
     return false;
 }
Example #41
0
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     // This can be used for a denial of service
     // Write-Output (((((("AAAAAAAAAAAAAAAAAAAAAA"*2)*2)*2)*2)*2)*2)
     // Keep on going with that pattern, and we're generating gigabytes of strings.
     throw PSTraceSource.NewArgumentException("ast");
 }
Example #42
0
 /// <summary/>
 public virtual AstVisitAction VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     return(AstVisitAction.Continue);
 }
Example #43
0
        public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
        {
            object constantValue;
            if (!CompilingConstantExpression && IsConstantValueVisitor.IsConstant(binaryExpressionAst, out constantValue))
            {
                return Expression.Constant(constantValue);
            }

            DynamicMetaObjectBinder binder;
            var lhs = CompileExpressionOperand(binaryExpressionAst.Left);
            var rhs = CompileExpressionOperand(binaryExpressionAst.Right);

            switch (binaryExpressionAst.Operator)
            {
                case TokenKind.And:
                    return Expression.AndAlso(lhs.Convert(typeof(bool)), rhs.Convert(typeof(bool)));
                case TokenKind.Or:
                    return Expression.OrElse(lhs.Convert(typeof(bool)), rhs.Convert(typeof(bool)));
                case TokenKind.Is:
                case TokenKind.IsNot:
                    if (rhs is ConstantExpression && rhs.Type == typeof(Type))
                    {
                        var isType = (Type)((ConstantExpression)rhs).Value;
                        if (!(isType == typeof(PSCustomObject)) && !(isType == typeof(PSObject)))
                        {
                            lhs = lhs.Type.GetTypeInfo().IsValueType ? lhs : Expression.Call(CachedReflectionInfo.PSObject_Base, lhs);
                            if (binaryExpressionAst.Operator == TokenKind.Is)
                                return Expression.TypeIs(lhs, isType);
                            return Expression.Not(Expression.TypeIs(lhs, isType));
                        }
                    }

                    Expression result = Expression.Call(CachedReflectionInfo.TypeOps_IsInstance, lhs.Cast(typeof(object)), rhs.Cast(typeof(object)));
                    if (binaryExpressionAst.Operator == TokenKind.IsNot)
                    {
                        result = Expression.Not(result);
                    }
                    return result;

                case TokenKind.As:
                    return Expression.Call(CachedReflectionInfo.TypeOps_AsOperator, lhs.Cast(typeof(object)), rhs.Convert(typeof(Type)));

                case TokenKind.DotDot:
                    return Expression.Call(CachedReflectionInfo.IntOps_Range,
                                           lhs.Convert(typeof(int)),
                                           rhs.Convert(typeof(int)));
                case TokenKind.Multiply:
                    if (lhs.Type == typeof(double) && rhs.Type == typeof(double))
                    {
                        return Expression.Multiply(lhs, rhs);
                    }
                    binder = PSBinaryOperationBinder.Get(ExpressionType.Multiply);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Divide:
                    if (lhs.Type == typeof(double) && rhs.Type == typeof(double))
                    {
                        return Expression.Divide(lhs, rhs);
                    }
                    binder = PSBinaryOperationBinder.Get(ExpressionType.Divide);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Rem:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.Modulo);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Plus:
                    if (lhs.Type == typeof(double) && rhs.Type == typeof(double))
                    {
                        return Expression.Add(lhs, rhs);
                    }
                    binder = PSBinaryOperationBinder.Get(ExpressionType.Add);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Minus:
                    if (lhs.Type == typeof(double) && rhs.Type == typeof(double))
                    {
                        return Expression.Subtract(lhs, rhs);
                    }
                    binder = PSBinaryOperationBinder.Get(ExpressionType.Subtract);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Format:
                    if (lhs.Type != typeof(string))
                    {
                        lhs = DynamicExpression.Dynamic(PSToStringBinder.Get(), typeof(string), lhs, _executionContextParameter);
                    }
                    return Expression.Call(CachedReflectionInfo.StringOps_FormatOperator, lhs, rhs.Cast(typeof(object)));
                case TokenKind.Xor:
                    return Expression.NotEqual(lhs.Convert(typeof(bool)), rhs.Convert(typeof(bool)));
                case TokenKind.Shl:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.LeftShift);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Shr:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.RightShift);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Band:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.And);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Bor:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.Or);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Bxor:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.ExclusiveOr);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Join:
                    // TODO: replace this with faster code
                    return Expression.Call(
                        CachedReflectionInfo.ParserOps_JoinOperator,
                        _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), lhs.Cast(typeof(object)), rhs.Cast(typeof(object)));
                case TokenKind.Ieq:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.Equal);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Ine:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.NotEqual);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Ige:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.GreaterThanOrEqual);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Igt:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.GreaterThan);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Ilt:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.LessThan);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Ile:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.LessThanOrEqual);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Ilike:
                    // TODO: replace this with faster code
                    return Expression.Call(
                        CachedReflectionInfo.ParserOps_LikeOperator,
                        _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition),
                        lhs.Cast(typeof(object)),
                        GetLikeRHSOperand(WildcardOptions.IgnoreCase, rhs).Cast(typeof(object)),
                        Expression.Constant(binaryExpressionAst.Operator));
                case TokenKind.Inotlike:
                    // TODO: replace this with faster code
                    return Expression.Call(
                        CachedReflectionInfo.ParserOps_LikeOperator,
                        _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition),
                        lhs.Cast(typeof(object)),
                        GetLikeRHSOperand(WildcardOptions.IgnoreCase, rhs).Cast(typeof(object)),
                        Expression.Constant(binaryExpressionAst.Operator));
                case TokenKind.Imatch:
                    // TODO: replace this with faster code
                    return Expression.Call(
                        CachedReflectionInfo.ParserOps_MatchOperator,
                        _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), lhs.Cast(typeof(object)), rhs.Cast(typeof(object)),
                        ExpressionCache.Constant(false), ExpressionCache.Constant(true));
                case TokenKind.Inotmatch:
                    // TODO: replace this with faster code
                    return Expression.Call(
                        CachedReflectionInfo.ParserOps_MatchOperator,
                        _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), lhs.Cast(typeof(object)), rhs.Cast(typeof(object)),
                        ExpressionCache.Constant(true), ExpressionCache.Constant(true));
                case TokenKind.Ireplace:
                    // TODO: replace this with faster code
                    return Expression.Call(
                        CachedReflectionInfo.ParserOps_ReplaceOperator,
                        _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), lhs.Cast(typeof(object)), rhs.Cast(typeof(object)),
                        ExpressionCache.Constant(true));
                case TokenKind.Icontains:
                    return GenerateCallContains(lhs, rhs, true);
                case TokenKind.Inotcontains:
                    return Expression.Not(GenerateCallContains(lhs, rhs, true));
                case TokenKind.Iin:
                    return GenerateCallContains(rhs, lhs, true);
                case TokenKind.Inotin:
                    return Expression.Not(GenerateCallContains(rhs, lhs, true));
                case TokenKind.Isplit:
                    // TODO: replace this with faster code
                    return Expression.Call(
                        CachedReflectionInfo.ParserOps_SplitOperator,
                        _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), lhs.Cast(typeof(object)), rhs.Cast(typeof(object)),
                        ExpressionCache.Constant(true));
                case TokenKind.Ceq:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.Equal, false);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Cne:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.NotEqual, false);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Cge:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.GreaterThanOrEqual, false);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Cgt:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.GreaterThan, false);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Clt:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.LessThan, false);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Cle:
                    binder = PSBinaryOperationBinder.Get(ExpressionType.LessThanOrEqual, false);
                    return DynamicExpression.Dynamic(binder, typeof(object), lhs, rhs);
                case TokenKind.Clike:
                    // TODO: replace this with faster code
                    return Expression.Call(
                        CachedReflectionInfo.ParserOps_LikeOperator,
                        _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition),
                        lhs.Cast(typeof(object)),
                        GetLikeRHSOperand(WildcardOptions.None, rhs).Cast(typeof(object)),
                        Expression.Constant(binaryExpressionAst.Operator));
                case TokenKind.Cnotlike:
                    // TODO: replace this with faster code
                    return Expression.Call(
                        CachedReflectionInfo.ParserOps_LikeOperator,
                        _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition),
                        lhs.Cast(typeof(object)),
                        GetLikeRHSOperand(WildcardOptions.None, rhs).Cast(typeof(object)),
                        Expression.Constant(binaryExpressionAst.Operator));
                case TokenKind.Cmatch:
                    // TODO: replace this with faster code
                    return Expression.Call(
                        CachedReflectionInfo.ParserOps_MatchOperator,
                        _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), lhs.Cast(typeof(object)), rhs.Cast(typeof(object)),
                        ExpressionCache.Constant(false), ExpressionCache.Constant(false));
                case TokenKind.Cnotmatch:
                    // TODO: replace this with faster code
                    return Expression.Call(
                        CachedReflectionInfo.ParserOps_MatchOperator,
                        _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), lhs.Cast(typeof(object)), rhs.Cast(typeof(object)),
                        ExpressionCache.Constant(true), ExpressionCache.Constant(false));
                case TokenKind.Creplace:
                    // TODO: replace this with faster code
                    return Expression.Call(
                        CachedReflectionInfo.ParserOps_ReplaceOperator,
                        _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), lhs.Cast(typeof(object)), rhs.Cast(typeof(object)),
                        ExpressionCache.Constant(false));
                case TokenKind.Ccontains:
                    return GenerateCallContains(lhs, rhs, false);
                case TokenKind.Cnotcontains:
                    return Expression.Not(GenerateCallContains(lhs, rhs, false));
                case TokenKind.Cin:
                    return GenerateCallContains(rhs, lhs, false);
                case TokenKind.Cnotin:
                    return Expression.Not(GenerateCallContains(rhs, lhs, false));
                case TokenKind.Csplit:
                    // TODO: replace this with faster code
                    return Expression.Call(
                        CachedReflectionInfo.ParserOps_SplitOperator,
                        _executionContextParameter, Expression.Constant(binaryExpressionAst.ErrorPosition), lhs.Cast(typeof(object)), rhs.Cast(typeof(object)),
                        ExpressionCache.Constant(false));
            }

            throw new InvalidOperationException("Unknown token in binary operator.");
        }
Example #44
0
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     CheckIsConstant(binaryExpressionAst, "Caller to verify ast is constant");
     return(CompileAndInvoke(binaryExpressionAst));
 }
 public object VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
 {
     throw new NotImplementedException();
 }