Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 1997-2013, www.tinygroup.org (tinygroup@126.com). Licensed under the GPL, Version 3.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.gnu.org/licenses/gpl.html Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
  
  package org.tinygroup.template.parser;
  
  
  import java.util.List;
  import java.util.Stack;
  
  // Visitor 模式访问器,用来生成 Java 代码
      private static final String[] RESERVED_WORDS = {"set""if""elseif""for""foreach""break""continue""stop""include""call""layout""macro""b""eol""t""bodyContent""import"};
      private TinyTemplateParser parser = null;
      private Stack<CodeBlockcodeBlocks = new Stack<CodeBlock>();
      private Stack<CodeLetcodeLets = new Stack<CodeLet>();
      private CodeBlock initCodeBlock = null;
      private CodeBlock macroCodeBlock = null;
      private int callMacroIndex = 1;
      private CodeBlock templateClass;
    
是否是严格格式,如果是严格格式会进行trim()
  
      public static boolean strictFormat = false;
  
      public TinyTemplateCodeVisitor(TinyTemplateParser parser) {
          this. = parser;
      }
  
  
          List<TinyTemplateParser.ExpressionContextexpressionList = ctx.expression();
          int i = 0;
          for (TinyTemplateParser.ExpressionContext expression : expressionList) {
              CodeLet exp = pushPeekCodeLet();
              expression.accept(this);
              popCodeLet();
              if (i > 0) {
                  peekCodeLet().code(",");
              }
              peekCodeLet().code(exp);
              i++;
          }
          return null;
      }
  
          throw reportError("Missing arguments for " + ctx.getText() + " directive."ctx.getStart().getLine(), ctx.getStart().getCharPositionInLine(), ctx);
      }
  
  
          CodeBlock callMacro = processVisitCallHead(ctx.expression(), ctx.para_expression_list());
          callMacro.subCode("$macro.render($template,$context,$newContext,$writer);");
          return callMacro;
      }
  
          CodeBlock callMacro = new CodeBlock();
          CodeLet nameCodeBlock = pushPeekCodeLet();
          macroName.accept(this);
          popCodeLet();
  
          String name = nameCodeBlock.toString();
          callMacro.subCode(String.format("$macro=getTemplateEngine().findMacro(%s,$template,$context);"name));
          callMacro.subCode("$newContext=new TemplateContextDefault();");
          callMacro.subCode("$paraList=new ArrayList();");
          callMacro.subCode("$newContext.put(" + name + "+\"ParameterList\",$paraList);");
          callMacro.subCode("$newContext.setParent($context);");
          if (paraExpressionListContext != null) {
              List<TinyTemplateParser.Para_expressionContextexpList = paraExpressionListContext.para_expression();
              if (expList != null) {
                  pushCodeBlock(callMacro);
                  int i = 0;
                  for (TinyTemplateParser.Para_expressionContext visitParaExpression : expList) {
                      processVisitPara(ivisitParaExpressionname);
                      i++;
                  }
                 popCodeBlock();
             }
         }
         return callMacro;
     }
 
         CodeBlock elseBlock = new CodeBlock().subCode(new CodeLet().lineCode("}else{")).tabIndent(-1);
         peekCodeBlock().subCode(elseBlock);
         ctx.block().accept(this);
         return null;
     }
 
 
         TinyTemplateParser.Hash_map_entry_listContext hashMapEntryListContext = ctx.hash_map_entry_list();
         if (hashMapEntryListContext != null) {
             peekCodeLet().code("new TemplateMap()").code(hashMapEntryListContext.accept(this).toString()).code("");
         }
         return null;
     }
 
         TinyTemplateParser.ExpressionContext expression = ctx.expression();
         processorConditionDirective(expression"continue;");
         return null;
     }
 
 
         CodeLet exp = pushPeekCodeLet();
         ctx.expression().accept(this);
         popCodeLet();
         peekCodeLet().code(ctx.getChild(1).getText().equals("?.") ? "U.sp(" : "U.p(").code(exp).code(",\"").code(ctx.IDENTIFIER().getText()).code("\")");
         return null;
     }
 
         CodeLet left = pushPeekCodeLet();
         ctx.expression(0).accept(this);
         popCodeLet();
         left.codeBefore("U.b(").code(")");
         CodeLet right = pushPeekCodeLet();
         ctx.expression(1).accept(this);
         popCodeLet();
         right.codeBefore("U.b(").code(")");
         String op = ctx.getChild(1).getText();
         peekCodeLet().code(left).code(op).code(right);
         return null;
     }
 
 
         String functionName = ctx.getChild(0).getText();
 
         peekCodeLet().codeBefore("getTemplateEngine().executeFunction($template,$context,\"").code(functionName).code("\"");
         if (list != null) {
             peekCodeLet().code(",");
             list.accept(this);
         }
         peekCodeLet().code(")");
         return null;
     }
 
 
         CodeBlock block = new CodeBlock();
         block.subCode("U.indent($context);");
         return block;
     }
 
 
         String name = ctx.getChild(0).getText();
         name = name.substring(6, name.length() - 1).trim();
         //这里进行保留字检查
         boolean isReserve = false;
         for (String word : ) {
             if (name.equals(word)) {
                 TerminalNodeImpl terminalNode = (TerminalNodeImplctx.getChild(0);
                 throw new SyntaxErrorException("Macro name<" + name + "> is reserved word."terminalNode.getSymbol().getLine(), terminalNode.getSymbol().getStartIndex());
             }
         }
 
         name = ResourceCompilerUtils.getClassNameGetter().getClassName(name).getSimpleClassName();
         .subCode(new CodeLet().lineCode("addMacro(new %s());"name));
         CodeBlock macro = new CodeBlock();
         TinyTemplateParser.Define_expression_listContext defineExpressionListContext = ctx.define_expression_list();
         pushPeekCodeLet();
         if (defineExpressionListContext != null) {
             defineExpressionListContext.accept(this);
         }
         macro.header(new CodeLet().lineCode("class %s extends AbstractMacro {"name));
         macro.footer(new CodeLet().lineCode("}"));
         macro.subCode(constructMethod(name));
         popCodeLet();
         CodeBlock render = getMacroRenderCodeBlock(false);
         pushCodeBlock(render);
         macro.subCode(render);
         ctx.block().accept(this);
         popCodeBlock();
         .subCode(macro);
         return null;
     }
 
     private CodeBlock constructMethod(String name) {
         CodeBlock block = new CodeBlock();
         block.header(CodeLet.lineCodeLet("public %s() {"name));
         block.subCode(String.format("super(\"%s\");"name));
         block.subCode(peekCodeLet());
         block.subCode(String.format("init(\"%s\");"name));
         block.footer(CodeLet.lineCodeLet("}"));
         return block;
     }
 
         peekCodeLet().code("O.e(\"").code(ctx.getChild(1).getText()).code("\",");
         ctx.expression(0).accept(this);
         peekCodeLet().code(",");
         ctx.expression(1).accept(this);
         peekCodeLet().code(")");
         return null;
     }
 
         CodeBlock valueCodeBlock = new CodeBlock();
         pushCodeLet();
         if (ctx.getChild(0).getText().equals("$${")) {
             peekCodeLet().code("write($writer,U.getI18n($template.getTemplateEngine().getI18nVistor(),$context,\"").code(ctx.identify_list().getText()).lineCode("\"));");
         } else {
             ctx.expression().accept(this);
             Token token = ((TerminalNodectx.getChild(0)).getSymbol();
             if (token.getType() == .) {
                 peekCodeLet().codeBefore("U.escapeHtml((").code("))");
             }
             peekCodeLet().codeBefore("write($writer,").lineCode(");");
         }
         valueCodeBlock.subCode(peekCodeLet());
         popCodeLet();
         return valueCodeBlock;
     }
 
         peekCodeLet().code("O.e(\"").code(ctx.getChild(1).getText()).code("\",");
         ctx.expression(0).accept(this);
         peekCodeLet().code(",");
         ctx.expression(1).accept(this);
         peekCodeLet().code(")");
         return null;
     }
 
 
         List<TinyTemplateParser.ExpressionContextexpressionContexts = ctx.expression();
         CodeLet keyPair = new CodeLet();
         CodeBlock result = new CodeBlock().subCode(keyPair);
         for (int i = 0; i < expressionContexts.size(); i += 2) {
             CodeBlock codeBlock = new CodeBlock();
             CodeLet keyCodeLet = pushPeekCodeLet();
             expressionContexts.get(i).accept(this);
             popCodeLet();
             CodeLet valueCodeLet = pushPeekCodeLet();
             expressionContexts.get(i + 1).accept(this);
             popCodeLet();
             codeBlock.subCode(new CodeLet().code(keyCodeLet).code(":").code(valueCodeLet));
             keyPair.code(".putItem(").code(keyCodeLet).code(",").code(valueCodeLet).code(")");
         }
         return result;
     }
 
         return ctx.getChild(0).accept(this);
     }
 
 
         CodeBlock block = new CodeBlock();
         block.subCode("U.dent($context);");
         return block;
     }
 
         CodeBlock templateCodeBlock = getTemplateCodeBlock();
         CodeBlock classCodeBlock = getClassCodeBlock();
         templateCodeBlock.subCode(classCodeBlock);
         CodeBlock renderMethodCodeBlock = getTemplateRenderCodeBlock();
         classCodeBlock.subCode(renderMethodCodeBlock);
         CodeBlock getTemplatePathMethod = getTemplatePathMethodCodeBlock();
         classCodeBlock.subCode(getTemplatePathMethod);
         pushCodeBlock(renderMethodCodeBlock);
         renderMethodCodeBlock.subCode(ctx.block().accept(this));
         popCodeBlock();
         return templateCodeBlock;
     }
 
     private CodeBlock getTemplateRenderCodeBlock() {
         CodeBlock renderMethod = new CodeBlock();
         renderMethod.header(new CodeLet().lineCode("protected void renderContent(TemplateContext $context, Writer $writer) throws IOException, TemplateException{")).footer(new CodeLet().lineCode("}"));
         renderMethod.subCode("Macro $macro=null;");
         renderMethod.subCode("Macro $bodyMacro=null;");
         renderMethod.subCode("Template $template=this;");
         renderMethod.subCode("TemplateContext $pageContext=$context;");
         renderMethod.subCode("TemplateContext $newContext=null;");
         renderMethod.subCode("List $paraList=null;");
 
         return renderMethod;
     }
 
     private CodeBlock getMacroRenderCodeBlock(boolean hasChild) {
         CodeBlock renderMethod = new CodeBlock();
         renderMethod.header(new CodeLet().lineCode("protected void renderMacro(Template $template,TemplateContext $pageContext, TemplateContext $context, Writer $writer) throws IOException, TemplateException{")).footer(new CodeLet().lineCode("}"));
         if (hasChild) {
             renderMethod.subCode("$context.getParent().getItemMap().put(\"isCalled\", true);");
         }
         renderMethod.subCode("Macro $macro=null;");
         renderMethod.subCode("Macro $bodyMacro=null;");
         renderMethod.subCode("TemplateContext $newContext=null;");
         renderMethod.subCode("List $paraList=null;");
 
         return renderMethod;
     }
 
         CodeBlock renderMethod = new CodeBlock();
         renderMethod.header(new CodeLet().lineCode("public String getPath(){")).footer(new CodeLet().lineCode("}"));
         renderMethod.subCode(new CodeLet().lineCode("return \"$TEMPLATE_PATH\";"));
         return renderMethod;
     }
 
     private CodeBlock getClassCodeBlock() {
          = 1;
          = new CodeBlock();
          = new CodeBlock().header(new CodeLet("{").endLine()).footer(new CodeLet("}").endLine());
         .header(new CodeLet().lineCode("public class $TEMPLATE_CLASS_NAME extends AbstractTemplate{"));
          = new CodeBlock();
         .footer(new CodeLet().lineCode("}"));
         return ;
     }
 
     private CodeBlock getTemplateCodeBlock() {
         CodeBlock codeBlock = new CodeBlock();
         codeBlock.subCode(new CodeLet().lineCode("import java.io.IOException;"));
         codeBlock.subCode(new CodeLet().lineCode("import java.util.*;"));
         codeBlock.subCode(new CodeLet().lineCode("import org.tinygroup.template.rumtime.*;"));
         codeBlock.subCode(new CodeLet().lineCode("import org.tinygroup.template.*;"));
         codeBlock.subCode(new CodeLet().lineCode("import java.io.Writer;"));
         codeBlock.subCode(new CodeLet().lineCode("import org.tinygroup.template.impl.*;"));
         return codeBlock;
     }
 
 
 
         return null;
     }
 
         Token token = ((TerminalNodectx.getChild(0)).getSymbol();
         String text = token.getText();
         switch (token.getType()) {
             case .:
                 if (text = text.trim();
                 break;
             case .:
                 text = text.substring(3, text.length() - 3);
                 break;
             case .:
                 text = text.substring(1);
                 break;
             default:
                 break;
         }
         if (text.length() == 0) {
             return null;
         }
         return new CodeBlock().header(new CodeLet().code("write($writer,\"").code(escapeJavaStyleString(text).toString()).lineCode("\");"));
     }
 
     private static StringBuffer escapeJavaStyleString(String str) {
         StringBuffer stringBuffer = new StringBuffer();
         int sz;
         sz = str.length();
         for (int i = 0; i < szi++) {
             char ch = str.charAt(i);
 
             switch (ch) {
                 case '\b':
                     escapeChar(stringBuffer'b');
                     break;
                 case '\n':
                     escapeChar(stringBuffer'n');
                     break;
                 case '\t':
                     escapeChar(stringBuffer't');
                     break;
                 case '\f':
                     escapeChar(stringBuffer'f');
                     break;
                 case '\r':
                     escapeChar(stringBuffer'r');
                     break;
                 case '"':
                     escapeChar(stringBuffer'"');
                     break;
                 case '\\':
                     escapeChar(stringBuffer'\\');
                     break;
                 default:
                     stringBuffer.append(ch);
                     break;
             }
         }
         return stringBuffer;
     }
 
     private static void escapeChar(StringBuffer stringBufferchar ch) {
         stringBuffer.append('\\');
         stringBuffer.append(ch);
     }
 
         String name = ctx.IDENTIFIER().getText();
         peekCodeLet().code("U.v($context,\"" + name + "\")");
         return null;
     }
 
 
         CodeBlock ifCodeBlock = pushPeekCodeBlock();
         pushCodeLet();
         ctx.expression().accept(this);
         ifCodeBlock.header(peekCodeLet().codeBefore("if(U.b(").lineCode(")){"));
         popCodeLet();
         ifCodeBlock.footer(new CodeLet().lineCode("}"));
         ctx.block().accept(this);
         List<TinyTemplateParser.Elseif_directiveContextelseifDirectiveContexts = ctx.elseif_directive();
         for (TinyTemplateParser.Elseif_directiveContext elseifDirectiveContext : elseifDirectiveContexts) {
             elseifDirectiveContext.accept(this);
         }
         TinyTemplateParser.Else_directiveContext elseDirectiveContext = ctx.else_directive();
         if (elseDirectiveContext != null) {
             elseDirectiveContext.accept(this);
         }
         popCodeBlock();
         return ifCodeBlock;
     }
 
         String name = "$" + ctx.IDENTIFIER().getText();
         CodeBlock positionCodeBlock = new CodeBlock();
         positionCodeBlock.subCode("if($context.exist(\"" + name + "\")){");
         positionCodeBlock.subCode("    write($writer,$context.get(\"" + name + "\"));");
         positionCodeBlock.subCode("}else {");
         positionCodeBlock.subCode("    new AbstractMacro(\"" + name + "\") {");
         positionCodeBlock.subCode("        protected void renderMacro(Template $template, TemplateContext $context,TemplateContext $newContext, Writer $writer) throws IOException, TemplateException {");
         CodeBlock subCodeBlock = pushPeekCodeBlock();
         ctx.block().accept(this);
         popCodeBlock();
         positionCodeBlock.subCode(subCodeBlock);
         positionCodeBlock.subCode("        }");
         positionCodeBlock.subCode("    }.renderMacro($template, $context, $newContext,$writer);");
         positionCodeBlock.subCode("}");
         return positionCodeBlock;
     }
 
 
 //    public CodeBlock visitExpr_math_unary_suffix(@NotNull TinyTemplateParser.Expr_math_unary_suffixContext ctx) {
 //        peekCodeLet().code("O.e(\"l").code(ctx.getChild(1).getText()).code("\",");
 //        ctx.expression().accept(this);
 //        peekCodeLet().code(")");
 //        return null;
 //    }
 
 
         CodeBlock codeBlock = new CodeBlock();
         codeBlock.subCode("$macro= getMacro($context);");
         codeBlock.subCode("if($macro!=null) {");
         codeBlock.subCode("    $newContext=new TemplateContextDefault();");
         codeBlock.subCode("    $newContext.setParent($context);");
         codeBlock.subCode("    $macro.render($template,$context,$newContext,$writer);");
         codeBlock.subCode("}");
         return codeBlock;
     }
 
         for (TinyTemplateParser.Define_expressionContext exp : ctx.define_expression()) {
             if (exp.expression() == null) {
                 peekCodeLet().code("addParameter(\"%s\",null);"exp.IDENTIFIER().getText());
             } else {
                 peekCodeLet().code("addParameter(\"%s\",new EvaluateExpression() {public Object evaluate(TemplateContext $context)throws TemplateException{return "exp.IDENTIFIER().getText());
                 exp.expression().accept(this);
                 peekCodeLet().code(";}});");
             }
         }
         peekCodeLet().code("\n");
         return null;
     }
 
 
         int index = ++;
         CodeBlock callMacro = new CodeBlock();
         CodeBlock callMacroFunctionDeclare = new CodeBlock();
         callMacroFunctionDeclare.header("private void callMacro" + index + "(TemplateContext $context, Writer $writer, Template $template) throws TemplateException {");
         callMacroFunctionDeclare.footer("}");
         CodeBlock callMacroFunctionBody = new CodeBlock();
         String name = ctx.getChild(0).getText();
         name = name.substring(1, name.length());
         if (name.endsWith("(")) {
             name = name.substring(0, name.length() - 1).trim();
         }
         if (name.equals("macro")) {
             TerminalNodeImpl terminalNode = (TerminalNodeImplctx.getChild(0);
             throw new SyntaxErrorException("Missing macro name for #macro directive."terminalNode.getSymbol().getLine(), terminalNode.getSymbol().getStartIndex());
         }
         processCallMacro(ctx.para_expression_list(), callMacroFunctionBody"\"" + name + "\"");
         callMacroFunctionBody.subCode(String.format("$macro.render($template,$context,$newContext,$writer);"));
         .subCode(callMacroFunctionDeclare);
         callMacroFunctionDeclare.subCode(callMacroFunctionBody);
         callMacro.subCode("callMacro" + index + "($context, $writer, $template);");
         return callMacro;
     }
 
 
         return null;
     }
 
         return null;
     }
 
 
         int index = ++;
 
         CodeBlock callMacro = new CodeBlock();
         CodeBlock callMacroFunctionDeclare = new CodeBlock();
         callMacroFunctionDeclare.header("private void callMacro" + index + "(TemplateContext $context, Writer $writer, Template $template) throws TemplateException {");
         callMacroFunctionDeclare.footer("}");
         CodeBlock callMacroFunctionBody = new CodeBlock();
         String name = ctx.getChild(0).getText();
         name = name.substring(2, name.length() - 1).trim();
         processCallMacro(ctx.para_expression_list(), callMacroFunctionBody"\"" + name + "\"");
         CodeBlock bodyContentMacro = new CodeBlock();
         //callMacro.subCode("$bodyMacro= (Macro) $context.getItemMap().get(\"bodyContent\");");
         //callMacro.subCode("if($bodyMacro==null){");
         callMacroFunctionBody.subCode(bodyContentMacro);
         bodyContentMacro.header("Macro $bodyMacro=new AbstractMacro(\"bodyContent\",(Macro)$context.getItemMap().get(\"bodyContent\")) {");
         CodeBlock render = getMacroRenderCodeBlock(true);
         bodyContentMacro.subCode(render);
 
         pushCodeBlock(render);
         ctx.block().accept(this);
 
         popCodeBlock();
         bodyContentMacro.footer("};");
         callMacroFunctionBody.subCode("$newContext.put(\"bodyContent\",$bodyMacro);");
         //callMacro.subCode("}");
         callMacroFunctionBody.subCode("$bodyMacro.setTemplateEngine(this.getTemplateEngine());");
         callMacroFunctionBody.subCode("$macro.render($template,$context,$newContext,$writer);");
         .subCode(callMacroFunctionDeclare);
         callMacroFunctionDeclare.subCode(callMacroFunctionBody);
         callMacro.subCode("callMacro" + index + "($context, $writer, $template);");
         return callMacro;
     }
 
     private void processCallMacro(TinyTemplateParser.Para_expression_listContext listContextCodeBlock callMacroString name) {
 
         callMacro.subCode(String.format("Macro $macro=getTemplateEngine().findMacro(%s,$template,$context);"name));
         callMacro.subCode("TemplateContext $newContext=new TemplateContextDefault();");
         callMacro.subCode("List $paraList=new ArrayList();");
         callMacro.subCode("$newContext.put(" + name + "+\"ParameterList\",$paraList);");
         callMacro.subCode("$newContext.setParent($context);");
         TinyTemplateParser.Para_expression_listContext expList = listContext;
         if (expList != null) {
             pushCodeBlock(callMacro);
             int i = 0;
             for (TinyTemplateParser.Para_expressionContext paraExpressionContext : expList.para_expression()) {
                 processVisitPara(iparaExpressionContextname);
                 i++;
             }
             popCodeBlock();
         }
     }
 
     private void processVisitPara(int iTinyTemplateParser.Para_expressionContext visitParaExpressionString name) {
         CodeLet expression = new CodeLet();
         pushCodeLet(expression);
         if (visitParaExpression.getChildCount() == 3) {
             //如果是带参数的
             visitParaExpression.getChild(2).accept(this);
             peekCodeBlock().subCode(String.format("$newContext.put(\"%s\",%s);"visitParaExpression.getChild(0).getText(), expression));
         } else {
             visitParaExpression.getChild(0).accept(this);
             peekCodeBlock().subCode(String.format("$newContext.put($macro.getParameterName(%d),%s);"iexpression));
         }
         peekCodeBlock().subCode(String.format("((List)$newContext.get(" + name + "+\"ParameterList\")).add(%s);"expression));
         popCodeLet();
     }
 
         CodeBlock include = new CodeBlock();
         CodeLet path = pushPeekCodeLet();
         ctx.expression().accept(this);
         popCodeLet();
         CodeLet map = pushPeekCodeLet();
         if (ctx.hash_map_entry_list() != null) {
             peekCodeLet().code("new TemplateMap()").code(ctx.hash_map_entry_list().accept(this).toString()).code("");
         }
         popCodeLet();
         include.subCode("$newContext = new TemplateContextDefault();");
         if (map.length() > 0) {
             include.subCode(String.format("$newContext.putAll(%s);"map));
         }
         include.subCode("$context.putSubContext(\"$newContext\",$newContext);");
         include.subCode(String.format("getTemplateEngine().renderTemplateWithOutLayout(U.getPath(getPath(),%s),$newContext,$writer);"path));
         include.subCode("$context.removeSubContext(\"$newContext\");");
         return include;
     }
 
 
         return null;
     }
 
 
         CodeBlock tab = new CodeBlock();
         tab.subCode("write($writer,U.getBlanks($context));");
         return tab;
     }
 
 
         CodeBlock callMacro = processVisitCallHead(ctx.expression(), ctx.para_expression_list());
 
         CodeBlock bodyContentMacro = new CodeBlock();
         callMacro.subCode(bodyContentMacro);
         callMacro.subCode("$macro.render($template,$context,$newContext,$writer);");
 
         bodyContentMacro.header("$newContext.put(\"bodyContent\",new AbstractMacro(\"bodyContent\",(Macro)$context.getItemMap().get(\"bodyContent\")) {");
         CodeBlock render = getMacroRenderCodeBlock(false);
         bodyContentMacro.subCode(render);
 
         pushCodeBlock(render);
         ctx.block().accept(this);
         popCodeBlock();
         bodyContentMacro.footer("});");
         callMacro.subCode("$context.removeSubContext(\"$newContext\");");
 
         //Body部分创建新的类,然后传入要调用的宏
         return callMacro;
     }
 
         ctx.expression(0).accept(this);
         if (ctx.children.get(1).getText().equals("?")) {
             peekCodeLet().codeBefore("U.sa(").code(",");
         } else {
             peekCodeLet().codeBefore("U.a(").code(",");
         }
         ctx.expression(1).accept(this);
         peekCodeLet().code(")");
         return null;
     }
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree node = ctx.children.get(i);
             CodeBlock codeBlock = node.accept(this);
             if (codeBlock != null) {
                 peekCodeBlock().subCode(codeBlock);
             }
         }
         return null;
     }
 
         peekCodeLet().code("O.e(\"").code(ctx.getChild(1).getText()).code("\",");
         ctx.expression(0).accept(this);
         peekCodeLet().code(",");
         ctx.expression(1).accept(this);
         peekCodeLet().code(")");
         return null;
     }
 
 
         peekCodeLet().code("O.e(\"").code(ctx.getChild(1).getText()).code("\",");
         ctx.expression(0).accept(this);
         peekCodeLet().code(",");
         ctx.expression(1).accept(this);
         peekCodeLet().code(")");
         return null;
     }
 
 
         return null;
     }
 
         CodeBlock codeBlock = new CodeBlock();
         CodeLet codeLet = pushPeekCodeLet();
         codeBlock.header(codeLet);
         ctx.expression().accept(this);
         popCodeLet();
         codeLet.codeBefore("$context.put(\"" + ctx.getChild(0).getText() + "\",").lineCode(");");
         return codeBlock;
     }
 
         peekCodeLet().code(node.getText());
         return null;
     }
 
 
         List<TinyTemplateParser.Set_expressionContextsetExpressionContexts = ctx.set_expression();
         for (TinyTemplateParser.Set_expressionContext node : setExpressionContexts) {
             CodeBlock codeBlock = new CodeBlock();
             CodeLet codeLet = pushPeekCodeLet();
             codeBlock.header(codeLet);
             node.getChild(2).accept(this);
             popCodeLet();
             if (ctx.getChild(0).getText().equals("#set(")) {
                 codeLet.codeBefore("$context.put(\"" + node.getChild(0) + "\",").lineCode(");");
             } else {
                 codeLet.codeBefore("$pageContext.put(\"" + node.getChild(0) + "\",").lineCode(");");
             }
             peekCodeBlock().subCode(codeBlock);
         }
         return null;
     }
 
 
         pushCodeBlock();
         pushCodeLet();
         ctx.expression().accept(this);
         .subCode(peekCodeLet().codeBefore("addImport(").lineCode(");"));
         popCodeLet();
         popCodeBlock();
 
         return null;
     }
 
         return null;
     }
 
 
         CodeLet codeLet = new CodeLet();
         pushCodeLet(codeLet);
         ctx.expression().accept(this);
         String functionName = ctx.IDENTIFIER().getText();
         peekCodeLet().codeBefore(ctx.getChild(1).getText().equals(".") ? "U.c($template,$context," : "U.sc($template,$context,").code(",\"").code(functionName).code("\"");
         if (list != null) {
             peekCodeLet().code(",");
             list.accept(this);
         }
         peekCodeLet().code(")");
         popCodeLet();
         peekCodeLet().code(codeLet);
         return null;
     }
 
         peekCodeLet().code("O.ce($context,\"").code(ctx.getChild(1).getText()).code("\",").code("\"" + ctx.getChild(0).getText() + "\",");
         ctx.expression().accept(this);
         peekCodeLet().code(")");
         return null;
     }
 
         CodeBlock blank = new CodeBlock();
         blank.subCode("write($writer,\" \");");
         return blank;
     }
 
 
         if (ctx.expression_range() != null) {
             CodeLet startExp = pushPeekCodeLet();
             ctx.expression_range().expression().get(0).accept(this);
             popCodeLet();
             CodeLet endExp = pushPeekCodeLet();
             ctx.expression_range().expression().get(1).accept(this);
             popCodeLet();
             peekCodeLet().code("new RangeList(%s,%s)"startExp.toString(), endExp.toString());
         } else {
             ParseTree items = ctx.getChild(1);
 
             for (int i = 0; i < items.getChildCount(); i++) {
                 CodeLet tmp = pushPeekCodeLet();
                 items.getChild(i).accept(this);
                 popCodeLet();
                 peekCodeLet().code(tmp);
             }
             peekCodeLet().codeBefore("new Object[]{").code("}");
         }
         return null;
     }
 
         String name = "$" + ctx.IDENTIFIER().getText();
         CodeBlock positionCodeBlock = new CodeBlock();
         positionCodeBlock.subCode("if(!$context.exist(\"" + name + "\")){");
         positionCodeBlock.subCode("    Writer templateWriter = new java.io.CharArrayWriter();");
         positionCodeBlock.subCode("    new AbstractMacro(\"" + name + "\") {");
         positionCodeBlock.subCode("        protected void renderMacro(Template $template, TemplateContext $context, TemplateContext $newContext,Writer $writer) throws IOException, TemplateException {");
         CodeBlock subCodeBlock = pushPeekCodeBlock();
         ctx.block().accept(this);
         popCodeBlock();
         positionCodeBlock.subCode(subCodeBlock);
         positionCodeBlock.subCode("        }");
         positionCodeBlock.subCode("    }.renderMacro($template, $context, $newContext,templateWriter);");
         positionCodeBlock.subCode("    $context.put(\"" + name + "\",templateWriter);");
         positionCodeBlock.subCode("}");
         return positionCodeBlock;
     }
 
 
         peekCodeLet().code("O.ce($context,\"l").code(ctx.getChild(0).getText()).code("\",").code("\"" + ctx.getChild(1).getText() + "\",");
         ctx.expression().accept(this);
         peekCodeLet().code(")");
         return null;
     }
 
 
         CodeLet condition = new CodeLet();
         pushCodeLet(condition);
         ctx.expression(0).accept(this);
         popCodeLet();
         CodeLet left = new CodeLet();
         pushCodeLet(left);
         ctx.expression(1).accept(this);
         popCodeLet();
         CodeLet right = new CodeLet();
         pushCodeLet(right);
         ctx.expression(2).