TAO.beh.html

Program{
	(@
   public static Vector TAOclasses = new Vector(13);
   public static String visitorclass="TAOVisitor";

   static { 
     TAOclasses.addElement("Traversal");
     TAOclasses.addElement("TAO_TravList");
     TAOclasses.addElement("TAO_TravLabel");
     TAOclasses.addElement("TAO_Bypass");
     TAOclasses.addElement("TAO_NextTrav");
     TAOclasses.addElement("TAO_ClassNames");
     TAOclasses.addElement("TAO_OneClassGlob");
     TAOclasses.addElement("TAO_ClassGlob");
     TAOclasses.addElement("TAO_ClassGlobSet");
     TAOclasses.addElement("TAO_ClassGlobList");
     TAOclasses.addElement("TAO_NextClassGlob");
     TAOclasses.addElement("TAO_AnyClass");
     TAOclasses.addElement("TAO_ClassName");
   }

   public static FindVisitorTargetsV fvtv;

   // before parser expansion
   public static void genTAO1() {
     // sanity check. we need some classes to be undefined:
     // Therefore, this must come before we start adding those classes
     for (Enumeration classes = prog.get_cg().get_defdict().keys();classes.hasMoreElements();) {
       String classname = ((ClassName) classes.nextElement()).toString();
       if (TAOclasses.contains(classname)) {
	 System.err.println("Please don't use the class name "+classname+" as TAO needs it");
	 System.exit(1);
       }
     }

     log.println(" TAO: Adding support classes"); 
     Program.addTAOClasses();
   }	

   // after repetiton expansion
   public static void genTAO2() {
     log.println(" TAO: Adding Methods to user classes");
     Program.addToUserCodeTAO();
   
   }
   

   public static void addTAOClasses() {

    System.err.println("  TAO: parsing functions");
     
       
//       System.err.println("Traversal");
       prog.addClassDef(ClassDef.parse(
"Traversal *parse* = [<label> TAO_TravLabel] \"from\" <fromclasses> TAO_ClassNames <path> TAO_TravList \";\" {("+"@" +
" static Graph fgraph ;\n"+
" static Graph rgraph ; \n"+
//" static Vector alternations = new Vector(); \n"+
" static public void set_graph(Graph g) {\n"+
"   fgraph = g;\n"+
"   rgraph = g.reversegraph();\n"+
" }\n"+
" static Hashtable cache = new Hashtable(); \n"+
" public String thestr; \n"+
" static void printindented(String str1, int indent, String str2) { System.err.print(str1); for (int i=0; i<indent; i++) System.err.print(\" \"); System.err.println(str2); } \n"+
" public void traverse(Object instobj, Vector vs) {\n"+
"   "+Program.visitorclass+"[] vsarr = new "+Program.visitorclass+"[vs.size()]; \n"+
"   vs.copyInto(vsarr); \n"+
"   traverse(instobj,vsarr);\n"+
" }\n"+
" public void traverse(Object instobj, "+Program.visitorclass+"[] vs) {\n"+
((Program.dbg)?"   System.err.println(\"TAO running: \"+thestr);\n":"")+
"   try { pathtrav(path.protoobject, fromclasses.toVector(), instobj,vs"+((Program.dbg)?",0":"")+");\n"+
"   } catch (NullPointerException e) {System.err.println(\" Traversal called on Class not in the traversal: \"+instobj.getClass().getName()+\"\\nprotoobj: \"+path.protoobject.toString()); e.printStackTrace(); System.exit(1);} \n"+ 
" }\n"+
" public void traverse(Object instobj, "+Program.visitorclass+" v) {\n"+
"   "+Program.visitorclass+"[] vsarr = {v}; \n"+ 
"   traverse(instobj,vsarr);\n"+   
" }\n"+

" public static Traversal fromString(String str) {\n"+
"   Traversal t = (Traversal) cache.get(str); \n"+
"   if (t != null) return t; \n"+
"   else { \n"+
"     t = Traversal.parse(str); \n"+
"     try { t.path.initPath(t.get_fromclasses().toVector());\n"+
"     } catch (Exception e) {System.err.println(\"Error initing the traversal \"+str); e.printStackTrace(); System.exit(1);} \n"+ 
"     t.thestr = str; \n"+
"     cache.put(str,t); \n"+
"     return t; } \n"+
" } \n"+
" @"+")}."));

//       System.err.println("TAO_TravList");
       prog.addClassDef(ClassDef.parse(
"TAO_TravList *parse* = [<bypass> TAO_Bypass] \"to\" <too> TAO_ClassNames [<next> TAO_NextTrav] {("+"@" +
" public Hashtable protoobject;\n"+
" public Graph myfgraph = Traversal.fgraph.deepcopy();\n"+
" public Graph myrgraph = Traversal.rgraph.deepcopy();\n"+
" private Vector fromclasses; \n"+
" static String strippackage(String str) { return str.substring(str.lastIndexOf('.')+1,str.length()); } \n"+
" public void initPath(Vector fclasses) { \n"+
"   fromclasses = fclasses;\n"+
"   Vector toclasses = too.toVector();\n"+
"   protoobject = new Hashtable();\n"+
"   Vector bypassclasses;\n"+
"   if (get_bypass() == null) bypassclasses = new Vector(0);\n"+
"   else bypassclasses= get_bypass().toVector();\n"+
"   if (next != null) { \n"+
"     // The boaz-lieberherr single protoobject impl.\n "+
// make the next traversal of the join
"     next.get_trav().initPath(toclasses); \n"+
"     try {\n"+
"       for (Enumeration tocenum = toclasses.elements(); tocenum.hasMoreElements();) {\n"+
// grab each to class of this traversal from the next traversal: this is called priming
"	 String  toclass = tocenum.nextElement().toString();\n"+
// grab the to class. This should be done better: 
// 1) check that toinst is a fromclass of the next trav
// 2) for tc in {this.to}, if tc.superclass* in {next.from}&& tc not in {next.from}, 
//       we should grab the closest superclass that is in {next.from}
"        Object[] toinst = (Object[]) next.get_trav().protoobject.get(toclass); \n"+
// store the grabbed object in this traversal, as per liberherr & boaz
"	 protoobject.put(toclass,toinst);\n"+
"       }\n"+
"     } catch (NullPointerException e) {\n"+
"       System.err.println(\n"+
"	 \"During a join, a nullpointer was derefrenced. Oops. Tell johan\");\n"+
"       e.printStackTrace();\n"+
"       System.exit(1);\n"+
"     }\n"+
"     selectFromToStop(fromclasses, bypassclasses, toclasses); \n"+      // next != null
"   } else { selectFromTo(fromclasses, bypassclasses, toclasses); } \n"+ // next  = null
//"   System.err.println(\"myfgraph:\"+myfgraph.toString());\n"+
"   for (Enumeration fcenum = fromclasses.elements(); fcenum.hasMoreElements();) {\n"+
"     String fromclassname = fcenum.nextElement().toString();\n"+
"     Traversal.makeproto(fromclassname,protoobject,myfgraph"+((Program.dbg)?",0":"")+");\n"+
"   }\n"+
"   myfgraph = null; myrgraph = null; \n"+
"  }\n"+

"  public void selectFromToStop(Vector fromclasses, Vector bypassclasses, Vector toclasses) { \n"+
"    for (Enumeration tcenum = toclasses.elements(); tcenum.hasMoreElements();) {\n"+
"      Ident toname = (Ident) tcenum.nextElement();\n"+
"      myfgraph.clearnode(toname); \n"+
"    } \n"+
"    myrgraph = myfgraph.reversegraph();\n"+
"    selectFromTo(fromclasses, bypassclasses,  toclasses);\n"+
"  }\n"+

"  public void selectFromTo(Vector fromclasses, Vector bypassclasses, Vector toclasses) {\n"+
// bypass edges: remove incoming
"    for (Enumeration bcenum = bypassclasses.elements(); bcenum.hasMoreElements();) {\n"+
"      Ident bypassingname   = (Ident) bcenum.nextElement();\n"+
"      myrgraph.clearnode(bypassingname); \n"+
"      myfgraph.removeincoming(bypassingname); \n"+
"    } \n"+
((Program.dbg)?"   System.err.println(\"Subgraph from \"+fromclasses.toString()+\" bypassing \"+bypassclasses.toString()+\" to \"+toclasses.toString());\n":"")+
"    for (Enumeration fcenum = fromclasses.elements(); fcenum.hasMoreElements();) {\n"+
"      Ident fromname = (Ident) fcenum.nextElement();\n"+
"      for (Enumeration tcenum = toclasses.elements(); tcenum.hasMoreElements();) {\n"+
"	 Ident toname   = (Ident) tcenum.nextElement();\n"+
//"        System.err.println(\"DFS \"+fromname+\" -> \"+toname); \n"+
"	 myfgraph.dfs(fromname,\"TAO_f_mark\");\n"+
"	 myrgraph.dfs(toname,\"TAO_r_mark\");\n"+
"	 for (Enumeration nodes = myfgraph.nodes(); nodes.hasMoreElements();) {\n"+
"	   Ident node = (Ident) nodes.nextElement();\n"+
"	   if (myfgraph.nodehasmark(node,\"TAO_f_mark\") && myrgraph.nodehasmark(node,\"TAO_r_mark\")) {\n"+
"	     myfgraph.marknode(node,\"TAO_t_mark\");\n"+
((Program.dbg)?"            System.err.println(\" includes: \"+node.toString());\n":"")+
"	 } }\n"+
"	 myfgraph.clearmark(\"TAO_f_mark\");\n"+
"	 myrgraph.clearmark(\"TAO_r_mark\");\n"+
((Program.dbg)?"            System.err.println(\"done\");\n":"")+
"      }\n"+
"    }\n"+
"  }\n"+
"\n"+
" @"+")}."));

//       System.err.println("TAO_NextTrav");
       prog.addClassDef(ClassDef.parse("TAO_NextTrav *parse* = \"then\" <trav> TAO_TravList. \n"));

//       System.err.println("TAO_Bypass");
       prog.addClassDef(ClassDef.parse(
"TAO_Bypass *parse* = \"bypassing\" <bypass> TAO_ClassNames \n"+
" { ("+"@ public Vector toVector() { Vector v = new Vector(); bypass.allClassNames(v); return v;} \n"+
" @"+") }.\n"));

//       System.err.println("TAO_TravLabel");
       prog.addClassDef(ClassDef.parse("TAO_TravLabel *parse* = <travlab> Ident \"=\".\n"));

     
       prog.addClassDef(ClassDef.parse(
"TAO_ClassNames *parse* : TAO_OneClassGlob | TAO_ClassGlobSet \n"+
"{ ("+"@ public Vector toVector() { Vector v = new Vector(); allClassNames(v); return v;} \n"+
" public void allClassNames(Vector v) {System.out.println(\"ClassNames should be overridden.\");}"+
" @"+")}."));

       prog.addClassDef(ClassDef.parse(
"TAO_OneClassGlob *parse* = <classglob> TAO_ClassGlob {("+"@\n"+
"public void allClassNames(Vector v) {get_classglob().allClassNames(v);} @"+")} ."));
       prog.addClassDef(ClassDef.parse(
"TAO_ClassGlobSet *parse* = \"{\" <classglobs> TAO_ClassGlobList \"}\" {("+"@ \n"+
"public void allClassNames(Vector v) {get_classglobs().allClassNames(v);} @"+")} ."));
       prog.addClassDef(ClassDef.parse(
"TAO_ClassGlobList *parse* = <classglob> TAO_ClassGlob [ <next> TAO_NextClassGlob] {("+"@ \n"+
"public void allClassNames(Vector v) {get_classglob().allClassNames(v); if (get_next() != null) get_next().allClassNames(v);} @"+")} ."));
       prog.addClassDef(ClassDef.parse(
"TAO_NextClassGlob *parse* = \",\" <classgloblist> TAO_ClassGlobList {("+"@ \n"+
"public void allClassNames(Vector v) {get_classgloblist().allClassNames(v);} @"+")} ."));
       prog.addClassDef(ClassDef.parse(
"TAO_ClassGlob *parse* : TAO_AnyClass | TAO_ClassName {("+"@ \n"+
"public void allClassNames(Vector v) {System.out.println(\"TAO_ClassGlob override\");} @"+")} ."));
       prog.addClassDef(ClassDef.parse(
"TAO_AnyClass *parse* = \"*\" {("+"@ \n"+
"public void allClassNames(Vector v) {System.err.println(\"Help\");} @"+")} ."));
       prog.addClassDef(ClassDef.parse(
"TAO_ClassName *parse* = <name> Ident {("+"@ \n"+
"public void allClassNames(Vector v) { \n"+
"       if (!v.contains(name)) v.addElement(name); } @"+")} ."));
    
       // finally, connect up the backlinks.
       prog.setInheritanceLinks();
  } 
@)
}

Program{
	(@
   public static void addToUserCodeTAO() {  

     // see if doug's wrapper info can remove the fvtv visitor.

     fvtv = new FindVisitorTargetsV();
     prog.findVisitorTargets(fvtv);

     CreateMethodsV cmv = new CreateMethodsV(fvtv.get_btargets(),fvtv.get_atargets(),fvtv.get_aroundtargets() ); 

     prog.makemethods(cmv);

   }
  @)
}

{ Program, ClassDef }{
	traversal makemethods(CreateMethodsV cmv) {
		to{ ClassDef, ConstructionClass, AlternationClass, OptionalPart, Part, Subclass, ClassParents, AlternationClass };
	}
}

Program{
	traversal findVisitorTargets(FindVisitorTargetsV fvtv) {
		through Wrapper to{ Before, After, Around, ClassNameExact, AnyClass };
	}
}

FindVisitorTargetsV{
	init (@
    btargets = new Vector();
    atargets = new Vector();
    aroundtargets = new Vector();
  @)
	before ClassDef (@ visitorname = host.get_classname().toString();
     if (Program.dbg) System.err.println("looking for wrappers in "+visitorname);
     @)
	before Before (@ doing = btargets; 
     if (Program.dbg) System.err.println(" seeing Before wrappers");
     @)
	before After (@ doing = atargets; 
     if (Program.dbg) System.err.println(" seeing After wrappers");
     @)
	before Around (@ 
     doing = aroundtargets; 
     if (Program.dbg) System.err.println(" seeing Around wrappers");
     @)
	before ClassNameExact (@ 
     if (Program.dbg) System.err.println("  "+host.get_classname());
     if (!doing.contains(host.get_classname()))
       doing.addElement(host.get_classname());
     @)
	before AnyClass (@
// BUG: a bit of one, at least....
       System.err.println("OOPS! died trying to goto all classes");
       System.exit(1);
     @)
	after Program (@
     // now go through the two arrays and mark any class wiht an active superclass as active
     for (Enumeration cds = Program.prog.get_cg().defdict.elements(); cds.hasMoreElements();) {
       ClassDef cd = (ClassDef) cds.nextElement();
       ClassName cdn = cd.get_classname();

       if (!btargets.contains(cdn)) {
	 ClassDef tcd = cd;
	 tcd = tcd.get_superclass_def();
	 while (tcd != null) {
	   if (btargets.contains(tcd.get_classname())) {
	     btargets.addElement(cdn);
	     if (Program.dbg) System.err.println("Before v in "+cdn);
	     break;
	   }
	   tcd = tcd.get_superclass_def();
	 }
       } else if (Program.dbg) System.err.println("Before v in "+cdn);

       if (!atargets.contains(cdn)) {
	 ClassDef tcd = cd;
	 tcd = tcd.get_superclass_def();
	 while (tcd != null) {
	   if (atargets.contains(tcd.get_classname())) {
	     atargets.addElement(cdn);
	     if (Program.dbg) System.err.println("After v in "+cdn);
	     break;
	   }
	   tcd = tcd.get_superclass_def();
	 }
       } else if (Program.dbg) System.err.println("After v in "+cdn);

       if (!aroundtargets.contains(cdn)) {
	 ClassDef tcd = cd;
	 tcd = tcd.get_superclass_def();
	 while (tcd != null) {
	   if (aroundtargets.contains(tcd.get_classname())) {
	     aroundtargets.addElement(cdn);
	     if (Program.dbg) System.err.println("Around v in "+cdn);
	     break;
	   }
	   tcd = tcd.get_superclass_def();
	 }
       } else if (Program.dbg) System.err.println("Around v in "+cdn);

     }
     @)
}

CreateMethodsV{
	(@	
   public CreateMethodsV(Vector b, Vector a, Vector ar) {
     btargets = b;
     atargets = a;
     aroundtargets = ar;
   }

   @)
}

CreateMethodsV{
	before Program (@
     makeprotomain = "";
     pathtravmain = "";
     graphstr = "";
     visitorstr = "";
     doneclasses = new Vector();
     baseclassname = "";
     @)
	around ClassDef (@ 
     // perhaps abort if we come into an alternation class first?

     // don't do the added classes or classes already done
     abort = Program.TAOclasses.contains(host.get_classname().toString()) ; 
     if (abort) return;

     // used in alternation hierarchies to check for *common* edges
     // from the flattened location, ie the _construction_ class at
     // the base of the hierarchy. This will be set to the last seen
     // construction class, so it might seem that we will get
     // erroneous results if we see a construction class, and then an
     // unrelated alternation class, but the computations affected by
     // this value (makeprotoparts) is only used by construction
     // classes, so it is harmless. Probably needs more expl.
     if (host.isConstructionClass()) set_baseclassname(host.get_classname().toString());

     set_makeprotoparts("");
     set_hierarchy(new Vector());
     set_partstr("");
     set_partcounter(1); // 0 is used as the classname checker.

     // first we do any superclass, if thsi is an alternation:
     ClassDef wcd = host.get_superclass_def();
     if (wcd != null) 
       wcd.makemethods(this); // use this visitor, so partstr and friends gets set


     get_hierarchy().addElement(host.get_classname());
     set_traverseparts("");
     set_subclassstr("");
     set_subclasscounter(1);
     set_makeprotosubclasses("");
     set_traversesubclasses("");     
     set_abort(false); 
     set_classname(host.get_classname().toString());


     set_rcd(host);
     set_optionalpart(false);

     if (!doneclasses.contains(get_classname())) {     
       makeBeforeVisitorStuff();
       makeAfterVisitorStuff();
       makeprotomain = makeprotomain + 
	 "   if (cn.equals(\""+classname+"\")) makeproto_"+classname+"(ht,pgt"+((Program.dbg)?", indent":"")+"); \n"; 
       pathtravmain = pathtravmain +
	 "   if ((instobj instanceof "+classname+") && (fromclasses.contains(new Ident(\""+classname+"\")))) { (("+classname+") instobj).prototrav_"+classname+"((Object[]) protoobj.get(\""+classname+"\"),visitors"+((Program.dbg)?", indent":"")+"); return ;}\n"; 
       
       visitorstr=visitorstr+
	 "   void before("+classname+" foo) {}\n   void after("+classname+" foo) {}\n   void around(AroundContinuation subtraversal, "+classname+" foo) {subtraversal.apply();}\n";
     }
     
// the parts
     subtraversal.apply(); 

     if (!doneclasses.contains(get_classname())) {
	String runaround = 
	  "    AroundContinuation cont_foo = new AroundContinuation() {public void apply() {subtraversal.apply(); parttrav_"+get_classname()+"(protoobj,visitors"+((Program.dbg)?",indent":"")+"); }}; \n"+
	  ((get_aroundtargets().contains(get_classname()))
	   ?"    final "+get_classname()+" oldthis = this;\n"+
	    "    for (int i = visitors.length -1; i >= 0 ; i-- ) {\n"+
	    "      final int j = i;\n final AroundContinuation cont_bar = cont_foo; \n"+  
	    "      cont_foo = new AroundContinuation() {public void apply() { visitors[j].around(cont_bar, oldthis);}}; } \n"
	   :"");


        rcd.addMethod(Verbatim.parse("("+"@\n"+
	    "  public void runwrappers_"+get_classname()+"(final Object[] protoobj,final "+Program.visitorclass+"[] visitors"+((Program.dbg)?",final int indent":"")+",final AroundContinuation subtraversal) {\n"+
//	    ((Program.dbg)?"System.err.println(\"Protoobject is of type:\"+(String) protoobj[0]+\" and this is a "+get_classname()+"\"); \n":"")+
            ((get_btargets().contains(get_classname()))?"    runBeforeVisitors_"+get_classname()+"(visitors);\n":"")+
  	    runaround+" cont_foo.apply();\n"+			   
	    ((get_atargets().contains(get_classname()))?"    runAfterVisitors_"+get_classname()+"(visitors);\n":"")+
            "  } // end of runwrappers\n\n"+
            "@"+")\n"));

	rcd.addMethod(Verbatim.parse("("+"@\n"+
	    "  public void parttrav_"+get_classname()+"(final Object[] protoobj,final "+Program.visitorclass+"[] visitors"+((Program.dbg)?",final int indent":"")+") {\n"+
	    traverseparts+	        
	    "} @"+")\n"));
	
	doneclasses.addElement(get_classname());
      }


      @)
	before ConstructionClass (@ 
     if (abort) return;
     if (Program.dbg) System.err.print("\n Construction: "+get_classname());
     @)
	before AlternationClass (@
     if (abort) return;
     if (Program.dbg) System.err.print("\n Alternation: "+ get_classname());
     @)
	before OptionalPart (@ optionalpart = true; @)
	after OptionalPart (@ optionalpart = false; @)
	before Part (@  
     if (abort) return;

     PartName partname = host.get_partname();
     ClassName partclass = host.get_classname();


     // only traverse .cd defined classes
     if (! Program.prog.get_cg().definesClass(partclass)) return; 
     if ( Program.TAOclasses.contains(partclass.toString())) return; 


     if (Program.dbg) System.err.print(" "+partname+":"+partcounter);

     makeprotoparts = makeprotoparts +
	 ((Program.dbg)?"Traversal.printindented(\"makeproto \",indent,\" making part: "+classname+"=>"+partclass+"\"); \n":"")+
         "   arr["+partcounter+"] = ((pgt.edgeexists(new Ident(\""+baseclassname+"\"),new Ident(\""+partname+"\")))?makeproto_"+partclass+"(ht,pgt"+((Program.dbg)?",indent+1":"")+"):null); \n";
 
     traverseparts = traverseparts +
         "   if (protoobj["+partcounter+"] != null) "+((optionalpart)?"if (get_"+partname+"() != null)":"")+" {\n"+
        ((Program.dbg)?"Traversal.printindented(\"prototrav \",indent,\""+classname+"->"+partname+"\");\n":"")+
         "     get_"+partname+"().prototrav_"+partclass+"((Object []) protoobj["+partcounter+"],visitors"+((Program.dbg)?",indent+1":"")+");\n"+
         "   }\n";
 
     partstr = partstr + partname+" "+partclass+" ";	

     partcounter++;

     @)
	before Subclass (@
     if (abort) return;

     ClassName partclass = host.get_classname();
     if (! Program.prog.get_cg().definesClass(partclass)) return; // only traverse .cd defined classes

     String partname = "_"+partclass.toString().toLowerCase();
     if (Program.dbg) System.err.print(" "+partname+":"+subclasscounter);
     
     traversesubclasses = traversesubclasses +
        "   if ((protoobj["+subclasscounter+"] != null) && (this instanceof "+partclass+")) {\n"+
        ((Program.dbg)?"Traversal.printindented(\"prototrav \",indent,\""+classname+"=> "+partname+"\");\n":"")+
        "     (("+partclass+") this).prototrav_"+partclass+"((Object []) protoobj["+subclasscounter+"],visitors"+((Program.dbg)?",indent+1":"")+");\n"+
        "   }\n";

     makeprotosubclasses = makeprotosubclasses +
	 ((Program.dbg)?"Traversal.printindented(\"makeproto \",indent,\" making part: "+classname+"=>"+partclass+"\"); \n":"")+
	 "  arr["+subclasscounter+"] = ((pgt.edgeexists(new Ident(\""+classname+"\"),new Ident(\""+partname+"\")))? makeproto_"+partclass+"(ht,pgt"+((Program.dbg)?",indent+1":"")+"):null);\n";

     subclassstr = subclassstr + partname+" "+partclass+" ";	

     subclasscounter++;
      
     @)
	after ConstOrAltClass (@
     if (abort) return;
     if (doneclasses.contains(get_classname())) return;

     if (rcd.isAlternationClass()) {
	 rcd.addMethod(Verbatim.parse(
	    "("+"@\n  public void prototrav_"+get_classname()+"(Object[] protoobj,"+Program.visitorclass+"[] visitors"+((Program.dbg)?",int indent":"")+") {\n"+
	    ((Program.dbg)?"System.err.println(\"Protoobject is of type:\"+(String) protoobj[0]+\" and this is a "+get_classname()+"\");\n":"")+
	    traversesubclasses +
	    " } // end of prototrav\n\n@"+")"));

	 ClassDef tcd = (ClassDef) Program.prog.findClassDef(ClassName.parse("Traversal"));
	 if (tcd == null)        System.err.println("No class Traversal was found.");
	 tcd.addMethod(Verbatim.parse(
	    "("+"@\n"+
            "  public static Object[] makeproto_"+get_classname()+"(Hashtable ht,Graph pgt"+((Program.dbg)?",int indent":"")+") { \n" +
	    "    // first check that this class belongs in the traversal. \n" +
	    "    if (! pgt.nodehasmark(new Ident(\""+get_classname()+"\"),\"TAO_t_mark\")) { \n"+
	    ((Program.dbg)?"Traversal.printindented(\"makeproto \",indent,\""+get_classname()+" not in graph\");\n":"")+
	    "      return null;}\n"+
            "    // if this class has an entry already, then return the entry, else make it and recurse for children \n" +
	    ((Program.dbg)?"System.err.println(\"makeproto "+get_classname()+" in graph\");\n":"")+
	    "    if (ht.containsKey(\""+get_classname()+"\")) { \n"+
	    "      return (Object[]) ht.get(\""+get_classname()+"\");\n"+
	    "    } \n"+
	    "    Object[] arr = new Object["+subclasscounter+"];\n"+
	    "    ht.put(\""+get_classname()+"\",arr);\n\n"+
	    "    arr[0] = \""+get_classname()+"\";\n"+
            makeprotosubclasses+"\n"+
            "    return  arr;\n"+
	    "  } // end makeproto \n\n @"+")"));
 	 graphstr = graphstr + get_classname()+" ( "+(subclasscounter-1) +" "+subclassstr+") ";
     }
     // else!
     
     if (rcd.isConstructionClass()) {
	 String makeconts = "";
       
	 Enumeration hclasses= hierarchy.elements();
	 ClassName thisclass = null;
	 ClassName lowerclass = (ClassName) hclasses.nextElement(); // there is at least one element- this class!
       
	 // while loop for all non concrete classes in the alterantion chain, from the top
	 while (hclasses.hasMoreElements()) {
	   thisclass = lowerclass;
	   lowerclass = (ClassName) hclasses.nextElement();
	 
	   String subcall = "runwrappers_"+lowerclass+"(protoobj,visitors"+((Program.dbg)?", indent":"")+",cont_"+lowerclass+");";       
	   makeconts = 
  	     " final AroundContinuation cont_"+thisclass+" = new AroundContinuation() { public void apply() { "+
	     subcall+
	     "}}; \n" + makeconts;
	 }
	 // so there is one more class to do: the concrete one: lowerclass
       
	 // This is just an empty placeholder, to be handed to runWrappers
	 makeconts = 
	   " final AroundContinuation cont_"+lowerclass+" = new AroundContinuation() { public void apply() {}}; \n "+
	   makeconts;
       
	 rcd.addMethod(Verbatim.parse(
	   "("+"@\n"+
	   "  public void prototrav_"+get_classname()+"(final Object[] protoobj, final "+Program.visitorclass+"[] visitors"+((Program.dbg)?",final int indent":"")+") {\n"+
	   makeconts+
	   "    runwrappers_"+((ClassName) hierarchy.firstElement())+"(protoobj,visitors"+((Program.dbg)?",indent":"")+",cont_"+((ClassName) hierarchy.firstElement())+"); \n"+
	   "  } // end of prototrav\n\n"+
	  "@"+")\n"));
	 
	 ClassDef tcd = (ClassDef) Program.prog.findClassDef(ClassName.parse("Traversal"));
	 if (tcd == null)        System.err.println("No class Traversal was found.");
	 tcd.addMethod(Verbatim.parse(
	   "("+"@\n"+
	   "  public static Object[] makeproto_"+get_classname()+"(Hashtable ht,Graph pgt"+((Program.dbg)?",int indent":"")+") { \n" +
	   "    // first check that this class belongs in the traversal. \n" +
	   "    if (! pgt.nodehasmark(new Ident(\""+get_classname()+"\"),\"TAO_t_mark\")) { \n"+
	   ((Program.dbg)?"Traversal.printindented(\"makeproto \",indent,\""+get_classname()+" not in graph\");\n":"")+
	   "      return null;}\n"+
	   "    // if this class has an entry already, then return the entry, else make it and recurse for children \n" +
	   ((Program.dbg)?"System.err.println(\"makeproto "+get_classname()+" in graph\");\n":"")+
	   "    if (ht.containsKey(\""+get_classname()+"\")) { \n"+
	   "      return (Object[]) ht.get(\""+get_classname()+"\");\n"+
	   "    } \n"+
	   "    Object[] arr = new Object["+partcounter+"];\n"+
	   "    ht.put(\""+get_classname()+"\",arr);\n\n"+
	   "    arr[0] = \""+get_classname()+"\";\n"+
	   makeprotoparts+"\n"+
	   "    return  arr;\n"+
	   "  } // end makeproto \n\n @"+")"));
	 graphstr = graphstr + get_classname()+" ( "+(partcounter-1) +" "+partstr+") ";
     }


     @)
	after Program (@ 
       ClassDef tcd = (ClassDef) Program.prog.findClassDef(ClassName.parse("Traversal"));
       if (tcd == null)        System.err.println("No class Traversal was found.");
       
       // the makeproto and pathtrav dispatch code.
       tcd.addMethod(Verbatim.parse(
	    "("+"@\n"+
            "  public static void makeproto(String cn, Hashtable ht,Graph pgt"+((Program.dbg)?",int indent":"")+") { \n" +
            makeprotomain+"\n"+
	    "  } // end makeproto \n\n @"+")"));

       tcd.addMethod(Verbatim.parse(
	    "("+"@\n"+ 
            " public static void pathtrav(Hashtable protoobj,Vector fromclasses, Object instobj, "+Program.visitorclass+"[]  visitors"+((Program.dbg)?", int indent":"")+") {;\n"+
	    pathtravmain+
	    "  // if we reach this spot, we were unable to dispatch the traversal, so cry foul \n"+
	    "  System.err.println(\"Pathtrav on \"+instobj+\" failed to be found as a fromclass of the traversal\"); System.exit(1);\n"+
   	    "  } // end pathtrav \n\n @"+")"));

       // visitor
       ClassDef vcd = (ClassDef) Program.prog.findClassDef(ClassName.parse(Program.visitorclass));
       if (vcd == null)       
	 System.err.println("All visitors to be used with TAO  must subclass "+Program.visitorclass+". \nYour program has no "+Program.visitorclass+" class");
       // we'll die later on...
       vcd.addMethod(Verbatim.parse("("+"@\n"+visitorstr+" @"+")"));

       // the cd graph init code
       tcd.addMethod(Verbatim.parse(
          "("+"@ static { set_graph(Graph.fromString(\""+graphstr+"\")); } @"+")"));
       // We also need to let Traversal know which classes are alternation classes.

       if (Program.dbg) System.err.println("");

     @)
	(@
   // This code prints out some java level mumbo of the class

   public void makeBeforeVisitorStuff() {

     if (!get_btargets().contains(get_classname())) return;
     // if no before visitors, don't even output code
     
     StringWriter vis_baos = new StringWriter(); 
     PrintWriter vis_behout = new PrintWriter(vis_baos);

     vis_behout.print("("+"@\n");
     vis_behout.print("  public void runBeforeVisitors_"+get_classname()+"("+Program.visitorclass+"[] visitors) {\n");
     ClassName supcn = rcd.get_superclass_name();
     if ((supcn != null) && (get_btargets().contains(supcn))) // if superclass has befores, runem
       vis_behout.print("     runBeforeVisitors_"+rcd.get_superclass_name()+"(visitors);\n");
     if (Program.dbg) vis_behout.print("    System.err.println(\"before visitors for "+get_classname()+"\");\n");
     vis_behout.print("    int len = visitors.length ; \n");
     vis_behout.print("    for (int i = 0; i < len ; i++ ) \n");
     vis_behout.print("      visitors[i].before(this);\n");
     vis_behout.print("  }\n @"+")");
     vis_baos.flush();
     rcd.addMethod(Verbatim.parse(vis_baos.toString()));
     
   }
@)
	(@
   public void makeAfterVisitorStuff() {

     if (!get_atargets().contains(get_classname())) return;

     StringWriter vis_baos = new StringWriter(); 
     PrintWriter vis_behout = new PrintWriter(vis_baos);

     vis_behout.print("("+"@\n");
     vis_behout.print("  public void runAfterVisitors_"+get_classname()+"("+Program.visitorclass+"[] visitors) {\n");
     if (Program.dbg) vis_behout.print("    System.err.println(\"after visitors for "+get_classname()+"\");\n");
     vis_behout.print("  for (int i = visitors.length -1; i >= 0 ; i-- ) \n");
     vis_behout.print("    visitors[i].after(this); \n");
     ClassName supcn = rcd.get_superclass_name();
     if ((supcn != null) && (get_atargets().contains(supcn))) // if superclass has befores, runem
       vis_behout.print("     runAfterVisitors_"+rcd.get_superclass_name()+"(visitors);\n");
     vis_behout.print("  }\n @"+")");
     vis_baos.flush();
     rcd.addMethod(Verbatim.parse(vis_baos.toString()));
   }
@)
}