diff --git a/src/Parser/XnParser.cs b/src/Parser/XnParser.cs index 1e7c54e..0a6e086 100644 --- a/src/Parser/XnParser.cs +++ b/src/Parser/XnParser.cs @@ -12,6 +12,7 @@ using Rule = XNeedle.Transformation.Rule; using System.Data; using System.ComponentModel.DataAnnotations; using System.Text; +using System.Security.AccessControl; namespace XNeedle.Parser { @@ -126,7 +127,18 @@ namespace XNeedle.Parser static Parser Term(Context ctx) { - return Parse.ChainOperator(Multiply.Or(Divide).Or(Modulo).Or(BitwiseXor).Or(BitwiseAnd).Or(BitwiseOr), InnerTerm(ctx), Expression.MakeBinary); + return Parse.ChainOperator(Multiply.Or(Divide), InnerTerm(ctx), Expression.MakeBinary); + } + + static Parser IntegerTerm(Context ctx) + { + // Integer operations can't deal with doubles, so we need to make unary casts to integer and back + return Parse.ChainOperator(Multiply.Or(Divide).Or(Modulo).Or(BitwiseXor).Or(BitwiseAnd).Or(BitwiseOr), + InnerTerm(ctx), (bt,left,right)=>Expression.MakeUnary( + ExpressionType.Convert, Expression.MakeBinary(bt, + Expression.MakeUnary(ExpressionType.Convert, left, typeof(long)), + Expression.MakeUnary(ExpressionType.Convert, right, typeof(long))), + typeof(double))); } static Parser ConcatExpr(Context ctx) @@ -141,7 +153,7 @@ namespace XNeedle.Parser static Parser ArithExpr(Context ctx) { - return Parse.ChainOperator(Add.Or(Subtract), Term(ctx), Expression.MakeBinary); + return Parse.ChainOperator(Add.Or(Subtract), IntegerTerm(ctx).Or(Term(ctx)), Expression.MakeBinary); } static Parser Expr(Context ctx)