示例#1
0
        /** <summary>
         *  A expr is normally just a string literal, but is still an AST that
         *  we must evaluate.  The expr can be any expression such as a template
         *  include or string cat expression etc...  Evaluate with its own writer
         *  so that we can convert to string and then reuse, don't want to compute
         *  all the time; must precompute w/o writing to output buffer.
         *  </summary>
         */
        public virtual string EvaluateExpression( StringTemplate self,
                                            object expr )
        {
            if ( expr == null )
            {
                return null;
            }

            StringTemplateAST exprAST = expr as StringTemplateAST;
            if ( exprAST != null )
            {
            #if COMPILE_EXPRESSIONS
                System.Func<StringTemplate, IStringTemplateWriter, int> value;
            #if CACHE_FUNCTORS
                if ( !_evaluators.TryGetValue( expr, out value ) )
            #endif
                {
                    value = GetEvaluator( this, exprAST );
            #if CACHE_FUNCTORS
                    _evaluators[expr] = value;
            #endif
                }
            #endif
                // must evaluate, writing to a string so we can hang on to it
                StringWriter buf = new StringWriter();
                IStringTemplateWriter sw =
                    self.Group.GetStringTemplateWriter( buf );
                {
                    try
                    {
            #if COMPILE_EXPRESSIONS
                        value( self, sw );
            #else
                        ActionEvaluator eval = new ActionEvaluator( self, this, sw, exprAST );
                        // eval tree
                        eval.action();
            #endif
                    }
                    catch ( RecognitionException re )
                    {
                        self.Error( "can't evaluate tree: " + _exprTree.ToStringTree(), re );
                    }
                }
                return buf.ToString();
            }
            else
            {
                // just in case we expand in the future and it's something else
                return expr.ToString();
            }
        }
示例#2
0
 /** <summary>
  *  To write out the value of an ASTExpr, invoke the evaluator in eval.g
  *  to walk the tree writing out the values.  For efficiency, don't
  *  compute a bunch of strings and then pack them together.  Write out directly.
  *  </summary>
  *
  *  <remarks>
  *  Compute separator and wrap expressions, save as strings so we don't
  *  recompute for each value in a multi-valued attribute or expression.
  *
  *  If they set anchor option, then inform the writer to push current
  *  char position.
  *  </remarks>
  */
 public override int Write( StringTemplate self, IStringTemplateWriter @out )
 {
     if ( _exprTree == null || self == null || @out == null )
     {
         return 0;
     }
     // handle options, anchor, wrap, separator...
     StringTemplateAST anchorAST = (StringTemplateAST)GetOption( "anchor" );
     if ( anchorAST != null )
     { // any non-empty expr means true; check presence
         @out.PushAnchorPoint();
     }
     @out.PushIndentation( Indentation );
     HandleExprOptions( self );
     //System.out.println("evaluating tree: "+exprTree.toStringList());
     #if COMPILE_EXPRESSIONS
     if ( EvaluateAction == null )
         EvaluateAction = GetEvaluator( this, AST );
     #else
     ActionEvaluator eval =
             new ActionEvaluator( self, this, @out, _exprTree );
     #endif
     int n = 0;
     try
     {
         // eval and write out tree
     #if COMPILE_EXPRESSIONS
         n = EvaluateAction( self, @out );
     #else
         n = eval.action();
     #endif
     }
     catch ( RecognitionException re )
     {
         self.Error( "can't evaluate tree: " + _exprTree.ToStringTree(), re );
     }
     @out.PopIndentation();
     if ( anchorAST != null )
     {
         @out.PopAnchorPoint();
     }
     return n;
 }
示例#3
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();
                };
        }