genprintvis.beh.html

Program{
	void addPrintVisitor(String name)(@
    addClassDef(ClassDef.parse("*notparsed* *visitor* " + name + " = "
			       + " <indent> int <needSpace> boolean."));
  @)
	static String genericOutputVisitorPreamble(String name)(@
    return
 "// This file is automatically generated by Demeter/Java.\n"
+"\n"
+ name + " {\n"
+"  " + Text.begin + "\n"
+"    private java.io.PrintWriter out = new java.io.PrintWriter(System.out, true);\n"
+"    java.io.PrintWriter get_out()             { return out; }\n"
+"    void set_out(java.io.PrintWriter new_out) { out = new_out; }\n"
+"    " + name + "(java.io.PrintWriter out)     { set_out(out); }\n"
+"    " + name + "(java.io.PrintStream out)\n"
+"      { set_out(new java.io.PrintWriter(out, true)); }\n"
+"  " + Text.end + "\n"
+"\n";
  @)
	void generatePrintVisitor(String name, File file)to{ Part, PlainSyntax, PrintIndent, PrintUnindent, PrintSkip, PrintSpace }{
		before Program (@
      host.openOutputFile(file);
      Program.out.println(host.genericOutputVisitorPreamble(name)
+"  private void space() " + Text.begin + "\n"
+"    if (needSpace) out.print(\" \");\n"
+"    needSpace = false;\n"
+"  " + Text.end + "\n"
      );
    @)
		(@ ClassName classname; Part part; String syntax; @)
		before ClassDef (@
      classname = host.get_classname();
      part = null;
      syntax = "";
    @)
		(@ boolean inOptional, partWasOptional, optHadPart; @)
		before PrintIndent (@
      syntax += "    out.print(\"\\t\");\n"
	      + "    indent++;\n"
	      + "    needSpace = false;\n";
    @)
		before PrintUnindent (@
      syntax += "    indent--;\n";
    @)
		before PrintSkip (@
      syntax += "    out.println();\n"
	      + "    for (int i = 0; i < indent; i++) out.print(\"\\t\");\n"
	      + "    needSpace = false;\n";
    @)
		before PrintSpace (@
      syntax += "    out.print(\" \");\n"
	      + "    needSpace = false;\n";
    @)
		before PlainSyntax (@
      String str = host.get_string();
      if (Character.isJavaIdentifierStart(str.charAt(0)))
	syntax += "    space();\n";
      syntax += "    out.print(\"" + str + "\");\n";
      if (Character.isJavaIdentifierPart(str.charAt(str.length()-1)))
	syntax += "    needSpace = true;\n";
      else
	syntax += "    needSpace = false;\n";
    @)
		before OptionalPart (@
      if (syntax.length() > 0) {
	if (part == null) {
	  Program.out.println(classname.makeBefore(syntax));
	} else {
	  Program.out.println(part.makeAfter(classname, syntax));
	}
	Program.out.println();
	syntax = "";
      }
      inOptional = true;
    @)
		before Part (@
      // Don't print final, static or derived members.
      if (host.isFinal() || host.isStatic() || host.isDerived()) return;
      part = host;
      partWasOptional = false;
      if (inOptional) optHadPart = true;
      PartName partname = host.get_partname();
      ClassName dest = host.get_classname();    
      String deststr = dest.toString();
      if (host.isTerminal()) {
	syntax += "    space();\n";
	if (deststr.equals("String")) {
	  syntax += "    out.print(\"\\\"\""
		  + " + source.get_" + partname + "() + \"\\\"\");\n";
	} else if (deststr.equals("Text")) {
	  syntax += "    out.print(\"" + Text.begin + "\""
		  + " + source.get_" + partname + "() + "
		  + Text.quoted_end + ");\n";
	} else if (deststr.equals("Character") || deststr.equals("char")) {
	  syntax += "    out.print(\"'\""
		  + " + source.get_" + partname + "() + \"'\");\n";
	} else {
	  syntax += "    out.print(source.get_" + partname + "());\n";
	}
	syntax += "    needSpace = true;\n";
      }
      if (syntax.length() > 0) {
	Program.out.println(host.makeBefore(classname, syntax));
	Program.out.println();
	syntax = "";
      }
    @)
		after OptionalPart (@
      if (optHadPart) {
	if (syntax.length() > 0) {
	  Program.out.println(part.makeAfter(classname, syntax));
	  Program.out.println();
	  syntax = "";
	}
      }
      optHadPart = false;
      inOptional = false;
      partWasOptional = true;
    @)
		after ClassDef (@
      if (syntax.length() > 0) {
	if (part == null) {
	  Program.out.println(classname.makeBefore(syntax));
	} else if (partWasOptional) {
	  Program.out.println(classname.makeAfter(syntax));
	} else {
	  Program.out.println(part.makeAfter(classname, syntax));
	}
	Program.out.println();
      }
    @)
		after Program (@
      Program.out.println("}");
      host.closeOutputFile();
    @)
	}
}