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(); }; }