protected internal virtual void evaluateArguments(StringTemplate self) { StringTemplateAST argumentsAST = self.getArgumentsAST(); if (argumentsAST == null || argumentsAST.getFirstChild() == null) { // return immediately if missing tree or no actual args return ; } ActionEvaluator eval = new ActionEvaluator(self, this, null); try { // using any initial argument context (such as when obj is set), // evaluate the arg list like bold(item=obj). Since we pass // in any existing arg context, that context gets filled with // new values. With bold(item=obj), context becomes: // {[obj=...],[item=...]}. IDictionary ac = eval.argList(argumentsAST, self.getArgumentContext()); self.setArgumentContext(ac); } catch (RecognitionException re) { self.error("can't evaluate tree: " + argumentsAST.ToStringList(), re); } }
/// <summary> /// Evaluate an argument list within the context of the enclosing /// template but store the values in the context of self, the /// new embedded template. For example, bold(item=item) means /// that bold.item should get the value of enclosing.item. /// </summary> protected internal virtual void evaluateArguments(StringTemplate self) { StringTemplateAST argumentsAST = self.getArgumentsAST(); if (argumentsAST == null || argumentsAST.getFirstChild() == null) { // return immediately if missing tree or no actual args return ; } // Evaluate args in the context of the enclosing template, but we // need the predefined args like 'it', 'attr', and 'i' to be // available as well so we put a dummy ST between the enclosing // context and the embedded context. The dummy has the predefined // context as does the embedded. StringTemplate enclosing = self.getEnclosingInstance(); StringTemplate argContextST = new StringTemplate(self.getGroup(), ""); argContextST.setName("<invoke "+self.getName()+" arg context>"); argContextST.setEnclosingInstance(enclosing); argContextST.setArgumentContext(self.getArgumentContext()); ActionEvaluator eval = new ActionEvaluator(argContextST, this, null); try { // using any initial argument context (such as when obj is set), // evaluate the arg list like bold(item=obj). Since we pass // in any existing arg context, that context gets filled with // new values. With bold(item=obj), context becomes: // {[obj=...],[item=...]}. IDictionary ac = eval.argList(argumentsAST, self, self.getArgumentContext()); self.setArgumentContext(ac); } catch (RecognitionException re) { self.error("can't evaluate tree: " + argumentsAST.ToStringList(), re); } }
/// <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> public override int write(StringTemplate self, StringTemplateWriter outWriter) { if (exprTree == null || self == null || outWriter == null) { return 0; } outWriter.pushIndentation(getIndentation()); //System.out.println("evaluating tree: "+exprTree.toStringList()); ActionEvaluator eval = new ActionEvaluator(self, this, outWriter); 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); } outWriter.popIndentation(); 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, StringTemplateWriter outWriter) { if (exprTree == null || self == null || outWriter == null) { return 0; } // System.out.println("evaluating conditional tree: "+exprTree.toStringList()); ActionEvaluator eval = new ActionEvaluator(self, this, outWriter); int n = 0; try { // get conditional from tree and compute result AST cond = exprTree.getFirstChild(); bool includeSubtemplate = eval.ifCondition(cond); // eval and write out tree // System.out.println("subtemplate "+subtemplate); if (includeSubtemplate) { /* 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.setEnclosingInstance(self); n = s.write(outWriter); } else if (elseSubtemplate != null) { // evaluate ELSE clause if present and IF condition failed StringTemplate s = elseSubtemplate.getInstanceOf(); s.setEnclosingInstance(self); n = s.write(outWriter); } } catch (RecognitionException re) { self.error("can't evaluate tree: " + exprTree.ToStringList(), re); } return n; }