dol: initial dol commit
[jump.git] / dol / src / dol / visitor / PipeAndFilter / PipeAndFilterModuleVisitor.java
diff --git a/dol/src/dol/visitor/PipeAndFilter/PipeAndFilterModuleVisitor.java b/dol/src/dol/visitor/PipeAndFilter/PipeAndFilterModuleVisitor.java
new file mode 100644 (file)
index 0000000..04d9f57
--- /dev/null
@@ -0,0 +1,311 @@
+/* $Id: PipeAndFilterModuleVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.PipeAndFilter;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.Resource;
+import dol.util.CodePrintStream;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * the main program.
+ */
+public class PipeAndFilterModuleVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     */
+    public PipeAndFilterModuleVisitor(String dir) {
+        _dir = dir;
+    }
+
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            String filename = _dir + _delimiter + "sc_application.cpp";
+            OutputStream file = new FileOutputStream(filename);
+            _code = new CodePrintStream(file);
+
+            _code.println("#include <iostream>");
+            _code.println();
+
+            _code.printPrefixln("#include \"lib/Fifo.h\"");
+            _code.printPrefixln("#include \"lib/Scheduler.h\"");
+            _code.printPrefixln("#include \"lib/WindowedFifo.h\"");
+            _code.println();
+            _code.printPrefixln("#include \"wrappers/wrappers.h\"");
+            _code.println();
+            _code.printPrefixln("#include \"processnetwork.h\"");
+            _code.println();
+            _code.printPrefixln("int main(void)");
+            _code.printLeftBracket();
+
+            _code.printPrefixln("std::map<std::string, "
+                    + "ProcessWrapper* > *processes");
+            _code.printPrefixln("        = new std::map<std::string, "
+                    + "ProcessWrapper* >();");
+            _code.println();
+
+            _code.printPrefixln("Scheduler *scheduler = "
+                    + "new Scheduler();");
+            _code.println();
+
+            //instantiate channels
+            for (Channel c : x.getChannelList()) {
+                if (c.getType().equals("fifo")) {
+                    printProcessNetwork("Fifo *" + c.getName()
+                        + " = new Fifo(\"" + c.getName()
+                        + "\", " + c.getSize() * c.getTokenSize()
+                        + ");");
+                } else if (c.getType().equals("wfifo")) {
+                    printProcessNetwork("WindowedFifo *" + c.getName()
+                            + " = new WindowedFifo(\"" + c.getName()
+                            + "\", " + c.getSize() * c.getTokenSize()
+                            + ");");
+                }
+            }
+            printProcessNetwork("");
+
+            // instantiate processes and connect to channels
+            for (Process p : x.getProcessList()) {
+                printProcessNetwork(p.getBasename() + "_wrapper *"
+                        + p.getName() + " = new "
+                        + p.getBasename() + "_wrapper(\""
+                        + p.getName() + "\");");
+                printProcessNetwork("processes->insert(std::pair"
+                        + "<std::string, ProcessWrapper* >(\""
+                        + p.getName() + "\", " + p.getName() + "));");
+                printProcessNetwork("");
+            }
+
+            //build the network
+            for (Channel ch : x.getChannelList()) {
+                ch.accept(this);
+            }
+
+            printProcessNetwork("}");
+
+            String headerfilename = _dir + _delimiter
+                     + "processnetwork.h";
+            OutputStream headerfile = new FileOutputStream(
+                     headerfilename);
+            CodePrintStream processnetworkHeader = new
+                     CodePrintStream(headerfile);
+            processnetworkHeader.printPrefixln(
+                     "#ifndef PROCESSNETWORK_H");
+            processnetworkHeader.printPrefixln(
+                    "#define PROCESSNETWORK_H");
+            processnetworkHeader.println();
+
+            for (int counter = 1; counter <= _processNetworkCounter;
+                    counter++) {
+                _code.printPrefixln("processnetwork_part"
+                        + String.format("%03d", counter) + "::create("
+                        + "processes);");
+                processnetworkHeader.println("#include "
+                        + "\"processnetwork_part"
+                        + String.format("%03d", counter) + ".h\"");
+            }
+            _code.println();
+
+            processnetworkHeader.println();
+            processnetworkHeader.printPrefixln("#endif");
+
+
+            //register processes
+            _code.printPrefixln("std::map<std::string, "
+                    + "ProcessWrapper* >::iterator process_iterator;");
+            _code.printPrefixln("for (process_iterator = "
+                   + "processes->begin();");
+            _code.printPrefixln("        process_iterator != "
+                   + "processes->end();");
+            _code.printPrefixln("        process_iterator++) {");
+            _code.printPrefixln("    scheduler->registerProcess("
+                   + "static_cast<ProcessWrapper* >");
+            _code.printPrefixln("        ((*process_iterator).second));");
+            _code.printPrefixln("}");
+            _code.println();
+
+            //run scheduler
+            _code.printPrefixln("scheduler->run();");
+            _code.println();
+
+            //clean up
+            _code.println();
+            _code.printPrefixln("for (process_iterator = "
+                    + "processes->begin();");
+            _code.printPrefixln("     process_iterator != "
+                    + "processes->end();");
+            _code.printPrefixln("     process_iterator++) {");
+            _code.printPrefixln("  delete static_cast<ProcessWrapper* >"
+                    + "((*process_iterator).second);");
+            _code.printPrefixln("}");
+            _code.println();
+            //_code.printPrefixln("std::cout << \"End.\" << std::endl;");
+            _code.printPrefixln("return 0;");
+            _code.printRightBracket();
+        }
+        catch (Exception e) {
+            System.out.println("PipeAndFilterModuleVisitor: "
+                    + "exception occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     */
+    protected void createProcessNetworkHeader(int part)
+            throws IOException {
+        String partString = String.format("%03d", part);
+        String filename = _dir + _delimiter + "processnetwork_part"
+                + partString + ".h";
+        OutputStream file = new FileOutputStream(filename);
+        CodePrintStream header = new CodePrintStream(file);
+
+        header.println("#ifndef PROCESSNETWORK_PART"
+                + partString + "_H");
+        header.println("#define PROCESSNETWORK_PART"
+                + partString + "_H");
+        header.println();
+        header.println("#include <map>");
+        header.println("#include <string>");
+        header.println();
+        header.println("#include \"lib/ProcessWrapper.h\"");
+        header.println("#include \"lib/Fifo.h\"");
+        header.println("#include \"lib/WindowedFifo.h\"");
+        header.println();
+        header.println("#include \"wrappers/wrappers.h\"");
+        header.println();
+        header.println("class processnetwork_part" + partString + " {");
+        header.println("    public:");
+        header.println("        processnetwork_part"
+                + partString + "();");
+        header.println("        virtual ~processnetwork_part"
+                + partString + "();");
+        header.println("        static void create(");
+        header.println("                std::map<std::string, "
+                + "ProcessWrapper* > *processes);");
+        header.println("};");
+        header.println();
+        header.println("#endif");
+    }
+
+
+    /**
+     *
+     */
+    protected void printProcessNetwork(String nextLine)
+            throws IOException {
+         if (!_fileOpen ||
+                (_numberOfLines >= MAX_NUMBER_OF_LINES &&
+                !nextLine.contains("->insert") &&
+                !nextLine.equals("") &&
+                !nextLine.contains("Port(") &&
+                !nextLine.contains("<std::string, Port* >"))) {
+
+            if (_fileOpen) {
+              _pn.printRightBracket();
+            }
+
+            _processNetworkCounter++;
+            _numberOfLines = 0;
+            createProcessNetworkHeader(_processNetworkCounter);
+            String partString = String.format("%03d",
+                    _processNetworkCounter);
+            String processNetworkFilename = _dir + _delimiter
+                    + "processnetwork_part" + partString + ".cpp";
+
+            _file = new FileOutputStream(processNetworkFilename);
+            _pn = new CodePrintStream(_file);
+            _fileOpen = true;
+
+            _pn.printPrefixln("#include \"processnetwork_part"
+                    + partString + ".h\"");
+            _pn.println();
+
+            _pn.printPrefixln("processnetwork_part" + partString
+                    + "::processnetwork_part" + partString + "() {");
+            _pn.printPrefixln("    //nothing to do");
+            _pn.printPrefixln("}");
+            _pn.println();
+            _pn.printPrefixln("processnetwork_part" + partString
+                    + "::~processnetwork_part" + partString + "() {");
+            _pn.printPrefixln("    //nothing to do");
+            _pn.printPrefixln("}");
+            _pn.println();
+            _pn.printPrefixln("void processnetwork_part" + partString
+                    + "::create(");
+            _pn.printPrefixln("        std::map<std::string, "
+                    + "ProcessWrapper* > *processes)");
+            _pn.printLeftBracket();
+        }
+
+        _pn.printPrefixln(nextLine);
+        _numberOfLines++;
+    }
+
+    /**
+     *
+     * @param x channel that needs to be rendered
+     */
+    public void visitComponent(Channel x) {
+        try {
+            for (Port p : x.getPortList()) {
+                Port peerPort = (Port)(p.getPeerPort());
+                Resource peerResource = p.getPeerResource();
+                String codeLine = "";
+                if (peerPort.getRange() != null) {
+                    if (p.isOutPort()) {
+                        codeLine = peerResource.getName()
+                                + "->INPORT_"
+                                + peerPort.getBasename()
+                                + peerPort.getName().replaceAll(
+                                "_([0-9]+)", "[$1]").replaceFirst(
+                                peerPort.getBasename(), "");
+                    }
+                    else if (p.isInPort()) {
+                        codeLine = peerResource.getName()
+                                + "->OUTPORT_"
+                                + peerPort.getBasename()
+                                + peerPort.getName().replaceAll(
+                                "_([0-9]+)", "[$1]").replaceFirst(
+                                peerPort.getBasename(), "");
+                    }
+                }
+                else {
+                    if (p.isOutPort()) {
+                        codeLine = peerResource.getName()
+                                + "->INPORT_" + peerPort.getName();
+                    }
+                    else if (p.isInPort()) {
+                        codeLine = peerResource.getName()
+                                + "->OUTPORT_" + peerPort.getName();
+                    }
+                }
+                printProcessNetwork(codeLine + " = " + x.getName() + ";");
+            }
+        }
+        catch (Exception e) {
+            System.out.println("PipeAndFilterModuleVisitor: "
+                    + "exception occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    protected CodePrintStream _code = null;
+    protected String _dir = null;
+    protected boolean _fileOpen = false;
+    protected int _processNetworkCounter = 0;
+    protected int _numberOfLines = 0;
+    protected static final int MAX_NUMBER_OF_LINES = 1000;
+    protected OutputStream _file;
+    protected CodePrintStream _pn;
+}
+