public ActionEvaluator(StringTemplate self, ASTExpr chunk, IStringTemplateWriter writer, ITree input) : base(new CommonTreeNodeStream(new StringTemplateTreeAdaptor(), input)) { this.self = self; this.chunk = chunk; this.writer = writer; }
/// <summary> /// Just print out the string; no reference to self because this /// is a literal--not sensitive to attribute values. /// /// These strings never wrap because they are not part of a /// <![CDATA[<...> expression. <"foo"; wrap="\n"> ]]> should wrap though /// if necessary. /// </summary> public override int Write(StringTemplate self, IStringTemplateWriter output) { if (str != null) { int n = output.Write(str); return n; } return 0; }
protected virtual int WriteSubTemplate(StringTemplate self, IStringTemplateWriter @out, StringTemplate subtemplate) { /* To evaluate the IF chunk, make a new instance whose enclosingInstance * points at 'self' so get attribute works. Otherwise, enclosingInstance * points at the template used to make the precompiled code. We need a * new template instance every time we exec this chunk to get the new * "enclosing instance" pointer. */ StringTemplate s = subtemplate.GetInstanceOf(); s.EnclosingInstance = self; // make sure we evaluate in context of enclosing template's // group so polymorphism works. :) s.Group = self.Group; s.NativeGroup = self.NativeGroup; return(s.Write(@out)); }
/** <summary> * Just print out the string; no reference to self because this * is a literal--not sensitive to attribute values. These strings * never wrap because they are not part of an <...> expression. * <"foo"; wrap="\n"> should wrap though if necessary. * </summary> */ public override int Write(StringTemplate self, IStringTemplateWriter writer) { return(writer.Write(str ?? string.Empty)); }
/** <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()); ActionEvaluator eval = null; #if COMPILE_EXPRESSIONS bool compile = self.Group != null && self.Group.EnableCompiledExpressions; bool cache = compile && self.Group.EnableCachedExpressions; System.Func<StringTemplate, IStringTemplateWriter, int> evaluator = EvaluateAction; if (compile) { if (!cache || EvaluateAction == null) { // caching won't help here because AST is read only EvaluatorCacheMisses++; evaluator = GetEvaluator(this, AST); if (cache) EvaluateAction = evaluator; } else { EvaluatorCacheHits++; } } else #endif { eval = new ActionEvaluator(self, this, @out, _exprTree); } int n = 0; try { // eval and write out tree #if COMPILE_EXPRESSIONS if (compile) { n = evaluator(self, @out); } else #endif { n = eval.action(); } } catch ( RecognitionException re ) { self.Error( "can't evaluate tree: " + _exprTree.ToStringTree(), re ); } @out.PopIndentation(); if ( anchorAST != null ) { @out.PopAnchorPoint(); } return n; }
public virtual void EmitTemplateStopDebugString( StringTemplate st, IStringTemplateWriter @out ) { if ( _noDebugStartStopStrings == null || !_noDebugStartStopStrings.Contains( st.Name ) ) { string groupPrefix = ""; if ( !st.Name.StartsWith( "if" ) && !st.Name.StartsWith( "else" ) ) { if ( st.NativeGroup != null ) { groupPrefix = st.NativeGroup.Name + "."; } else { groupPrefix = st.Group.Name + "."; } } @out.Write( "</" + groupPrefix + st.Name + ">" ); } }
protected virtual int WriteSubTemplate( StringTemplate self, IStringTemplateWriter @out, StringTemplate subtemplate) { /* To evaluate the IF chunk, make a new instance whose enclosingInstance * points at 'self' so get attribute works. Otherwise, enclosingInstance * points at the template used to make the precompiled code. We need a * new template instance every time we exec this chunk to get the new * "enclosing instance" pointer. */ StringTemplate s = subtemplate.GetInstanceOf(); s.EnclosingInstance = self; // make sure we evaluate in context of enclosing template's // group so polymorphism works. :) s.Group = self.Group; s.NativeGroup = self.NativeGroup; return s.Write( @out ); }
/** Create an evaluator using attributes from self */ public ActionEvaluator(StringTemplate self, ASTExpr chunk, IStringTemplateWriter @out) { this.self = self; this.chunk = chunk; this.@out = @out; }
/** <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; }
protected virtual int WriteTemplate(StringTemplate self, StringTemplate stToWrite, IStringTemplateWriter @out) { int n = 0; /* failsafe: perhaps enclosing instance not set * Or, it could be set to another context! This occurs * when you store a template instance as an attribute of more * than one template (like both a header file and C file when * generating C code). It must execute within the context of * the enclosing template. */ stToWrite.EnclosingInstance = self; // if self is found up the enclosing instance chain, then infinite recursion if (StringTemplate.LintMode && StringTemplate.IsRecursiveEnclosingInstance(stToWrite)) { // throw exception since sometimes eval keeps going even after I ignore this write of o. throw new InvalidOperationException("infinite recursion to " + stToWrite.GetTemplateDeclaratorString() + " referenced in " + stToWrite.EnclosingInstance.TemplateDeclaratorString + "; stack trace:" + Environment.NewLine + stToWrite.GetEnclosingInstanceStackTrace()); } else { // if we have a wrap string, then inform writer it might need to wrap if (_wrapString != null) { n = @out.WriteWrapSeparator(_wrapString); } // check if formatting needs to be applied to the stToWrite if (_formatString != null) { IAttributeRenderer renderer = self.GetAttributeRenderer(typeof(string)); if (renderer != null) { /* you pay a penalty for applying format option to a template * because the template must be written to a temp StringWriter so it can * be formatted before being written to the real output. */ StringWriter buf = new StringWriter(); IStringTemplateWriter sw = self.Group.GetStringTemplateWriter(buf); stToWrite.Write(sw); n = @out.Write(renderer.ToString(buf.ToString(), _formatString)); return n; } } n = stToWrite.Write(@out); } return n; }
protected virtual int WriteObject(StringTemplate self, object o, IStringTemplateWriter @out) { int n = 0; IAttributeRenderer renderer = self.GetAttributeRenderer(o.GetType()); string v = null; if (renderer != null) { if (_formatString != null) v = renderer.ToString(o, _formatString); else v = renderer.ToString(o); } else { v = o.ToString(); } if (_wrapString != null) n = @out.Write(v, _wrapString); else n = @out.Write(v); return n; }
protected virtual int WriteIterableValue(StringTemplate self, Iterator iter, IStringTemplateWriter @out) { int n = 0; bool seenAValue = false; while (iter.hasNext()) { object iterValue = iter.next() ?? _nullValue; if (iterValue != null) { // if no separator or separator but iterValue isn't a single IF condition template if (_separatorString == null) { // if no separator, don't waste time writing to temp buffer int nw = Write(self, iterValue, @out); if (nw != Missing) n += nw; continue; } /* if value to emit is a template, only buffer its * value if it's nullable (can eval to missing). * Only a sequence of IF can eval to missing. */ StringTemplate st = iterValue as StringTemplate; if (st != null) { int nchunks = st.Chunks != null ? st.Chunks.Count : 0; bool nullable = true; for (int i = 0; i < nchunks; i++) { Expr a = st.Chunks[i]; if (!(a is ConditionalExpr)) nullable = false; } // if not all IF, not nullable, spit out w/o buffering if (!nullable) { if (seenAValue && _separatorString != null) { n += @out.WriteSeparator(_separatorString); } int nw = Write(self, iterValue, @out); n += nw; seenAValue = true; continue; } } else if (!(iterValue is Iterator)) { // if not possible to be missing, don't waste time // writing to temp buffer; might need separator though if (seenAValue && _separatorString != null) { n += @out.WriteSeparator(_separatorString); } int nw = Write(self, iterValue, @out); seenAValue = true; n += nw; continue; } /* if separator exists, write iterated value to a * tmp buffer in case we don't need a separator. * Can't generate separator then test next expr value * as we can't undo separator emit. * Write to dummy buffer to if it is MISSING * but eval/write value again to real out so * we get proper autowrap etc... * Ack: you pay a penalty now for a separator * Later, i can optimze to check if one chunk and * it's a conditional */ StringWriter buf = new StringWriter(); IStringTemplateWriter sw = self.Group.GetStringTemplateWriter(buf); int tmpsize = Write(self, iterValue, sw); if (tmpsize != Missing) { if (seenAValue && _separatorString != null) { n += @out.WriteSeparator(_separatorString); } // do it to real output stream now int nw = Write(self, iterValue, @out); n += nw; seenAValue = true; } } } return n; }
/** <summary>Write o relative to self to out.</summary> * * <remarks> * John Snyders fixes here for formatString. Basically, any time * you are about to write a value, check formatting. * </remarks> */ protected virtual int Write( StringTemplate self, object o, IStringTemplateWriter @out ) { if ( o == null ) { if ( _nullValue == null ) { return Missing; } o = _nullValue; // continue with null option if specified } try { StringTemplate stToWrite = o as StringTemplate; if (stToWrite != null) return WriteTemplate(self, stToWrite, @out); // normalize o = ConvertAnythingIteratableToIterator(o); Iterator iter = o as Iterator; if (iter != null) return WriteIterableValue(self, iter, @out); return WriteObject(self, o, @out); } catch ( IOException io ) { self.Error( "problem writing object: " + o, io ); return 0; } }
/** <summary>How to write this node to output; return how many char written</summary> */ abstract public int Write(StringTemplate self, IStringTemplateWriter writer);
/** <summary> * Just print out the string; no reference to self because this * is a literal--not sensitive to attribute values. These strings * never wrap because they are not part of an <...> expression. * <"foo"; wrap="\n"> should wrap though if necessary. * </summary> */ public override int Write( StringTemplate self, IStringTemplateWriter writer ) { return writer.Write( str ?? string.Empty ); }
/// <exception cref="IOException" /> public virtual void EmitTemplateStopDebugString(StringTemplate st, IStringTemplateWriter writer) { if ((noDebugStartStopStrings == null) || !noDebugStartStopStrings.Contains(st.Name)) { writer.Write("</" + st.Name + ">"); } }
/// <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. /// /// 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. /// </summary> public override int Write(StringTemplate self, IStringTemplateWriter output) { if (exprTree == null || self == null || output == null) { return 0; } output.PushIndentation(Indentation); // handle options, anchor, wrap, separator... StringTemplateAST anchorAST = (StringTemplateAST)GetOption("anchor"); if (anchorAST != null) // any non-empty expr means true; check presence { output.PushAnchorPoint(); } HandleExprOptions(self); ActionEvaluator eval = new ActionEvaluator(self, this, output); ActionParser.initializeASTFactory(eval.getASTFactory()); int n = 0; try { n = eval.action(exprTree); // eval and write out tree } catch (RecognitionException re) { self.Error("can't evaluate tree: " + exprTree.ToStringList(), re); } output.PopIndentation(); if (anchorAST != null) { output.PopAnchorPoint(); } return n; }
/** <summary> * To write out the value of a condition expr, invoke the evaluator in eval.g * to walk the condition tree computing the boolean value. If result * is true, then write subtemplate. * </summary> */ public override int Write( StringTemplate self, IStringTemplateWriter @out ) { if ( AST == null || self == null || @out == null ) { return 0; } //System.Console.Out.WriteLine( "evaluating conditional tree: " + AST.ToStringTree() ); #if !COMPILE_EXPRESSIONS ActionEvaluator eval = null; #endif int n = 0; try { bool testedTrue = false; // get conditional from tree and compute result #if COMPILE_EXPRESSIONS if ( EvaluateCondition == null ) EvaluateCondition = GetEvaluator( this, AST.GetChild( 0 ) ); bool includeSubtemplate = EvaluateCondition( self, @out ); // eval and write out tree #else ITree cond = AST.GetChild( 0 ); eval = new ActionEvaluator( self, this, @out, cond ); // eval and write out trees bool includeSubtemplate = eval.ifCondition(); #endif //System.Console.Out.WriteLine( "subtemplate " + _subtemplate ); // IF if ( includeSubtemplate ) { n = WriteSubTemplate( self, @out, _subtemplate ); testedTrue = true; } // ELSEIF else if ( _elseIfSubtemplates != null && _elseIfSubtemplates.Count > 0 ) { for ( int i = 0; i < _elseIfSubtemplates.Count; i++ ) { ElseIfClauseData elseIfClause = _elseIfSubtemplates[i]; #if COMPILE_EXPRESSIONS if ( elseIfClause.EvaluateCondition == null ) elseIfClause.EvaluateCondition = GetEvaluator( this, elseIfClause.expr.AST ); includeSubtemplate = elseIfClause.EvaluateCondition( self, @out ); #else eval = new ActionEvaluator( self, this, @out, elseIfClause.expr.AST ); includeSubtemplate = eval.ifCondition(); #endif if ( includeSubtemplate ) { WriteSubTemplate( self, @out, elseIfClause.st ); testedTrue = true; break; } } } // ELSE if ( !testedTrue && _elseSubtemplate != null ) { // evaluate ELSE clause if present and IF condition failed StringTemplate s = _elseSubtemplate.GetInstanceOf(); s.EnclosingInstance = self; s.Group = self.Group; s.NativeGroup = self.NativeGroup; n = s.Write( @out ); } // cond==false and no else => Missing output not empty if (!testedTrue && _elseSubtemplate == null) n = Missing; } catch ( RecognitionException re ) { self.Error( "can't evaluate tree: " + AST.ToStringTree(), re ); } return n; }
/// <summary>How to spit out an object. If it's not a StringTemplate nor a /// List, just do o.toString(). If it's a StringTemplate, /// do o.write(out). If it's a Vector, do a write(out, /// o.elementAt(i)) for all elements. Note that if you do /// something weird like set the values of a multivalued tag /// to be vectors, it will effectively flatten it. /// /// If self is an embedded template, you might have specified /// a separator arg; used when is a vector. /// </summary> public virtual int WriteAttribute(StringTemplate self, object o, IStringTemplateWriter output) { return Write(self, o, output); }
public static bool CallFunctionalConditionEvaluator( HoldsConditionFuncAndChunk data, StringTemplate self, IStringTemplateWriter writer ) { return data.func( data.chunk, self, writer ); }
/// <summary> /// Write o relative to self to out /// </summary> /// <remarks> /// John Snyders fixes here for formatString. Basically, any time /// you are about to write a value, check formatting. /// </remarks> protected internal virtual int Write(StringTemplate self, object o, IStringTemplateWriter output) { if (o == null) { if (nullValue == null) { return 0; } // continue with null option if specified o = nullValue; } int n = 0; try { if (o is StringTemplate) { StringTemplate stToWrite = (StringTemplate) o; // failsafe: perhaps enclosing instance not set // Or, it could be set to another context! This occurs // when you store a template instance as an attribute of more // than one template (like both a header file and C file when // generating C code). It must execute within the context of // the enclosing template. stToWrite.EnclosingInstance = self; // if self is found up the enclosing instance chain, then // infinite recursion if (StringTemplate.IsInLintMode && StringTemplate.IsRecursiveEnclosingInstance(stToWrite)) { // throw exception since sometimes eval keeps going // even after I ignore this write of o. throw new SystemException("infinite recursion to " + stToWrite.GetTemplateDeclaratorString() + " referenced in " + stToWrite.EnclosingInstance.GetTemplateDeclaratorString() + "; stack trace:\n" + stToWrite.GetEnclosingInstanceStackTrace()); } else { // if we have a wrap string, then inform writer it // might need to wrap if (wrapString != null) { n = output.WriteWrapSeparator(wrapString); } // check if formatting needs to be applied to the stToWrite if ( formatString != null ) { IAttributeRenderer renderer = self.GetAttributeRenderer(typeof(string)); if ( renderer != null ) { // you pay a penalty for applying format option to a template // because the template must be written to a temp StringWriter so it can // be formatted before being written to the real output. StringWriter buf = new StringWriter(); IStringTemplateWriter sw = self.Group.CreateInstanceOfTemplateWriter(buf); stToWrite.Write(sw); n = output.Write(renderer.ToString(buf.ToString(), formatString)); return n; } } n = stToWrite.Write(output); } return n; } // normalize anything iteratable to iterator o = ConvertAnythingIteratableToIterator(o); if (o is IEnumerator) { IEnumerator iter = (IEnumerator)o; bool seenPrevValue = false; while (iter.MoveNext()) { object iterValue = iter.Current; if (iterValue == null) { iterValue = nullValue; } if (iterValue != null) { if (seenPrevValue /*prevIterValue!=null*/ && (separatorString != null)) { n += output.WriteSeparator(separatorString); } seenPrevValue = true; int nw = Write(self, iterValue, output); n += nw; } } } else { IAttributeRenderer renderer = self.GetAttributeRenderer(o.GetType()); string v = null; if (renderer != null) { if (formatString != null) { v = renderer.ToString(o, formatString); } else { v = renderer.ToString(o); } } else { v = o.ToString(); } if (wrapString != null) { n = output.Write(v, wrapString); } else { n = output.Write(v); } return n; } } catch (IOException io) { self.Error("problem writing object: " + o, io); } return n; }
/** <summary> * To write out the value of a condition expr, invoke the evaluator in eval.g * to walk the condition tree computing the boolean value. If result * is true, then write subtemplate. * </summary> */ public override int Write(StringTemplate self, IStringTemplateWriter @out) { if (AST == null || self == null || @out == null) { return(0); } //System.Console.Out.WriteLine( "evaluating conditional tree: " + AST.ToStringTree() ); #if !COMPILE_EXPRESSIONS ActionEvaluator eval = null; #endif int n = 0; try { bool testedTrue = false; // get conditional from tree and compute result #if COMPILE_EXPRESSIONS if (EvaluateCondition == null) { EvaluateCondition = GetEvaluator(this, AST.GetChild(0)); } bool includeSubtemplate = EvaluateCondition(self, @out); // eval and write out tree #else ITree cond = AST.GetChild(0); eval = new ActionEvaluator(self, this, @out, cond); // eval and write out trees bool includeSubtemplate = eval.ifCondition(); #endif //System.Console.Out.WriteLine( "subtemplate " + _subtemplate ); // IF if (includeSubtemplate) { n = WriteSubTemplate(self, @out, _subtemplate); testedTrue = true; } // ELSEIF else if (_elseIfSubtemplates != null && _elseIfSubtemplates.Count > 0) { for (int i = 0; i < _elseIfSubtemplates.Count; i++) { ElseIfClauseData elseIfClause = _elseIfSubtemplates[i]; #if COMPILE_EXPRESSIONS if (elseIfClause.EvaluateCondition == null) { elseIfClause.EvaluateCondition = GetEvaluator(this, elseIfClause.expr.AST); } includeSubtemplate = elseIfClause.EvaluateCondition(self, @out); #else eval = new ActionEvaluator(self, this, @out, elseIfClause.expr.AST); includeSubtemplate = eval.ifCondition(); #endif if (includeSubtemplate) { WriteSubTemplate(self, @out, elseIfClause.st); testedTrue = true; break; } } } // ELSE if (!testedTrue && _elseSubtemplate != null) { // evaluate ELSE clause if present and IF condition failed StringTemplate s = _elseSubtemplate.GetInstanceOf(); s.EnclosingInstance = self; s.Group = self.Group; s.NativeGroup = self.NativeGroup; n = s.Write(@out); } // cond==false and no else => Missing output not empty if (!testedTrue && _elseSubtemplate == null) { n = Missing; } } catch (RecognitionException re) { self.Error("can't evaluate tree: " + AST.ToStringTree(), re); } return(n); }
/** <summary>How to write this node to output; return how many char written</summary> */ public abstract int Write( StringTemplate self, IStringTemplateWriter writer );
public static bool CallFunctionalConditionEvaluator(HoldsConditionFuncAndChunk data, StringTemplate self, IStringTemplateWriter writer) { return(data.func(data.chunk, self, writer)); }
internal int Evaluate(StringTemplate template, IStringTemplateWriter writer) { return func(chunk, template, writer); }