Ejemplo n.º 1
0
        public static CodegenExpression Codegen(
            ExprBetweenNodeForge forge,
            CodegenMethodScope codegenMethodScope,
            ExprForgeCodegenSymbol exprSymbol,
            CodegenClassScope codegenClassScope)
        {
            var nodes = forge.ForgeRenderable.ChildNodes;
            var value = nodes[0].Forge;
            var lower = nodes[1].Forge;
            var higher = nodes[2].Forge;
            var isNot = forge.ForgeRenderable.IsNotBetween;

            var methodNode = codegenMethodScope.MakeChild(
                typeof(bool?),
                typeof(ExprBetweenNodeForgeEval),
                codegenClassScope);
            var block = methodNode.Block;

            var valueType = value.EvaluationType.GetBoxedType();
            block.DeclareVar(
                valueType,
                "value",
                value.EvaluateCodegen(valueType, methodNode, exprSymbol, codegenClassScope));
            if (valueType.CanBeNull()) {
                block.IfRefNullReturnFalse("value");
            }

            var lowerType = lower.EvaluationType.GetBoxedType();
            block.DeclareVar(
                lowerType,
                "lower",
                lower.EvaluateCodegen(lowerType, methodNode, exprSymbol, codegenClassScope));
            if (lowerType.CanBeNull()) {
                block.IfRefNull("lower").BlockReturn(Constant(isNot));
            }

            var higherType = higher.EvaluationType.GetBoxedType();
            block.DeclareVar(
                higherType,
                "higher",
                higher.EvaluateCodegen(higherType, methodNode, exprSymbol, codegenClassScope));
            if (higher.EvaluationType.CanBeNull()) {
                block.IfRefNull("higher").BlockReturn(Constant(isNot));
            }

            block.DeclareVar<bool>(
                "result",
                forge.Computer.CodegenNoNullCheck(
                    Unbox(Ref("value"), valueType),
                    value.EvaluationType,
                    Unbox(Ref("lower"), lowerType),
                    lower.EvaluationType,
                    Unbox(Ref("higher"), higherType),
                    higher.EvaluationType,
                    methodNode,
                    codegenClassScope));
            block.MethodReturn(NotOptional(forge.ForgeRenderable.IsNotBetween, Ref("result")));
            return LocalMethod(methodNode);
        }
Ejemplo n.º 2
0
        public override ExprNode Validate(ExprValidationContext validationContext)
        {
            if (ChildNodes.Length != 3) {
                throw new ExprValidationException("The Between operator requires exactly 3 child expressions");
            }

            // Must be either numeric or string
            var forges = ExprNodeUtilityQuery.GetForges(ChildNodes);
            var typeOne = forges[0].EvaluationType.GetBoxedType();
            var typeTwo = forges[1].EvaluationType.GetBoxedType();
            var typeThree = forges[2].EvaluationType.GetBoxedType();

            if (typeOne == null) {
                throw new ExprValidationException("Null value not allowed in between-clause");
            }

            Type compareType;
            var isAlwaysFalse = false;
            ExprBetweenComp computer = null;
            if (typeTwo == null || typeThree == null) {
                isAlwaysFalse = true;
            }
            else {
                if (typeOne != typeof(string) || typeTwo != typeof(string) || typeThree != typeof(string)) {
                    if (!typeOne.IsNumeric()) {
                        throw new ExprValidationException(
                            "Implicit conversion from datatype '" +
                            typeOne.CleanName() +
                            "' to numeric is not allowed");
                    }

                    if (!typeTwo.IsNumeric()) {
                        throw new ExprValidationException(
                            "Implicit conversion from datatype '" +
                            typeTwo.CleanName() +
                            "' to numeric is not allowed");
                    }

                    if (!typeThree.IsNumeric()) {
                        throw new ExprValidationException(
                            "Implicit conversion from datatype '" +
                            typeThree.CleanName() +
                            "' to numeric is not allowed");
                    }
                }

                var intermedType = typeOne.GetCompareToCoercionType(typeTwo);
                compareType = intermedType.GetCompareToCoercionType(typeThree);
                computer = MakeComputer(compareType, typeOne, typeTwo, typeThree);
            }

            _forge = new ExprBetweenNodeForge(this, computer, isAlwaysFalse);
            return null;
        }
Ejemplo n.º 3
0
 public ExprBetweenNodeForgeEval(
     ExprBetweenNodeForge forge,
     ExprEvaluator valueEval,
     ExprEvaluator lowerEval,
     ExprEvaluator higherEval)
 {
     _forge = forge;
     _valueEval = valueEval;
     _lowerEval = lowerEval;
     _higherEval = higherEval;
 }