void CompileMath(XPathMathExpr mathExpr) { // are we doing math on two literal numbers? If so, do it at compile time if (XPathExprType.Number == mathExpr.Right.Type && XPathExprType.Number == mathExpr.Left.Type) { double left = ((XPathNumberExpr)mathExpr.Left).Number; if (((XPathNumberExpr)mathExpr.Left).Negate) { ((XPathNumberExpr)mathExpr.Left).Negate = false; left = -left; } double right = ((XPathNumberExpr)mathExpr.Right).Number; if (((XPathNumberExpr)mathExpr.Right).Negate) { ((XPathNumberExpr)mathExpr.Right).Negate = false; right = -right; } switch (mathExpr.Op) { case MathOperator.Div: left /= right; break; case MathOperator.Minus: left -= right; break; case MathOperator.Mod: left %= right; break; case MathOperator.Multiply: left *= right; break; case MathOperator.Plus: left += right; break; } this.codeBlock.Append(new PushNumberOpcode(left)); return; } // Arguments are pushed C style - right to left this.CompileExpression(mathExpr.Right); if (ValueDataType.Double != mathExpr.Right.ReturnType) { this.CompileTypecast(ValueDataType.Double); } this.CompileExpression(mathExpr.Left); if (ValueDataType.Double != mathExpr.Left.ReturnType) { this.CompileTypecast(ValueDataType.Double); } this.codeBlock.Append(this.CreateMathOpcode(mathExpr.Op)); }
private void CompileMath(XPathMathExpr mathExpr) { if ((XPathExprType.Number != mathExpr.Right.Type) || (XPathExprType.Number != mathExpr.Left.Type)) { this.CompileExpression(mathExpr.Right); if (ValueDataType.Double != mathExpr.Right.ReturnType) { this.CompileTypecast(ValueDataType.Double); } this.CompileExpression(mathExpr.Left); if (ValueDataType.Double != mathExpr.Left.ReturnType) { this.CompileTypecast(ValueDataType.Double); } this.codeBlock.Append(this.CreateMathOpcode(mathExpr.Op)); } else { double number = ((XPathNumberExpr)mathExpr.Left).Number; if (((XPathNumberExpr)mathExpr.Left).Negate) { ((XPathNumberExpr)mathExpr.Left).Negate = false; number = -number; } double num2 = ((XPathNumberExpr)mathExpr.Right).Number; if (((XPathNumberExpr)mathExpr.Right).Negate) { ((XPathNumberExpr)mathExpr.Right).Negate = false; num2 = -num2; } switch (mathExpr.Op) { case MathOperator.Plus: number += num2; break; case MathOperator.Minus: number -= num2; break; case MathOperator.Div: number /= num2; break; case MathOperator.Multiply: number *= num2; break; case MathOperator.Mod: number = number % num2; break; } this.codeBlock.Append(new PushNumberOpcode(number)); } }
XPathExpr ParseMultiplicativeExpression() { XPathExpr leftExpr = this.ParseUnaryExpression(); if (null != leftExpr) { MathOperator op; do { op = MathOperator.None; XPathToken token = this.NextToken(); if (null != token) { switch (token.TokenID) { default: this.PushToken(token); break; case XPathTokenID.Multiply: op = MathOperator.Multiply; break; case XPathTokenID.Div: op = MathOperator.Div; break; case XPathTokenID.Mod: op = MathOperator.Mod; break; } if (MathOperator.None != op) { XPathExpr rightExpr = this.ParseUnaryExpression(); if (null == rightExpr) { this.ThrowError(QueryCompileError.InvalidExpression); } leftExpr = new XPathMathExpr(op, leftExpr, rightExpr); } } } while (MathOperator.None != op); } return(leftExpr); }
private XPathExpr ParseMultiplicativeExpression() { XPathExpr left = this.ParseUnaryExpression(); if (left != null) { MathOperator none; do { none = MathOperator.None; XPathToken token = this.NextToken(); if (token != null) { XPathTokenID tokenID = token.TokenID; if (tokenID == XPathTokenID.Multiply) { none = MathOperator.Multiply; } else if (tokenID == XPathTokenID.Mod) { none = MathOperator.Mod; } else if (tokenID == XPathTokenID.Div) { none = MathOperator.Div; } else { this.PushToken(token); } if (none != MathOperator.None) { XPathExpr right = this.ParseUnaryExpression(); if (right == null) { this.ThrowError(QueryCompileError.InvalidExpression); } left = new XPathMathExpr(none, left, right); } } }while (none != MathOperator.None); } return(left); }
private XPathExpr ParseAdditiveExpression() { XPathExpr left = this.ParseMultiplicativeExpression(); if (left != null) { MathOperator none; do { none = MathOperator.None; XPathToken token = this.NextToken(); if (token != null) { switch (token.TokenID) { case XPathTokenID.Plus: none = MathOperator.Plus; break; case XPathTokenID.Minus: none = MathOperator.Minus; break; default: this.PushToken(token); break; } if (none != MathOperator.None) { XPathExpr right = this.ParseMultiplicativeExpression(); if (right == null) { this.ThrowError(QueryCompileError.InvalidExpression); } left = new XPathMathExpr(none, left, right); } } }while (none != MathOperator.None); } return(left); }
XPathExpr ParseMultiplicativeExpression() { XPathExpr leftExpr = this.ParseUnaryExpression(); if (null != leftExpr) { MathOperator op; do { op = MathOperator.None; XPathToken token = this.NextToken(); if (null != token) { switch (token.TokenID) { default: this.PushToken(token); break; case XPathTokenID.Multiply: op = MathOperator.Multiply; break; case XPathTokenID.Div: op = MathOperator.Div; break; case XPathTokenID.Mod: op = MathOperator.Mod; break; } if (MathOperator.None != op) { XPathExpr rightExpr = this.ParseUnaryExpression(); if (null == rightExpr) { this.ThrowError(QueryCompileError.InvalidExpression); } leftExpr = new XPathMathExpr(op, leftExpr, rightExpr); } } } while (MathOperator.None != op); } return leftExpr; }
private void CompileMath(XPathMathExpr mathExpr) { if ((XPathExprType.Number != mathExpr.Right.Type) || (XPathExprType.Number != mathExpr.Left.Type)) { this.CompileExpression(mathExpr.Right); if (ValueDataType.Double != mathExpr.Right.ReturnType) { this.CompileTypecast(ValueDataType.Double); } this.CompileExpression(mathExpr.Left); if (ValueDataType.Double != mathExpr.Left.ReturnType) { this.CompileTypecast(ValueDataType.Double); } this.codeBlock.Append(this.CreateMathOpcode(mathExpr.Op)); } else { double number = ((XPathNumberExpr) mathExpr.Left).Number; if (((XPathNumberExpr) mathExpr.Left).Negate) { ((XPathNumberExpr) mathExpr.Left).Negate = false; number = -number; } double num2 = ((XPathNumberExpr) mathExpr.Right).Number; if (((XPathNumberExpr) mathExpr.Right).Negate) { ((XPathNumberExpr) mathExpr.Right).Negate = false; num2 = -num2; } switch (mathExpr.Op) { case MathOperator.Plus: number += num2; break; case MathOperator.Minus: number -= num2; break; case MathOperator.Div: number /= num2; break; case MathOperator.Multiply: number *= num2; break; case MathOperator.Mod: number = number % num2; break; } this.codeBlock.Append(new PushNumberOpcode(number)); } }
private XPathExpr ParseMultiplicativeExpression() { XPathExpr left = this.ParseUnaryExpression(); if (left != null) { MathOperator none; do { none = MathOperator.None; XPathToken token = this.NextToken(); if (token != null) { XPathTokenID tokenID = token.TokenID; if (tokenID == XPathTokenID.Multiply) { none = MathOperator.Multiply; } else if (tokenID == XPathTokenID.Mod) { none = MathOperator.Mod; } else if (tokenID == XPathTokenID.Div) { none = MathOperator.Div; } else { this.PushToken(token); } if (none != MathOperator.None) { XPathExpr right = this.ParseUnaryExpression(); if (right == null) { this.ThrowError(QueryCompileError.InvalidExpression); } left = new XPathMathExpr(none, left, right); } } } while (none != MathOperator.None); } return left; }
private XPathExpr ParseAdditiveExpression() { XPathExpr left = this.ParseMultiplicativeExpression(); if (left != null) { MathOperator none; do { none = MathOperator.None; XPathToken token = this.NextToken(); if (token != null) { switch (token.TokenID) { case XPathTokenID.Plus: none = MathOperator.Plus; break; case XPathTokenID.Minus: none = MathOperator.Minus; break; default: this.PushToken(token); break; } if (none != MathOperator.None) { XPathExpr right = this.ParseMultiplicativeExpression(); if (right == null) { this.ThrowError(QueryCompileError.InvalidExpression); } left = new XPathMathExpr(none, left, right); } } } while (none != MathOperator.None); } return left; }