001    package toolbus;
002    
003    import java.io.File;
004    import java.io.FileOutputStream;
005    import java.io.IOException;
006    import java.io.PrintWriter;
007    import java.text.DateFormat;
008    import java.util.ArrayList;
009    import java.util.Date;
010    import java.util.HashMap;
011    import java.util.Iterator;
012    import java.util.Map;
013    import java.util.Set;
014    import aterm.ATerm;
015    import aterm.ATermAppl;
016    import aterm.ATermFactory;
017    import aterm.ATermList;
018    import aterm.ATermPlaceholder;
019    import aterm.pure.PureFactory;
020    
021    public class JavaTif{
022            private ATermList tifs = null;
023            
024            private final ATermFactory factory;
025            
026            private final Map<ATermAppl, SpecOrderVector> doEvents;
027            private final Map<ATermAppl, SpecOrderVector> evalEvents;
028            private final Map<ATermAppl, SpecOrderVector> otherEvents;
029            private boolean hasRecAckEvent = false;
030            
031            private final String package_name;
032            private final String tool_interface;
033            private final String tool_class;
034            private final String tool_bridge;
035            private final boolean swingTool;
036            
037            static void usage(){
038                    System.err.println("usage: tifstojava" + " -tool <tool> -tifs <tifs> " + "[-class <class>] [-package <package>] [-swing]");
039                    System.exit(0);
040            }
041            
042            public static void main(String[] args) throws IOException{
043                    String tifsfile = null;
044                    String package_name = null, tool_interface = null, tool_class = null;
045                    String tool_bridge = null;
046                    boolean swingTool = false;
047                    String tool = null;
048                    
049                    for(int i = 0; i < args.length; i++){
050                            if(args[i].equals("-h")){
051                                    usage();
052                            }else if(args[i].equals("-tool")){
053                                    tool = args[++i];
054                            }else if(args[i].equals("-tifs")){
055                                    tifsfile = args[++i];
056                            }else if(args[i].equals("-package")){
057                                    package_name = args[++i];
058                            }else if(args[i].equals("-tool-interface")){
059                                    tool_interface = args[++i];
060                            }else if(args[i].equals("-tool-class")){
061                                    tool_class = args[++i];
062                            }else if(args[i].equals("-tool-bridge")){
063                                    tool_bridge = args[++i];
064                            }else if(args[i].equals("-swing")){
065                                    swingTool = true;
066                            }
067                    }
068                    
069                    if(tool == null || tifsfile == null){
070                            usage();
071                    }else{
072                            String tool_name = JavaTif.capitalize(tool, true);
073                            if(tool_interface == null){
074                                    tool_interface = tool_name + "Tif";
075                            }
076                            if(tool_class == null){
077                                    tool_class = tool_name + "Tool";
078                            }
079                            if(tool_bridge == null){
080                                    tool_bridge = tool_name + "Bridge";
081                            }
082                            
083                            JavaTif gen = new JavaTif(package_name, tool_interface, tool_class, tool_bridge, swingTool);
084                            gen.readTifs(tifsfile, tool);
085                            gen.genTif();
086                            gen.genTool();
087                            gen.genBridge();
088                    }
089            }
090            
091            public JavaTif(String pkg_name, String tool_interface, String tool_class, String tool_bridge, boolean swingTool){
092                    doEvents = new HashMap<ATermAppl, SpecOrderVector>();
093                    evalEvents = new HashMap<ATermAppl, SpecOrderVector>();
094                    otherEvents = new HashMap<ATermAppl, SpecOrderVector>();
095                    factory = new PureFactory();
096                    
097                    this.package_name = pkg_name;
098                    this.tool_interface = tool_interface;
099                    this.tool_class = tool_class;
100                    this.tool_bridge = tool_bridge;
101                    this.swingTool = swingTool;
102            }
103            
104            private void populateMap(ATermList signature){
105                    ATermList empty = factory.makeList();
106                    
107                    ATermList toolSignature = signature;
108                    while(toolSignature != empty){
109                            ATermAppl request = (ATermAppl) toolSignature.getFirst();
110                            
111                            if(request.getAFun().getArity() == 2 && request.getAFun().getName().startsWith("rec-")){
112                                    ATerm pattern = request.getArgument(1);
113                                    if(pattern instanceof ATermAppl){
114                                            ATermAppl appl = (ATermAppl) request.getArgument(1);
115                                            appl = normalize(appl);
116                                            SpecOrderVector specOrderVector = new SpecOrderVector();
117                                            specOrderVector.insert(appl);
118                                            
119                                            tifs = factory.makeList(request, tifs);
120                                            
121                                            if(request.getAFun().getName().equals("rec-do")){
122                                                    doEvents.put(appl, specOrderVector);
123                                            }else if(request.getAFun().getName().equals("rec-eval")){
124                                                    evalEvents.put(appl, specOrderVector);
125                                            }else if(request.getAFun().getName().equals("rec-ack-event")){
126                                                    hasRecAckEvent = true;
127                                            }else{
128                                                    otherEvents.put(appl, specOrderVector);
129                                            }
130                                    }
131                            }
132                            toolSignature = toolSignature.getNext();
133                    }
134            }
135            
136            private void populateMaps(ATermList inputSignature, ATermList outputSignature, ATermList otherSignature, String tool){
137                    tifs = factory.makeList();
138                    
139                    populateMap(inputSignature);
140                    populateMap(outputSignature);
141                    populateMap(otherSignature);
142                    
143                    ATermAppl recTerminate = (ATermAppl) factory.parse("rec-terminate(<"+tool+">, <term>)");
144                    tifs = factory.makeList(recTerminate, tifs);
145                    
146                    SpecOrderVector terminateSpecOrderVector = new SpecOrderVector();
147                    terminateSpecOrderVector.insert((ATermAppl) factory.parse("rec-terminate(<term>)"));
148                    otherEvents.put(recTerminate, terminateSpecOrderVector);
149                    
150                    if(hasRecAckEvent){
151                            ATermAppl recAckEvent = (ATermAppl) factory.parse("rec-ack-event(<"+tool+">, <term>)");
152                            tifs = factory.makeList(recAckEvent, tifs);
153                            
154                            SpecOrderVector ackEventSpecOrderVector = new SpecOrderVector();
155                            ackEventSpecOrderVector.insert((ATermAppl) factory.parse("rec-ack-event(<term>)"));
156                            otherEvents.put(recAckEvent, ackEventSpecOrderVector);
157                    }
158            }
159            
160            private static String capitalize(String str, boolean fc){
161                    boolean firstCap = fc;
162                    StringBuffer name = new StringBuffer();
163                    for(int i = 0; i < str.length(); i++){
164                            if(str.charAt(i) == '-')
165                                    firstCap = true;
166                            else{
167                                    if(firstCap){
168                                            name.append(Character.toUpperCase(str.charAt(i)));
169                                            firstCap = false;
170                                    }else name.append(str.charAt(i));
171                            }
172                    }
173                    return name.toString();
174            }
175            
176            private void readTifs(String tifsfile, String tool) throws IOException{
177                    ATermList empty = factory.makeList();
178                    ATermList allSignatures = (ATermList) factory.readFromFile(tifsfile);
179                    while(allSignatures != empty){
180                            ATermAppl toolSignature = (ATermAppl) allSignatures.getFirst();
181                            
182                            if(((ATermAppl) toolSignature.getArgument(0)).getAFun().getName().equals(tool)){
183                                    populateMaps((ATermList) toolSignature.getArgument(1), (ATermList) toolSignature.getArgument(2), (ATermList) toolSignature.getArgument(3), tool);
184                                    return;
185                            }
186                            
187                            allSignatures = allSignatures.getNext();
188                    }
189                    throw new RuntimeException("No tifs found for tool: "+tool);
190            }
191            
192            private void genTif() throws IOException{
193                    File path;
194                    if(package_name != null){
195                            path = new File(package_name.replaceAll("[.]", File.separator));
196                            path.mkdirs();
197                    }else{
198                            path = new File(".");
199                    }
200                    String filename = path + File.separator + tool_interface + ".java";
201                    
202                    System.out.println("generating file " + filename);
203                    PrintWriter out = new PrintWriter(new FileOutputStream(filename));
204                    genTifHeader(out);
205                    genMethods(out, false);
206                    out.println("}");
207                    out.close();
208            }
209            
210            private void genTifHeader(PrintWriter out){
211                    out.println("// Java tool interface " + tool_interface);
212                    out.println("// This file is generated automatically, please do not edit!");
213                    out.print("// generation time: ");
214                    out.println(DateFormat.getDateTimeInstance().format(new Date()));
215                    
216                    out.println();
217                    if(package_name != null){
218                            out.println("package " + package_name + ";");
219                    }
220                    out.println();
221                    out.println("import aterm.*;");
222                    out.println();
223                    out.println("public interface " + tool_interface + "{");
224            }
225            
226            private void genTool() throws IOException{
227                    File path;
228                    if(package_name != null){
229                            path = new File(package_name.replaceAll("[.]", File.separator));
230                            path.mkdirs();
231                    }else{
232                            path = new File(".");
233                    }
234                    String filename = path + File.separator + tool_class + ".java";
235                    
236                    System.out.println("generating file " + filename);
237                    
238                    PrintWriter out = new PrintWriter(new FileOutputStream(filename));
239                    genHeader(out);
240                    
241                    genSigTable(out);
242                    genPatternAttribs(out);
243                    out.println();
244                    
245                    genConstructor(out);
246                    out.println();
247                    
248                    genInitSigTable(out);
249                    out.println();
250                    genInitPatterns(out);
251                    out.println();
252                    
253                    genHandler(out);
254                    out.println();
255                    genCheckInputSignature(out);
256                    out.println();
257                    genNotInInputSignature(out);
258                    out.println("}");
259                    out.close();
260            }
261            
262            private void genSigTable(PrintWriter out){
263                    out.println("  // This table will hold the complete input signature");
264                    out.println("  private final Set<ATerm> sigTable = new HashSet<ATerm>();");
265                    out.println();
266            }
267            
268            private void genHeader(PrintWriter out){
269                    out.println("// Java tool interface class " + tool_class);
270                    out.println("// This file is generated automatically, please do not edit!");
271                    out.print("// generation time: ");
272                    out.println(DateFormat.getDateTimeInstance().format(new Date()));
273                    
274                    out.println();
275                    if(package_name != null){
276                            out.println("package " + package_name + ";");
277                    }
278                    out.println();
279                    out.println("import java.util.HashSet;");
280                    out.println("import java.util.List;");
281                    out.println("import java.util.Set;");
282                    out.println();
283                    if(swingTool){
284                            out.println("import toolbus.SwingTool;");
285                    }else{
286                            out.println("import toolbus.AbstractTool;");
287                    }
288                    out.println();
289                    out.println("import aterm.ATerm;");
290                    out.println("import aterm.ATermAppl;");
291                    out.println("import aterm.ATermFactory;");
292                    out.println("import aterm.ATermList;");
293                    out.println();
294                    out.print("abstract public class " + tool_class);
295                    if(swingTool){
296                            out.print(" extends SwingTool");
297                    }else{
298                            out.print(" extends AbstractTool");
299                    }
300                    out.print(" implements " + tool_interface);
301                    out.println("{");
302            }
303            
304            private void genPatternAttribs(PrintWriter out){
305                    out.println("  // Patterns that are used to match against incoming terms");
306                    
307                    Set<ATermAppl> eventKeys = doEvents.keySet();
308                    Iterator<ATermAppl> eventKeysIterator = eventKeys.iterator();
309                    while(eventKeysIterator.hasNext()){
310                            ATermAppl key = eventKeysIterator.next();
311                            SpecOrderVector v = doEvents.get(key);
312                            v.genPatternAttribs(out, capitalize(key.getName(), false));
313                    }
314                    
315                    Set<ATermAppl> evalKeys = evalEvents.keySet();
316                    Iterator<ATermAppl> evalKeysIterator = evalKeys.iterator();
317                    while(evalKeysIterator.hasNext()){
318                            ATermAppl key = evalKeysIterator.next();
319                            SpecOrderVector v = evalEvents.get(key);
320                            v.genPatternAttribs(out, capitalize(key.getName(), false));
321                    }
322                    
323                    Set<ATermAppl> otherEventsKeys = otherEvents.keySet();
324                    Iterator<ATermAppl> otherEventsKeysIterator = otherEventsKeys.iterator();
325                    while(otherEventsKeysIterator.hasNext()){
326                            ATermAppl key = otherEventsKeysIterator.next();
327                            SpecOrderVector v = otherEvents.get(key);
328                            v.genPatternAttribs(out, capitalize(key.getName(), false));
329                    }
330            }
331            
332            private void genConstructor(PrintWriter out){
333                    String decl = "protected " + tool_class + "(ATermFactory factory)";
334                    out.println("  // Mimic the constructor from the AbstractTool class");
335                    out.println("  " + decl);
336                    out.println("  {");
337                    out.println("    super(factory);");
338                    out.println("    initSigTable();");
339                    out.println("    initPatterns();");
340                    out.println("  }");
341            }
342            
343            private void genInitSigTable(PrintWriter out){
344                    String decl = "private void initSigTable()";
345                    out.println("  // This method initializes the table with input signatures");
346                    out.println("  " + decl);
347                    out.println("  {");
348                    ATermList sigs = tifs;
349                    while(!sigs.isEmpty()){
350                            ATerm sig = sigs.getFirst();
351                            sigs = sigs.getNext();
352                            out.print("    sigTable.add(factory.parse(\"");
353                            out.print(sig.toString());
354                            out.println("\"));");
355                    }
356                    out.println("  }");
357            }
358            
359            private void genInitPatterns(PrintWriter out){
360                    String decl = "private void initPatterns()";
361                    out.println("  // Initialize the patterns that are used to match against incoming terms");
362                    out.println("  " + decl);
363                    out.println("  {");
364                    
365                    Set<ATermAppl> eventKeys = doEvents.keySet();
366                    Iterator<ATermAppl> eventKeysIterator = eventKeys.iterator();
367                    while(eventKeysIterator.hasNext()){
368                            ATermAppl key = eventKeysIterator.next();
369                            SpecOrderVector v = doEvents.get(key);
370                            v.genPatterns(out, capitalize(key.getName(), false), "rec-do");
371                    }
372                    
373                    Set<ATermAppl> evalKeys = evalEvents.keySet();
374                    Iterator<ATermAppl> evalKeysIterator = evalKeys.iterator();
375                    while(evalKeysIterator.hasNext()){
376                            ATermAppl key = evalKeysIterator.next();
377                            SpecOrderVector v = evalEvents.get(key);
378                            v.genPatterns(out, capitalize(key.getName(), false), "rec-eval");
379                    }
380                    
381                    Set<ATermAppl> otherEventsKeys = otherEvents.keySet();
382                    Iterator<ATermAppl> otherEventsKeysIterator = otherEventsKeys.iterator();
383                    while(otherEventsKeysIterator.hasNext()){
384                            ATermAppl key = otherEventsKeysIterator.next();
385                            SpecOrderVector v = otherEvents.get(key);
386                            v.genPatterns(out, capitalize(key.getName(), false), null);
387                    }
388                    
389                    out.println("  }");
390            }
391            
392            private void genHandler(PrintWriter out){
393                    String decl = "public ATerm handler(ATerm term)";
394                    out.println("  // The generic handler calls the specific handlers");
395                    out.println("  " + decl);
396                    out.println("  {");
397                    out.println("    List<?> result;");
398                    out.println();
399                    
400                    Set<ATermAppl> eventKeys = doEvents.keySet();
401                    Iterator<ATermAppl> eventKeysIterator = eventKeys.iterator();
402                    while(eventKeysIterator.hasNext()){
403                            ATermAppl key = eventKeysIterator.next();
404                            SpecOrderVector v = doEvents.get(key);
405                            v.genCalls(out, capitalize(key.getName(), false), false);
406                    }
407                    
408                    Set<ATermAppl> evalKeys = evalEvents.keySet();
409                    Iterator<ATermAppl> evalKeysIterator = evalKeys.iterator();
410                    while(evalKeysIterator.hasNext()){
411                            ATermAppl key = evalKeysIterator.next();
412                            SpecOrderVector v = evalEvents.get(key);
413                            v.genCalls(out, capitalize(key.getName(), false), true);
414                    }
415                    
416                    Set<ATermAppl> otherEventsKeys = otherEvents.keySet();
417                    Iterator<ATermAppl> otherEventsKeysIterator = otherEventsKeys.iterator();
418                    while(otherEventsKeysIterator.hasNext()){
419                            ATermAppl key = otherEventsKeysIterator.next();
420                            SpecOrderVector v = otherEvents.get(key);
421                            v.genCalls(out, capitalize(key.getName(), false), false);
422                    }
423                    
424                    out.println();
425                    out.println("    notInInputSignature(term);");
426                    out.println("    return null;");
427                    out.println("  }");
428            }
429            
430            private void genMethods(PrintWriter out, boolean gen_impl){
431                    Set<ATermAppl> eventKeys = doEvents.keySet();
432                    Iterator<ATermAppl> eventKeysIterator = eventKeys.iterator();
433                    while(eventKeysIterator.hasNext()){
434                            ATermAppl key = eventKeysIterator.next();
435                            SpecOrderVector v = doEvents.get(key);
436                            v.genMethods(out, capitalize(key.getName(), false), false, gen_impl);
437                    }
438                    
439                    Set<ATermAppl> evalKeys = evalEvents.keySet();
440                    Iterator<ATermAppl> evalKeysIterator = evalKeys.iterator();
441                    while(evalKeysIterator.hasNext()){
442                            ATermAppl key = evalKeysIterator.next();
443                            SpecOrderVector v = evalEvents.get(key);
444                            v.genMethods(out, capitalize(key.getName(), false), true, gen_impl);
445                    }
446                    
447                    Set<ATermAppl> otherEventsKeys = otherEvents.keySet();
448                    Iterator<ATermAppl> otherEventsKeysIterator = otherEventsKeys.iterator();
449                    while(otherEventsKeysIterator.hasNext()){
450                            ATermAppl key = otherEventsKeysIterator.next();
451                            SpecOrderVector v = otherEvents.get(key);
452                            v.genMethods(out, capitalize(key.getName(), false), false, gen_impl);
453                    }
454            }
455            
456            private void genCheckInputSignature(PrintWriter out){
457                    String decl = "public void checkInputSignature(ATermList sigs)";
458                    out.println("  // Check the input signature");
459                    out.println("  " + decl);
460                    out.println("  {");
461                    out.println("    while(!sigs.isEmpty()) {");
462                    out.println("      ATermAppl sig = (ATermAppl)sigs.getFirst();");
463                    out.println("      sigs = sigs.getNext();");
464                    out.println("      if (!sigTable.contains(sig)) {");
465                    out.println("        // Sorry, but the term is not in the input signature!");
466                    out.println("        notInInputSignature(sig);");
467                    out.println("      }");
468                    out.println("    }");
469                    out.println("  }");
470            }
471            
472            private void genNotInInputSignature(PrintWriter out){
473                    String decl = "void notInInputSignature(ATerm t)";
474                    out.println("  // This function is called when an input term");
475                    out.println("  // was not in the input signature.");
476                    out.println("  " + decl);
477                    out.println("  {");
478                    out.println("    throw new RuntimeException(" + "\"term not in input signature: \" + t);");
479                    out.println("  }");
480            }
481            
482            private void genBridge() throws IOException{
483                    File path;
484                    if(package_name != null){
485                            path = new File(package_name.replaceAll("[.]", File.separator));
486                            path.mkdirs();
487                    }else{
488                            path = new File(".");
489                    }
490                    String filename = path + File.separator + tool_bridge + ".java";
491                    
492                    System.out.println("generating file " + filename);
493                    PrintWriter out = new PrintWriter(new FileOutputStream(filename));
494                    genBridgeHeader(out);
495                    
496                    out.println("  private final " + tool_interface + " tool;");
497                    out.println();
498                    String decl = "public " + tool_bridge + "(ATermFactory factory, " + tool_interface + " tool)";
499                    out.println("  " + decl + "{");
500                    out.println("    super(factory);");
501                    out.println("    this.tool = tool;");
502                    out.println("  }");
503                    out.println();
504                    
505                    genMethods(out, true);
506                    out.println("}");
507                    out.close();
508            }
509            
510            private void genBridgeHeader(PrintWriter out){
511                    out.println("// Java tool bridge " + tool_bridge);
512                    out.println("// This file is generated automatically, please do not edit!");
513                    out.print("// generation time: ");
514                    out.println(DateFormat.getDateTimeInstance().format(new Date()));
515                    
516                    out.println();
517                    if(package_name != null){
518                            out.println("package " + package_name + ";");
519                    }
520                    out.println();
521                    out.println("import aterm.*;");
522                    out.println();
523                    out.print("public class " + tool_bridge);
524                    out.print(" extends " + tool_class);
525                    out.println("{");
526            }
527            
528            private ATermAppl normalize(ATermAppl appl){
529                    ATermList args = appl.getArguments();
530                    int len = args.getLength();
531                    ATerm[] newargs = new ATerm[len];
532                    String type = null;
533                    
534                    for(int i = 0; i < len; i++){
535                            ATerm arg = args.getFirst();
536                            args = args.getNext();
537                            switch(arg.getType()){
538                                    case ATerm.APPL:
539                                            type = "<term>";
540                                            break;
541                                    case ATerm.INT:
542                                            type = "<int>";
543                                            break;
544                                    case ATerm.REAL:
545                                            type = "<real>";
546                                            break;
547                                    case ATerm.PLACEHOLDER:
548                                            type = arg.toString();
549                                            if(!type.equals("<int>") && !type.equals("<str>") && !type.equals("<real>")){
550                                                    type = "<term>";
551                                            }
552                                            // newargs[i] = arg;
553                                            break;
554                                    case ATerm.LIST:
555                                            type = "<term>";
556                                            break;
557                            }
558                            if(newargs[i] == null){
559                                    newargs[i] = factory.parse(type);
560                            }
561                    }
562                    return factory.makeAppl(appl.getAFun(), newargs);
563            }
564    }
565    
566    class SpecOrderVector extends ArrayList<ATermAppl>{
567            private static final long serialVersionUID = -864376275786608076L;
568    
569            public void insert(ATermAppl appl){
570                    for(int i = 0; i < size(); i++){
571                            if(moreSpecific(appl, get(i))){
572                                    add(i, appl);
573                                    return;
574                            }
575                    }
576                    add(appl);
577            }
578            
579            private boolean moreSpecific(ATerm a, ATerm b){
580                    if(a == b) return true;
581                    if(a.equals(b)) return true;
582                    if(a.getType() > b.getType()) return true;
583                    if(a.getType() < b.getType()) return false;
584                    switch(a.getType()){
585                            case ATerm.APPL:
586                                    ATermAppl appl1 = (ATermAppl) a;
587                                    ATermAppl appl2 = (ATermAppl) b;
588                                    if(appl1.getName().equals(appl2.getName())) return moreSpecific(appl1.getArguments(), appl2.getArguments());
589                                    if(moreSpecific(appl1.getName(), appl2.getName())) return true;
590                                    return false;
591                            case ATerm.PLACEHOLDER:
592                                    ATermPlaceholder p1 = (ATermPlaceholder) a;
593                                    ATermPlaceholder p2 = (ATermPlaceholder) b;
594                                    return moreSpecific(p1.getPlaceholder(), p2.getPlaceholder());
595                            case ATerm.LIST:
596                                    ATermList terms1 = (ATermList) a;
597                                    ATermList terms2 = (ATermList) b;
598                                    if(terms1.isEmpty()) return true;
599                                    if(terms2.isEmpty()) return false;
600                                    if(terms1.getFirst().equals(terms2.getFirst())) return moreSpecific(terms1.getNext(), terms2.getNext());
601                                    return moreSpecific(terms1.getFirst(), terms2.getFirst());
602                    }
603                    return false; // compiler!
604            }
605            
606            private boolean moreSpecific(String a, String b){
607                    int i;
608                    for(i = 0; i < a.length(); i++){
609                            if(i > b.length()) return true;
610                            if(a.charAt(i) < b.charAt(i)) return true;
611                    }
612                    return false;
613            }
614            
615            public void print(PrintWriter out){
616                    for(int i = 0; i < size(); i++){
617                            out.println(get(i).toString());
618                    }
619            }
620            
621            public void genPatterns(PrintWriter out, String base, String func){
622                    for(int i = 0; i < size(); i++){
623                            out.print("    P" + base + i + " = factory.parse(\"");
624                            if(func != null){
625                                    out.print(func + "(");
626                            }
627                            out.print(get(i).toString());
628                            if(func != null){
629                                    out.print(")");
630                            }
631                            out.println("\");");
632                    }
633            }
634            
635            public void genPatternAttribs(PrintWriter out, String base){
636                    for(int i = 0; i < size(); i++)
637                            out.println("  private ATerm P" + base + i + ";");
638            }
639            
640            public void genCalls(PrintWriter out, String base, boolean ret){
641                    for(int i = 0; i < size(); i++){
642                            ATermAppl appl = get(i);
643                            out.println("    result = term.match(P" + base + i + ");");
644                            out.println("    if (result != null) {");
645                            if(ret){
646                                    out.print("      return " + base + "(");
647                            }else{
648                                    out.print("      " + base + "(");
649                            }
650                            
651                            genArgs(out, appl.getArguments());
652                            out.println(");");
653                            if(!ret){
654                                    out.println("      return null;");
655                            }
656                            out.println("    }");
657                    }
658            }
659            
660            private static void genArgs(PrintWriter out, ATermList args){
661                    ATermList arguments = args;
662                    int idx = 0;
663                    
664                    while(!arguments.isEmpty()){
665                            ATermPlaceholder ph = (ATermPlaceholder) arguments.getFirst();
666                            String fun = ((ATermAppl) ph.getPlaceholder()).getName();
667                            arguments = arguments.getNext();
668                            if(fun.equals("int"))
669                                    out.print("((Integer) result.get(" + idx + ")).intValue()");
670                            else if(fun.equals("real"))
671                                    out.print("((Double) result.get(" + idx + ")).doubleValue()");
672                            else if(fun.equals("term"))
673                                    out.print("(ATerm) result.get(" + idx + ")");
674                            else if(fun.equals("appl"))
675                                    out.print("(ATermAppl) result.get(" + idx + ")");
676                            else if(fun.equals("list"))
677                                    out.print("(ATermList) result.get(" + idx + ")");
678                            else if(fun.equals("str"))
679                                    out.print("(String) result.get(" + idx + ")");
680                            else out.print("(ATermAppl) result.get(" + idx + ")");
681                            if(!arguments.isEmpty()) out.print(", ");
682                            idx++;
683                    }
684            }
685            
686            public void genMethods(PrintWriter out, String base, boolean ret, boolean gen_impl){
687                    for(int i = 0; i < size(); i++){
688                            ATermAppl appl = get(i);
689                            
690                            String decl;
691                            
692                            if(ret){
693                                    decl = "public ATerm " + base + "(";
694                            }else{
695                                    decl = "public void " + base + "(";
696                            }
697                            
698                            decl += buildFormals(appl.getArguments());
699                            decl += ")";
700                            
701                            out.print("  " + decl);
702                            
703                            if(gen_impl){
704                                    out.println("{");
705                                    out.print("    " + (ret ? "return " : "") + "tool." + base + "(");
706                                    genActuals(out, appl.getArguments());
707                                    out.println(");");
708                                    out.println("  }");
709                                    out.println();
710                            }else{
711                                    out.println(";");
712                            }
713                    }
714            }
715            
716            private static String buildFormals(ATermList args){
717                    ATermList arguments = args;
718                    int idx = 0;
719                    StringBuffer result = new StringBuffer();
720                    
721                    while(!arguments.isEmpty()){
722                            ATermPlaceholder ph = (ATermPlaceholder) arguments.getFirst();
723                            String fun = ((ATermAppl) ph.getPlaceholder()).getName();
724                            arguments = arguments.getNext();
725                            if(fun.equals("int")){
726                                    result.append("int i" + idx);
727                            }else if(fun.equals("real")){
728                                    result.append("double d" + idx);
729                            }else if(fun.equals("term")){
730                                    result.append("ATerm t" + idx);
731                            }else if(fun.equals("appl")){
732                                    result.append("ATermAppl a" + idx);
733                            }else if(fun.equals("list")){
734                                    result.append("ATermList l" + idx);
735                            }else if(fun.equals("str")){
736                                    result.append("String s" + idx);
737                            }else{
738                                    result.append("ATermAppl a" + idx);
739                            }
740                            
741                            if(!arguments.isEmpty()){
742                                    result.append(", ");
743                            }
744                            idx++;
745                    }
746                    
747                    return result.toString();
748            }
749            
750            private static void genActuals(PrintWriter out, ATermList args){
751                    ATermList arguments = args;
752                    int idx = 0;
753                    
754                    while(!arguments.isEmpty()){
755                            ATermPlaceholder ph = (ATermPlaceholder) arguments.getFirst();
756                            String fun = ((ATermAppl) ph.getPlaceholder()).getName();
757                            arguments = arguments.getNext();
758                            if(fun.equals("int")){
759                                    out.print("i" + idx);
760                            }else if(fun.equals("real")){
761                                    out.print("d" + idx);
762                            }else if(fun.equals("term")){
763                                    out.print("t" + idx);
764                            }else if(fun.equals("appl")){
765                                    out.print("a" + idx);
766                            }else if(fun.equals("list")){
767                                    out.print("l" + idx);
768                            }else if(fun.equals("str")){
769                                    out.print("s" + idx);
770                            }else{
771                                    out.print("a" + idx);
772                            }
773                            
774                            if(!arguments.isEmpty()){
775                                    out.print(", ");
776                            }
777                            idx++;
778                    }
779            }
780    }