Beispiel #1
0
        protected override SyntaxToken VisitBinary(BinarySyntaxToken token)
        {
            SyntaxToken left = this.Visit(token.Left);
            SyntaxToken right = this.Visit(token.Right);
            BinaryOperationType type = token.Type;
            if (left.TokenType == SyntaxTokenType.Constant && right.TokenType == SyntaxTokenType.Constant)
            {
                return this.EvalBinary((ConstantSyntaxToken)left, (ConstantSyntaxToken)right, type);
            }
            // swap constant to the right
            if ((type == BinaryOperationType.Add || type == BinaryOperationType.Multiply) && (left.TokenType == SyntaxTokenType.Constant))
            {
                SyntaxToken temp = right;
                right = left;
                left = temp;
            }
            // add
            if (type == BinaryOperationType.Add)
            {
                if (right.HasValue(0))
                {
                    return left;
                }
            }
            // subtract
            else if (type == BinaryOperationType.Subtract)
            {
                if (right.HasValue(0))
                {
                    return left;
                }
                if (SyntaxToken.Equals(left, right))
                {
                    return SyntaxToken.Constant(0);
                }
            }
            // multiply
            else if (type == BinaryOperationType.Multiply)
            {
                if (right.HasValue(0))
                {
                    return SyntaxToken.Constant(0);
                }
                if (right.HasValue(1))
                {
                    return left;
                }
                if (left.TokenType == SyntaxTokenType.Binary && right.TokenType == SyntaxTokenType.Binary)
                {
                    BinarySyntaxToken bl = (BinarySyntaxToken)left;
                    BinarySyntaxToken br = (BinarySyntaxToken)right;
                    if (bl.Type == BinaryOperationType.Power && br.Type == BinaryOperationType.Power && SyntaxToken.Equals(bl.Left, br.Left))
                    {
                        return this.Visit(SyntaxToken.Pow(bl.Left, SyntaxToken.Add(bl.Right, br.Right)));
                    }
                }
            }
            // divide
            else if (type == BinaryOperationType.Divide)
            {
                if (left.HasValue(0))
                {
                    return SyntaxToken.Constant(0);
                }
                if (SyntaxToken.Equals(left, right))
                {
                    return SyntaxToken.Constant(1);
                }
            }
            // modulus
            else if (type == BinaryOperationType.Modulus)
            {
                if (left.HasValue(0))
                {
                    return SyntaxToken.Constant(0);
                }
                if (SyntaxToken.Equals(left, right))
                {
                    return SyntaxToken.Constant(0);
                }
            }
            // pow
            else if (type == BinaryOperationType.Power)
            {
                if (right.HasValue(0))
                {
                    return SyntaxToken.Constant(1);
                }
                if (right.HasValue(1))
                {
                    return left;
                }
                if (left.HasValue(0))
                {
                    return SyntaxToken.Constant(1);
                }
                if (left.TokenType == SyntaxTokenType.Binary)
                {
                    BinarySyntaxToken bl = (BinarySyntaxToken)left;
                    if (bl.Type == BinaryOperationType.Power)
                    {
                        return this.Visit(SyntaxToken.Pow(bl.Left, SyntaxToken.Multiply(bl.Right, right)));
                    }
                }
            }

            return SyntaxToken.Binary(left, right, type);
        }