public static CodegenExpression CodegenLong(
     ReformatBetweenNonConstantParamsForge forge,
     CodegenExpression inner,
     CodegenMethodScope codegenMethodScope,
     ExprForgeCodegenSymbol exprSymbol,
     CodegenClassScope codegenClassScope)
 {
     return CodegenLongInternal(forge, inner, codegenMethodScope, exprSymbol, codegenClassScope);
 }
 public ReformatBetweenNonConstantParamsForgeOp(
     ReformatBetweenNonConstantParamsForge forge,
     ExprEvaluator startEval,
     ExprEvaluator endEval,
     ExprEvaluator evalIncludeLow,
     ExprEvaluator evalIncludeHigh)
 {
     this._forge = forge;
     this._startEval = startEval;
     this._endEval = endEval;
     this._evalIncludeLow = evalIncludeLow;
     this._evalIncludeHigh = evalIncludeHigh;
 }
        public static CodegenExpression CodegenDateTimeEx(
            ReformatBetweenNonConstantParamsForge forge,
            CodegenExpression inner,
            CodegenMethodScope codegenMethodScope,
            ExprForgeCodegenSymbol exprSymbol,
            CodegenClassScope codegenClassScope)
        {
            var methodNode = codegenMethodScope.MakeChild(
                    typeof(bool?),
                    typeof(ReformatBetweenNonConstantParamsForgeOp),
                    codegenClassScope)
                .AddParam(typeof(DateTimeEx), "dateTime");

            methodNode.Block
                .IfRefNullReturnNull("dateTime")
                .MethodReturn(
                    CodegenLongInternal(
                        forge,
                        ExprDotName(Ref("dateTime"), "UtcMillis"),
                        methodNode,
                        exprSymbol,
                        codegenClassScope));
            return LocalMethod(methodNode, inner);
        }
        private static CodegenExpression CodegenLongInternal(
            ReformatBetweenNonConstantParamsForge forge,
            CodegenExpression inner,
            CodegenMethodScope codegenMethodScope,
            ExprForgeCodegenSymbol exprSymbol,
            CodegenClassScope codegenClassScope)
        {
            var methodNode = codegenMethodScope.MakeChild(
                    typeof(bool?),
                    typeof(ReformatBetweenNonConstantParamsForgeOp),
                    codegenClassScope)
                .AddParam(typeof(long), "ts");

            var block = methodNode.Block;

            CodegenLongCoercion(
                block,
                "first",
                forge.Start,
                forge.StartCoercer,
                methodNode,
                exprSymbol,
                codegenClassScope);

            CodegenLongCoercion(
                block,
                "second",
                forge.End,
                forge.SecondCoercer,
                methodNode,
                exprSymbol,
                codegenClassScope);

            CodegenExpression first = Ref("first");
            CodegenExpression second = Ref("second");
            CodegenExpression ts = Ref("ts");

            if (forge.IncludeBoth) {
                block.IfCondition(Relational(first, LE, second))
                    .BlockReturn(And(Relational(first, LE, ts), Relational(ts, LE, second)))
                    .MethodReturn(And(Relational(second, LE, ts), Relational(ts, LE, first)));
            }
            else if (forge.IncludeLow != null && forge.IncludeHigh != null) {
                block.IfCondition(Relational(ts, forge.IncludeLow.Value ? LT : LE, first))
                    .BlockReturn(ConstantFalse())
                    .IfCondition(Relational(ts, forge.IncludeHigh.Value ? GT : GE, second))
                    .BlockReturn(ConstantFalse())
                    .MethodReturn(ConstantTrue());
            }
            else {
                CodegenBooleanEval(
                    block,
                    "includeLowEndpoint",
                    forge.IncludeLow,
                    forge.ForgeIncludeLow,
                    methodNode,
                    exprSymbol,
                    codegenClassScope);

                CodegenBooleanEval(
                    block,
                    "includeLowHighpoint",
                    forge.IncludeHigh,
                    forge.ForgeIncludeHigh,
                    methodNode,
                    exprSymbol,
                    codegenClassScope);

                block.MethodReturn(
                    StaticMethod(
                        typeof(ReformatBetweenNonConstantParamsForgeOp),
                        "CompareTimestamps",
                        first,
                        ts,
                        second,
                        Ref("includeLowEndpoint"),
                        Ref("includeLowHighpoint")));
            }

            return LocalMethod(methodNode, inner);
        }