Esempio n. 1
0
            private void CompileLiteralOrdinal(XPathExpr expr)
            {
                int ordinal = 0;

                try
                {
                    XPathNumberExpr expr2 = (XPathNumberExpr)expr;
                    ordinal = Convert.ToInt32(expr2.Number);
                    if (expr2.Negate)
                    {
                        ordinal      = -ordinal;
                        expr2.Negate = false;
                    }
                    if (ordinal < 1)
                    {
                        this.ThrowError(QueryCompileError.InvalidOrdinal);
                    }
                }
                catch (OverflowException)
                {
                    this.ThrowError(QueryCompileError.InvalidOrdinal);
                }
                if ((this.compiler.flags & QueryCompilerFlags.InverseQuery) != QueryCompilerFlags.None)
                {
                    this.codeBlock.Append(new PushContextPositionOpcode());
                    this.codeBlock.Append(new NumberEqualsOpcode((double)ordinal));
                }
                else
                {
                    this.codeBlock.Append(new LiteralOrdinalOpcode(ordinal));
                }
            }
Esempio n. 2
0
            void CompileNumberRelation(XPathRelationExpr expr)
            {
                if (expr.Op == RelationOperator.Eq)
                {
                    this.CompileNumberLiteralEquality(expr);
                    return;
                }

                bool leftNumber  = (XPathExprType.Number == expr.Left.Type);
                bool rightNumber = (XPathExprType.Number == expr.Right.Type);

                Fx.Assert(leftNumber || rightNumber, "");
                Fx.Assert(!(leftNumber && rightNumber), "");

                this.CompileExpression(leftNumber ? expr.Right : expr.Left);
                XPathNumberExpr litExpr = leftNumber ? (XPathNumberExpr)expr.Left : (XPathNumberExpr)expr.Right;
                double          literal = litExpr.Number;

                if (litExpr.Negate)
                {
                    litExpr.Negate = false;
                    literal        = -literal;
                }

                // To maximize code branch commonality, we canonacalize the relation expressions so that the non-literal
                // is always to the left and the literal to the right. If this makes us swap expressions, we must also flip
                // relation operators appropriately.
                if (leftNumber)
                {
                    // Flip operators
                    switch (expr.Op)
                    {
                    case RelationOperator.Gt:
                        expr.Op = RelationOperator.Lt;
                        break;

                    case RelationOperator.Ge:
                        expr.Op = RelationOperator.Le;
                        break;

                    case RelationOperator.Lt:
                        expr.Op = RelationOperator.Gt;
                        break;

                    case RelationOperator.Le:
                        expr.Op = RelationOperator.Ge;
                        break;
                    }
                }

                if (0 != (this.compiler.flags & QueryCompilerFlags.InverseQuery))
                {
                    this.codeBlock.Append(new NumberIntervalOpcode(literal, expr.Op));
                }
                else
                {
                    this.codeBlock.Append(new NumberRelationOpcode(literal, expr.Op));
                }
            }
Esempio n. 3
0
            private void CompileNumberRelation(XPathRelationExpr expr)
            {
                if (expr.Op == RelationOperator.Eq)
                {
                    this.CompileNumberLiteralEquality(expr);
                }
                else
                {
                    bool          flag = XPathExprType.Number == expr.Left.Type;
                    XPathExprType type = expr.Right.Type;
                    this.CompileExpression(flag ? expr.Right : expr.Left);
                    XPathNumberExpr expr2  = flag ? ((XPathNumberExpr)expr.Left) : ((XPathNumberExpr)expr.Right);
                    double          number = expr2.Number;
                    if (expr2.Negate)
                    {
                        expr2.Negate = false;
                        number       = -number;
                    }
                    if (flag)
                    {
                        switch (expr.Op)
                        {
                        case RelationOperator.Gt:
                            expr.Op = RelationOperator.Lt;
                            break;

                        case RelationOperator.Ge:
                            expr.Op = RelationOperator.Le;
                            break;

                        case RelationOperator.Lt:
                            expr.Op = RelationOperator.Gt;
                            break;

                        case RelationOperator.Le:
                            expr.Op = RelationOperator.Ge;
                            break;
                        }
                    }
                    if ((this.compiler.flags & QueryCompilerFlags.InverseQuery) != QueryCompilerFlags.None)
                    {
                        this.codeBlock.Append(new NumberIntervalOpcode(number, expr.Op));
                    }
                    else
                    {
                        this.codeBlock.Append(new NumberRelationOpcode(number, expr.Op));
                    }
                }
            }
Esempio n. 4
0
            private void CompileNumberLiteralEquality(XPathRelationExpr expr)
            {
                bool          flag = XPathExprType.Number == expr.Left.Type;
                XPathExprType type = expr.Right.Type;

                this.CompileExpression(flag ? expr.Right : expr.Left);
                XPathNumberExpr expr2  = flag ? ((XPathNumberExpr)expr.Left) : ((XPathNumberExpr)expr.Right);
                double          number = expr2.Number;

                if (expr2.Negate)
                {
                    expr2.Negate = false;
                    number       = -number;
                }
                this.codeBlock.Append(new NumberEqualsOpcode(number));
            }
Esempio n. 5
0
            void CompileNumberLiteralEquality(XPathRelationExpr expr)
            {
                Fx.Assert(expr.Op == RelationOperator.Eq, "");

                bool leftNumber  = (XPathExprType.Number == expr.Left.Type);
                bool rightNumber = (XPathExprType.Number == expr.Right.Type);

                Fx.Assert(leftNumber || rightNumber, "");
                Fx.Assert(!(leftNumber && rightNumber), "");

                this.CompileExpression(leftNumber ? expr.Right : expr.Left);
                XPathNumberExpr litExpr = leftNumber ? (XPathNumberExpr)expr.Left : (XPathNumberExpr)expr.Right;
                double          literal = litExpr.Number;

                if (litExpr.Negate)
                {
                    litExpr.Negate = false;
                    literal        = -literal;
                }
                this.codeBlock.Append(new NumberEqualsOpcode(literal));
            }
Esempio n. 6
0
            private void CompileExpression(XPathExpr expr)
            {
                switch (expr.Type)
                {
                case XPathExprType.Or:
                    this.CompileBoolean(expr, false);
                    break;

                case XPathExprType.And:
                    this.CompileBoolean(expr, true);
                    break;

                case XPathExprType.Relational:
                    this.CompileRelational((XPathRelationExpr)expr);
                    break;

                case XPathExprType.Union:
                {
                    XPathConjunctExpr expr2 = (XPathConjunctExpr)expr;
                    this.CompileExpression(expr2.Left);
                    this.CompileExpression(expr2.Right);
                    this.codeBlock.Append(new UnionOpcode());
                    break;
                }

                case XPathExprType.LocationPath:
                    if (expr.SubExprCount > 0)
                    {
                        this.CompileLocationPath(expr);
                        this.codeBlock.Append(new PopSequenceToValueStackOpcode());
                    }
                    break;

                case XPathExprType.RelativePath:
                    this.CompileRelativePath(expr, true);
                    break;

                case XPathExprType.XsltVariable:
                    this.CompileXsltVariable((XPathXsltVariableExpr)expr);
                    break;

                case XPathExprType.String:
                    this.codeBlock.Append(new PushStringOpcode(((XPathStringExpr)expr).String));
                    break;

                case XPathExprType.Number:
                {
                    XPathNumberExpr expr3  = (XPathNumberExpr)expr;
                    double          number = expr3.Number;
                    if (expr3.Negate)
                    {
                        expr3.Negate = false;
                        number       = -number;
                    }
                    this.codeBlock.Append(new PushNumberOpcode(number));
                    break;
                }

                case XPathExprType.Function:
                    this.CompileFunction((XPathFunctionExpr)expr);
                    break;

                case XPathExprType.XsltFunction:
                    this.CompileXsltFunction((XPathXsltFunctionExpr)expr);
                    break;

                case XPathExprType.Math:
                    this.CompileMath((XPathMathExpr)expr);
                    break;

                case XPathExprType.Filter:
                    this.CompileFilter(expr);
                    if (expr.ReturnType == ValueDataType.Sequence)
                    {
                        this.codeBlock.Append(new PopSequenceToValueStackOpcode());
                    }
                    break;

                case XPathExprType.Path:
                    this.CompilePath(expr);
                    if ((expr.SubExprCount == 0) && (expr.ReturnType == ValueDataType.Sequence))
                    {
                        this.codeBlock.Append(new PopSequenceToValueStackOpcode());
                    }
                    break;

                default:
                    this.ThrowError(QueryCompileError.UnsupportedExpression);
                    break;
                }
                this.NegateIfRequired(expr);
            }
Esempio n. 7
0
            void CompileExpression(XPathExpr expr)
            {
                Fx.Assert(null != expr, "");

                switch (expr.Type)
                {
                default:
                    this.ThrowError(QueryCompileError.UnsupportedExpression);
                    break;

                case XPathExprType.And:
                    this.CompileBoolean(expr, true);
                    break;

                case XPathExprType.Or:
                    this.CompileBoolean(expr, false);
                    break;

                case XPathExprType.Relational:
                    this.CompileRelational((XPathRelationExpr)expr);
                    break;

                case XPathExprType.Function:
                    this.CompileFunction((XPathFunctionExpr)expr);
                    break;

                case XPathExprType.Union:
                {
                    XPathConjunctExpr unionExpr = (XPathConjunctExpr)expr;
                    this.CompileExpression(unionExpr.Left);
                    this.CompileExpression(unionExpr.Right);
                    this.codeBlock.Append(new UnionOpcode());
                }
                break;

                case XPathExprType.RelativePath:
                    this.CompileRelativePath(expr, true);
                    break;

                case XPathExprType.LocationPath:
                    if (expr.SubExprCount > 0)
                    {
                        this.CompileLocationPath(expr);
                        // Step complete. Transfer results onto the value stack
                        this.codeBlock.Append(new PopSequenceToValueStackOpcode());
                    }
                    break;

                case XPathExprType.Math:
                    this.CompileMath((XPathMathExpr)expr);
                    break;

                case XPathExprType.Number:
                    XPathNumberExpr number  = (XPathNumberExpr)expr;
                    double          literal = number.Number;
                    if (number.Negate)
                    {
                        number.Negate = false;
                        literal       = -literal;
                    }
                    this.codeBlock.Append(new PushNumberOpcode(literal));
                    break;

                case XPathExprType.String:
                    this.codeBlock.Append(new PushStringOpcode(((XPathStringExpr)expr).String));
                    break;

                case XPathExprType.Filter:
                    this.CompileFilter(expr);
                    if (expr.ReturnType == ValueDataType.Sequence)
                    {
                        this.codeBlock.Append(new PopSequenceToValueStackOpcode());
                    }
                    break;

                case XPathExprType.Path:
                    this.CompilePath(expr);
                    if (expr.SubExprCount == 0 && expr.ReturnType == ValueDataType.Sequence)
                    {
                        this.codeBlock.Append(new PopSequenceToValueStackOpcode());
                    }
                    break;

                case XPathExprType.XsltFunction:
                    this.CompileXsltFunction((XPathXsltFunctionExpr)expr);
                    break;

                case XPathExprType.XsltVariable:
                    this.CompileXsltVariable((XPathXsltVariableExpr)expr);
                    break;
                }

                NegateIfRequired(expr);
            }