dol: initial dol commit
[jump.git] / dol / src / dol / visitor / PipeAndFilter / PipeAndFilterModuleVisitor.java
1 /* $Id: PipeAndFilterModuleVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
2 package dol.visitor.PipeAndFilter;
3
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.io.OutputStream;
7
8 import dol.datamodel.pn.Channel;
9 import dol.datamodel.pn.Port;
10 import dol.datamodel.pn.Process;
11 import dol.datamodel.pn.ProcessNetwork;
12 import dol.datamodel.pn.Resource;
13 import dol.util.CodePrintStream;
14 import dol.visitor.PNVisitor;
15
16 /**
17  * This class is a class for a visitor that is used to generate
18  * the main program.
19  */
20 public class PipeAndFilterModuleVisitor extends PNVisitor {
21
22     /**
23      * Constructor.
24      */
25     public PipeAndFilterModuleVisitor(String dir) {
26         _dir = dir;
27     }
28
29     public void visitComponent(ProcessNetwork x) {
30         try {
31             String filename = _dir + _delimiter + "sc_application.cpp";
32             OutputStream file = new FileOutputStream(filename);
33             _code = new CodePrintStream(file);
34
35             _code.println("#include <iostream>");
36             _code.println();
37
38             _code.printPrefixln("#include \"lib/Fifo.h\"");
39             _code.printPrefixln("#include \"lib/Scheduler.h\"");
40             _code.printPrefixln("#include \"lib/WindowedFifo.h\"");
41             _code.println();
42             _code.printPrefixln("#include \"wrappers/wrappers.h\"");
43             _code.println();
44             _code.printPrefixln("#include \"processnetwork.h\"");
45             _code.println();
46             _code.printPrefixln("int main(void)");
47             _code.printLeftBracket();
48
49             _code.printPrefixln("std::map<std::string, "
50                     + "ProcessWrapper* > *processes");
51             _code.printPrefixln("        = new std::map<std::string, "
52                     + "ProcessWrapper* >();");
53             _code.println();
54
55             _code.printPrefixln("Scheduler *scheduler = "
56                     + "new Scheduler();");
57             _code.println();
58
59             //instantiate channels
60             for (Channel c : x.getChannelList()) {
61                 if (c.getType().equals("fifo")) {
62                     printProcessNetwork("Fifo *" + c.getName()
63                         + " = new Fifo(\"" + c.getName()
64                         + "\", " + c.getSize() * c.getTokenSize()
65                         + ");");
66                 } else if (c.getType().equals("wfifo")) {
67                     printProcessNetwork("WindowedFifo *" + c.getName()
68                             + " = new WindowedFifo(\"" + c.getName()
69                             + "\", " + c.getSize() * c.getTokenSize()
70                             + ");");
71                 }
72             }
73             printProcessNetwork("");
74
75             // instantiate processes and connect to channels
76             for (Process p : x.getProcessList()) {
77                 printProcessNetwork(p.getBasename() + "_wrapper *"
78                         + p.getName() + " = new "
79                         + p.getBasename() + "_wrapper(\""
80                         + p.getName() + "\");");
81                 printProcessNetwork("processes->insert(std::pair"
82                         + "<std::string, ProcessWrapper* >(\""
83                         + p.getName() + "\", " + p.getName() + "));");
84                 printProcessNetwork("");
85             }
86
87             //build the network
88             for (Channel ch : x.getChannelList()) {
89                 ch.accept(this);
90             }
91
92             printProcessNetwork("}");
93
94             String headerfilename = _dir + _delimiter
95                      + "processnetwork.h";
96             OutputStream headerfile = new FileOutputStream(
97                      headerfilename);
98             CodePrintStream processnetworkHeader = new
99                      CodePrintStream(headerfile);
100             processnetworkHeader.printPrefixln(
101                      "#ifndef PROCESSNETWORK_H");
102             processnetworkHeader.printPrefixln(
103                     "#define PROCESSNETWORK_H");
104             processnetworkHeader.println();
105
106             for (int counter = 1; counter <= _processNetworkCounter;
107                     counter++) {
108                 _code.printPrefixln("processnetwork_part"
109                         + String.format("%03d", counter) + "::create("
110                         + "processes);");
111                 processnetworkHeader.println("#include "
112                         + "\"processnetwork_part"
113                         + String.format("%03d", counter) + ".h\"");
114             }
115             _code.println();
116
117             processnetworkHeader.println();
118             processnetworkHeader.printPrefixln("#endif");
119
120
121             //register processes
122             _code.printPrefixln("std::map<std::string, "
123                     + "ProcessWrapper* >::iterator process_iterator;");
124             _code.printPrefixln("for (process_iterator = "
125                    + "processes->begin();");
126             _code.printPrefixln("        process_iterator != "
127                    + "processes->end();");
128             _code.printPrefixln("        process_iterator++) {");
129             _code.printPrefixln("    scheduler->registerProcess("
130                    + "static_cast<ProcessWrapper* >");
131             _code.printPrefixln("        ((*process_iterator).second));");
132             _code.printPrefixln("}");
133             _code.println();
134
135             //run scheduler
136             _code.printPrefixln("scheduler->run();");
137             _code.println();
138
139             //clean up
140             _code.println();
141             _code.printPrefixln("for (process_iterator = "
142                     + "processes->begin();");
143             _code.printPrefixln("     process_iterator != "
144                     + "processes->end();");
145             _code.printPrefixln("     process_iterator++) {");
146             _code.printPrefixln("  delete static_cast<ProcessWrapper* >"
147                     + "((*process_iterator).second);");
148             _code.printPrefixln("}");
149             _code.println();
150             //_code.printPrefixln("std::cout << \"End.\" << std::endl;");
151             _code.printPrefixln("return 0;");
152             _code.printRightBracket();
153         }
154         catch (Exception e) {
155             System.out.println("PipeAndFilterModuleVisitor: "
156                     + "exception occured: " + e.getMessage());
157             e.printStackTrace();
158         }
159     }
160
161     /**
162      *
163      */
164     protected void createProcessNetworkHeader(int part)
165             throws IOException {
166         String partString = String.format("%03d", part);
167         String filename = _dir + _delimiter + "processnetwork_part"
168                 + partString + ".h";
169         OutputStream file = new FileOutputStream(filename);
170         CodePrintStream header = new CodePrintStream(file);
171
172         header.println("#ifndef PROCESSNETWORK_PART"
173                 + partString + "_H");
174         header.println("#define PROCESSNETWORK_PART"
175                 + partString + "_H");
176         header.println();
177         header.println("#include <map>");
178         header.println("#include <string>");
179         header.println();
180         header.println("#include \"lib/ProcessWrapper.h\"");
181         header.println("#include \"lib/Fifo.h\"");
182         header.println("#include \"lib/WindowedFifo.h\"");
183         header.println();
184         header.println("#include \"wrappers/wrappers.h\"");
185         header.println();
186         header.println("class processnetwork_part" + partString + " {");
187         header.println("    public:");
188         header.println("        processnetwork_part"
189                 + partString + "();");
190         header.println("        virtual ~processnetwork_part"
191                 + partString + "();");
192         header.println("        static void create(");
193         header.println("                std::map<std::string, "
194                 + "ProcessWrapper* > *processes);");
195         header.println("};");
196         header.println();
197         header.println("#endif");
198     }
199
200
201     /**
202      *
203      */
204     protected void printProcessNetwork(String nextLine)
205             throws IOException {
206          if (!_fileOpen ||
207                 (_numberOfLines >= MAX_NUMBER_OF_LINES &&
208                 !nextLine.contains("->insert") &&
209                 !nextLine.equals("") &&
210                 !nextLine.contains("Port(") &&
211                 !nextLine.contains("<std::string, Port* >"))) {
212
213             if (_fileOpen) {
214               _pn.printRightBracket();
215             }
216
217             _processNetworkCounter++;
218             _numberOfLines = 0;
219             createProcessNetworkHeader(_processNetworkCounter);
220             String partString = String.format("%03d",
221                     _processNetworkCounter);
222             String processNetworkFilename = _dir + _delimiter
223                     + "processnetwork_part" + partString + ".cpp";
224
225             _file = new FileOutputStream(processNetworkFilename);
226             _pn = new CodePrintStream(_file);
227             _fileOpen = true;
228
229             _pn.printPrefixln("#include \"processnetwork_part"
230                     + partString + ".h\"");
231             _pn.println();
232
233             _pn.printPrefixln("processnetwork_part" + partString
234                     + "::processnetwork_part" + partString + "() {");
235             _pn.printPrefixln("    //nothing to do");
236             _pn.printPrefixln("}");
237             _pn.println();
238             _pn.printPrefixln("processnetwork_part" + partString
239                     + "::~processnetwork_part" + partString + "() {");
240             _pn.printPrefixln("    //nothing to do");
241             _pn.printPrefixln("}");
242             _pn.println();
243             _pn.printPrefixln("void processnetwork_part" + partString
244                     + "::create(");
245             _pn.printPrefixln("        std::map<std::string, "
246                     + "ProcessWrapper* > *processes)");
247             _pn.printLeftBracket();
248         }
249
250         _pn.printPrefixln(nextLine);
251         _numberOfLines++;
252     }
253
254     /**
255      *
256      * @param x channel that needs to be rendered
257      */
258     public void visitComponent(Channel x) {
259         try {
260             for (Port p : x.getPortList()) {
261                 Port peerPort = (Port)(p.getPeerPort());
262                 Resource peerResource = p.getPeerResource();
263                 String codeLine = "";
264                 if (peerPort.getRange() != null) {
265                     if (p.isOutPort()) {
266                         codeLine = peerResource.getName()
267                                 + "->INPORT_"
268                                 + peerPort.getBasename()
269                                 + peerPort.getName().replaceAll(
270                                 "_([0-9]+)", "[$1]").replaceFirst(
271                                 peerPort.getBasename(), "");
272                     }
273                     else if (p.isInPort()) {
274                         codeLine = peerResource.getName()
275                                 + "->OUTPORT_"
276                                 + peerPort.getBasename()
277                                 + peerPort.getName().replaceAll(
278                                 "_([0-9]+)", "[$1]").replaceFirst(
279                                 peerPort.getBasename(), "");
280                     }
281                 }
282                 else {
283                     if (p.isOutPort()) {
284                         codeLine = peerResource.getName()
285                                 + "->INPORT_" + peerPort.getName();
286                     }
287                     else if (p.isInPort()) {
288                         codeLine = peerResource.getName()
289                                 + "->OUTPORT_" + peerPort.getName();
290                     }
291                 }
292                 printProcessNetwork(codeLine + " = " + x.getName() + ";");
293             }
294         }
295         catch (Exception e) {
296             System.out.println("PipeAndFilterModuleVisitor: "
297                     + "exception occured: " + e.getMessage());
298             e.printStackTrace();
299         }
300     }
301
302     protected CodePrintStream _code = null;
303     protected String _dir = null;
304     protected boolean _fileOpen = false;
305     protected int _processNetworkCounter = 0;
306     protected int _numberOfLines = 0;
307     protected static final int MAX_NUMBER_OF_LINES = 1000;
308     protected OutputStream _file;
309     protected CodePrintStream _pn;
310 }
311