예제 #1
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);
            }
예제 #2
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);
            }