public CodegenExpression Codegen(
                CodegenMethodScope codegenMethodScope,
                CodegenClassScope codegenClassScope,
                CodegenExpressionRef left,
                CodegenExpressionRef right,
                Type ltype,
                Type rtype)
            {
                var resultType = typeof(decimal);

                if (ltype.IsNullable() || rtype.IsNullable() || _divisionByZeroReturnsNull)
                {
                    resultType = typeof(decimal?);
                }

                var block = codegenMethodScope
                            .MakeChild(resultType, typeof(DivideDecimalConvComputerBase), codegenClassScope)
                            .AddParam(ltype, "d1")
                            .AddParam(rtype, "d2")
                            .Block
                            .DeclareVar <decimal>(
                    "s1",
                    _convOne.CoerceCodegen(CodegenExpressionBuilder.Ref("d1"), ltype))
                            .DeclareVar <decimal>(
                    "s2",
                    _convTwo.CoerceCodegen(CodegenExpressionBuilder.Ref("d2"), rtype));
                var ifZeroDivisor =
                    block.IfCondition(
                        CodegenExpressionBuilder.EqualsIdentity(
                            CodegenExpressionBuilder.Ref("s2"),
                            CodegenExpressionBuilder.Constant(0.0m)));

                if (_divisionByZeroReturnsNull)
                {
                    ifZeroDivisor.BlockReturn(CodegenExpressionBuilder.ConstantNull());
                }
                else
                {
                    ifZeroDivisor.DeclareVar <decimal>(
                        "result",
                        CodegenExpressionBuilder.Op(
                            CodegenExpressionBuilder.Ref("s1"),
                            "/",
                            CodegenExpressionBuilder.Constant(0.0m)))
                    .BlockReturn(CodegenExpressionBuilder.Ref("result"));
                }

                var method = block.MethodReturn(
                    DoDivideCodegen(
                        CodegenExpressionBuilder.Ref("s1"),
                        CodegenExpressionBuilder.Ref("s2"),
                        codegenClassScope));

                return(CodegenExpressionBuilder
                       .LocalMethodBuild(method)
                       .Pass(left)
                       .Pass(right)
                       .Call());
            }
            public CodegenExpression Codegen(
                CodegenMethodScope codegenMethodScope,
                CodegenClassScope codegenClassScope,
                CodegenExpressionRef left,
                CodegenExpressionRef right,
                Type ltype,
                Type rtype)
            {
                var leftValue  = _convOne.CoerceCodegen(left, ltype);
                var rightValue = _convTwo.CoerceCodegen(right, rtype);

                return(CodegenExpressionBuilder.Op(leftValue, "+", rightValue));
            }
            public CodegenExpression Codegen(
                CodegenMethodScope codegenMethodScope,
                CodegenClassScope codegenClassScope,
                CodegenExpressionRef left,
                CodegenExpressionRef right,
                Type ltype,
                Type rtype)
            {
                var method = codegenMethodScope
                             .MakeChild(typeof(decimal?), typeof(SubtractDecimalConvComputer), codegenClassScope)
                             .AddParam(ltype, "d1")
                             .AddParam(rtype, "d2")
                             .Block
                             .DeclareVar <decimal?>("s1", convOne.CoerceCodegen(Ref("d1"), ltype))
                             .DeclareVar <decimal?>("s2", convTwo.CoerceCodegen(Ref("d2"), rtype))
                             .MethodReturn(
                    Op(
                        ExprDotName(Ref("s1"), "Value"),
                        "-",
                        ExprDotName(Ref("s2"), "Value")));

                return(LocalMethodBuild(method).Pass(left).Pass(right).Call());
            }