// main class
  @Override
  public void visit(MainClassSingle c) {
    // Every class must go into its own class file.
    try {
      this.writer =
          new java.io.BufferedWriter(
              new java.io.OutputStreamWriter(new java.io.FileOutputStream(c.id + ".j")));
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    }

    this.sayln("; This is automatically generated by the Tiger compiler.");
    this.sayln("; Do NOT modify!\n");

    this.sayln(".class public " + c.id);
    this.sayln(".super java/lang/Object\n");
    this.sayln(".method public static main([Ljava/lang/String;)V");
    this.isayln(".limit stack 4096");
    this.isayln(".limit locals 2");
    for (Stm.T s : c.stms) s.accept(this);
    this.isayln("return");
    this.sayln(".end method");

    try {
      this.writer.close();
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    }
    return;
  }
  // class
  @Override
  public void visit(ClassSingle c) {
    // Every class must go into its own class file.
    try {
      this.writer =
          new java.io.BufferedWriter(
              new java.io.OutputStreamWriter(new java.io.FileOutputStream(c.id + ".smali")));
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    }

    // header
    this.sayln("; This is automatically generated by the Tiger compiler.");
    this.sayln("; Do NOT modify!\n");

    this.sayln(".class public " + c.id);
    if (c.extendss == null) this.sayln(".super java/lang/Object\n");
    else this.sayln(".super " + c.extendss);

    // fields
    for (Dec.T d : c.decs) {
      DecSingle dd = (DecSingle) d;
      this.say(".field public " + dd.id);
      dd.type.accept(this);
      this.sayln("");
    }

    // methods
    this.sayln(".method public <init>()V");
    this.isayln("aload 0");
    if (c.extendss == null) this.isayln("invokespecial java/lang/Object/<init>()V");
    else this.isayln("invokespecial " + c.extendss + "/<init>()V");
    this.isayln("return");
    this.sayln(".end method\n\n");

    for (Method.T m : c.methods) {
      m.accept(this);
    }

    try {
      this.writer.close();
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    }
    return;
  }
 private void say(String s) {
   try {
     this.writer.write(s);
   } catch (Exception e) {
     e.printStackTrace();
     System.exit(1);
   }
 }
 private void isayln(String s) {
   say("    ");
   say(s);
   try {
     this.writer.write("\n");
   } catch (Exception e) {
     e.printStackTrace();
     System.exit(1);
   }
 }