示例#1
0
        static System.Func<StringTemplate, IStringTemplateWriter, int> GetEvaluator( ASTExpr chunk, ITree condition )
        {
            if ( EnableDynamicMethods )
            {
                try
                {
                    DynamicMethod method = null;
            #if CACHE_FUNCTORS
                    if ( !_methods.TryGetValue( condition, out method ) )
            #endif
                    {
                        Type[] parameterTypes = { typeof( ASTExpr ), typeof( StringTemplate ), typeof( IStringTemplateWriter ) };
                        method = new DynamicMethod( "ActionEvaluator" + _evaluatorNumber, typeof( int ), parameterTypes, typeof( ConditionalExpr ), true );
                        method.DefineParameter( 1, ParameterAttributes.None, "chunk" );
                        method.DefineParameter( 2, ParameterAttributes.None, "self" );
                        method.DefineParameter( 3, ParameterAttributes.None, "writer" );
                        _evaluatorNumber++;

                        var gen = method.GetILGenerator();
                        ActionEvaluator evalCompiled = new ActionEvaluator( null, chunk, null, condition );
                        evalCompiled.actionCompiled( gen );
                        gen.Emit( OpCodes.Ret );
            #if CACHE_FUNCTORS
                        _methods[condition] = method;
            #endif
                    }

                    var dynamicEvaluator = (System.Func<StringTemplate, IStringTemplateWriter, int>)method.CreateDelegate( typeof( System.Func<StringTemplate, IStringTemplateWriter, int> ), chunk );
                    return dynamicEvaluator;
                }
                catch
                {
                    // fall back to functional (or interpreted) version
                }
            }

            if ( EnableFunctionalMethods )
            {
                try
                {
                    ActionEvaluator evalFunctional = new ActionEvaluator( null, chunk, null, condition );
                    var functionalEvaluator = evalFunctional.actionFunctional();
                    HoldsActionFuncAndChunk holder = new HoldsActionFuncAndChunk()
                    {
                        func = functionalEvaluator,
                        chunk = chunk
                    };
                    return (System.Func<StringTemplate, IStringTemplateWriter, int>)System.Delegate.CreateDelegate( typeof( System.Func<StringTemplate, IStringTemplateWriter, int> ), holder, typeof( ASTExpr ).GetMethod( "CallFunctionalActionEvaluator" ) );
                }
                catch
                {
                    // fall back to interpreted version
                }
            }

            return ( self, writer ) =>
                {
                    ActionEvaluator eval = new ActionEvaluator( self, chunk, writer, condition );
                    return eval.action();
                };
        }