dol: initial dol commit
[jump.git] / dol / src / dol / visitor / yapi / YapiProcessVisitor.java
1 /* $Id: YapiProcessVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
2 package dol.visitor.yapi;
3
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.io.OutputStream;
7 import java.util.Vector;
8
9 import dol.datamodel.pn.Port;
10 import dol.datamodel.pn.Process;
11 import dol.datamodel.pn.ProcessNetwork;
12 import dol.datamodel.pn.SourceCode;
13 import dol.util.CodePrintStream;
14 import dol.util.Sed;
15 import dol.visitor.PNVisitor;
16
17 /**
18  *
19  */
20 public class YapiProcessVisitor extends PNVisitor {
21
22     /**
23      * Constructor.
24      */
25     public YapiProcessVisitor(String dir) {
26         _dir = dir;
27     }
28
29     /**
30     *
31     * @param x process network that needs to be rendered
32     */
33    public void visitComponent(ProcessNetwork x) {
34        try {
35            Vector<String> pList = new Vector<String>();
36
37            for (Process p : x.getProcessList()) {
38                String basename = p.getBasename();
39                if (!pList.contains(basename)) {
40                    pList.add(basename);
41                    p.accept(this);
42                }
43            }
44        }
45        catch (Exception e) {
46            System.out.println("Process Visitor: exception "
47                    + "occured: " + e.getMessage());
48            e.printStackTrace();
49        }
50    }
51
52    /**
53     *
54     * @param p process that needs to be rendered
55     */
56    public void visitComponent(Process p) {
57        try {
58            _createCppFile(p);
59            _createHeaderFile(p);
60            _adaptSources(p);
61        }
62        catch (Exception e) {
63            System.out.println("Process Visitor: exception "
64                    + "occured: " + e.getMessage());
65            e.printStackTrace();
66        }
67    }
68
69    /**
70     *
71     */
72    protected void _adaptSources(Process p) throws IOException {
73        Sed sed = new Sed();
74        for (Port port : p.getPortList()) {
75            String processHeaderFile;
76
77            for (SourceCode sr : p.getSrcList()) {
78                processHeaderFile = _dir + _delimiter + ".."
79                        + _delimiter + "processes" + _delimiter
80                        + sr.getLocality().
81                        replaceAll("(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
82
83                if (port.isOutPort()) {
84                    sed.sed(processHeaderFile,
85                            "(#define[ ]*PORT_\\w*[ ]*)\"?"
86                            + port.getBasename() + "\"?",
87                            "$1 " + "(const_cast<void *>((const void*)"
88                            +"(((static_cast<" + p.getBasename()
89                            + "_wrapper *>(p->wptr))->OUTPORT_"
90                            + port.getBasename() + "))))");
91                }
92                else if (port.isInPort()) {
93                    sed.sed(processHeaderFile,
94                            "(#define[ ]*PORT_\\w*[ ]*)\"?"
95                            + port.getBasename() + "\"?",
96                            "$1 " + "(const_cast<void *>((const void*)"
97                            +"(((static_cast<" + p.getBasename()
98                            + "_wrapper *>(p->wptr))->INPORT_"
99                            + port.getBasename() + "))))");
100                }
101            }
102        }
103    }
104    
105    /**
106     *
107     */
108    protected void _createCppFile(Process p) throws IOException {
109        String filename = _dir + _delimiter + p.getBasename()
110                + "_wrapper.cpp";
111        OutputStream file = new FileOutputStream(filename);
112        CodePrintStream ps = new CodePrintStream(file);
113
114        String newline = System.getProperty("line.separator");
115        String code = "#include \"" + p.getBasename() + "_wrapper.h\""
116                + newline;
117        code += "#include \"dolSupport.h\"" + newline;
118        for (SourceCode sr : p.getSrcList()) {
119            code += "#include \"" + sr.getLocality() + "\"" + newline;
120        }
121        
122        code += newline;
123
124        code += p.getBasename() + "_wrapper::" + p.getBasename()
125                + "_wrapper(const char* name, const Id& n";
126        for (Port port : p.getPortList()) {
127            if (port.isInPort()) {
128                code += ", In<char>& inport_" + port.getName();
129            } else {
130                code += ", Out<char>& outport_" + port.getName();
131            }
132        }
133        code += ")" + newline;
134
135        code += " : ProcessWrapper(name, n)" + newline;
136        code += " {" + newline;
137        code += "    _state = (LocalState)new "
138                + p.getBasename().substring(0, 1).toUpperCase()
139                + p.getBasename().substring(1) + "_State;"
140                + newline;
141        code += "    _process.local = _state;"  + newline; 
142        code += "    _process.init = " + p.getBasename() + "_init;"
143                + newline;
144        code += "    _process.fire = " + p.getBasename() + "_fire;"
145                + newline;
146        code += "    _process.wptr = this;" + newline;
147        for (Port port : p.getPortList()) {
148            if (!port.getRange().equals("")) {
149                String portName =
150                    port.getName().replaceAll("_([0-9])", "][$1");
151                portName += "]";
152                portName = portName.replaceFirst("]", "");
153                if (port.isOutPort()) {
154                    code += "    OUTPORT_" + portName
155                            + " = new OutPort<char>(id(\"" + port.getName()
156                            + "\"), outport_" + port.getName() + ");"
157                            + newline;
158                }
159                else if (port.isInPort()) {
160                    code += "    INPORT_" + portName
161                            + " = new InPort<char>(id(\"" + port.getName()
162                            + "\"), inport_" + port.getName() + ");"
163                            + newline;
164                }
165            } else {
166                if (port.isInPort()) {
167                    code += "    INPORT_" + port.getName()
168                            + " = new InPort<char>(id(\"" + port.getName()
169                            + "\"), inport_" + port.getName() + ");"
170                            + newline;
171                } else {
172                    code += "    OUTPORT_" + port.getName()
173                            + " = new OutPort<char>(id(\"" + port.getName()
174                            + "\"), outport_" + port.getName() + ");"
175                            + newline;
176                }
177            }
178        }
179        code += "}" + newline + newline;
180
181        code += p.getBasename() + "_wrapper::~" + p.getBasename()
182                + "_wrapper() {" + newline;
183        code += "    if (_state)" + newline;
184        code += "        delete ("
185                + p.getBasename().substring(0, 1).toUpperCase()
186                + p.getBasename().substring(1) + "_State*)_state;"
187                + newline;
188        for (Port port : p.getPortList()) {
189            if (!port.getRange().equals("")) {
190                String portName =
191                    port.getName().replaceAll("_([0-9])", "][$1");
192                portName += "]";
193                portName = portName.replaceFirst("]", "");
194                if (port.isOutPort()) {
195                    code += "    if (OUTPORT_" + portName + ")" + newline;
196                    code += "        delete OUTPORT_" + portName + ";"
197                            + newline;
198                }
199                else if (port.isInPort()) {
200                    code += "    if (INPORT_" + portName + ")" + newline;
201                    code += "        delete INPORT_" + portName + ";"
202                            + newline;
203                }
204            } else {
205                if (port.isInPort()) {
206                    code += "    if(INPORT_" + port.getName() + ")"
207                            + newline;
208                    code += "        delete INPORT_" + port.getName() + ";"
209                            + newline;
210                } else {
211                    code += "    if(OUTPORT_" + port.getName() + ")"
212                            + newline;
213                    code += "        delete OUTPORT_" + port.getName() + ";"
214                            + newline;
215                }
216            }
217        }
218        code += "}" + newline + newline;
219        
220        code += "const char* "
221                + p.getBasename() + "_wrapper::type() const {" + newline;
222        code += "    return \"" + p.getName() + "\";" + newline;
223        code += "}" + newline + newline;
224
225        code += "void " + p.getBasename() + "_wrapper::main() {" + newline;
226        code += "    _process.init(&_process);" + newline;
227        code += "    while(!isDetached()) {" + newline;
228        code += "        _process.fire(&_process);" + newline;
229        code += "    }" + newline;
230        code += "}" + newline;
231        ps.printPrefixln(code);
232    }
233
234    protected void _createHeaderFile(Process p)
235        throws IOException {
236        String filename = _dir + _delimiter + p.getBasename()
237                + "_wrapper.h";
238        OutputStream file = new FileOutputStream(filename);
239        CodePrintStream ps = new CodePrintStream(file);
240
241        String newline = System.getProperty("line.separator");
242        String code = "#ifndef " + p.getBasename() + "_WRAPPER_H"
243                + newline;
244        code += "#define " + p.getBasename() + "_WRAPPER_H" + newline
245                + newline;
246        code += "#include \"ProcessWrapper.h\"" + newline; 
247        code += newline;
248
249        code += "class " + p.getBasename() + "_wrapper : "
250                + "public ProcessWrapper {" + newline;
251        code += "    public:" + newline;
252        code += "        " + p.getBasename()
253                + "_wrapper(const char* name, const Id& n";
254        for (Port port : p.getPortList()) {
255            if (port.isInPort()) {
256                code += ", In<char>& inport_" + port.getName();
257            } else {
258                code += ", Out<char>& outport_" + port.getName();
259            }
260        }
261        code += ");" + newline;
262        code += "        virtual ~" + p.getBasename() + "_wrapper();"
263                + newline;
264        code += "        const char* type() const;" + newline;
265        code += "        void main();" + newline + newline;
266
267        Vector<String> portList = new Vector<String>();
268        for (Port port : p.getPortList()) {
269            String basename = port.getBasename();
270
271            if (!portList.contains(basename)) {
272                portList.add(basename);
273
274                if (!port.getRange().equals("")) {
275                    if (port.isOutPort()) {
276                        code += "        OutPort<char> *OUTPORT_"
277                                + port.getBasename() + "["
278                                + port.getRange().replaceAll(
279                                ";", "\\]\\[") + "];" + newline;
280                    }
281                    else if (port.isInPort()) {
282                        code += "        InPort<char> *INPORT_"
283                                + port.getBasename() + "["
284                                + port.getRange().replaceAll(
285                                ";", "\\]\\[") + "];" + newline;
286                    }
287                }
288                else {
289                    if (port.isOutPort()) {
290                        code += "        OutPort<char> *OUTPORT_"
291                                + port.getName() + ";" + newline;
292                    }
293                    else if (port.isInPort()) {
294                        code += "        InPort<char> *INPORT_"
295                                + port.getName() + ";" + newline;
296                    }
297                }
298            }
299        }
300        code += newline;
301        code += "    protected:" + newline;
302        code += "        LocalState _state;" + newline;
303        code += "};" + newline + newline;
304        code += "#endif";
305        ps.printPrefixln(code);
306    }
307
308    protected String _dir = null;
309 }