1 /* $Id: ProtothreadProcessVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
2 package dol.visitor.protothread;
4 import java.io.BufferedReader;
5 import java.io.BufferedWriter;
6 import java.io.FileInputStream;
7 import java.io.FileOutputStream;
8 import java.io.FileWriter;
9 import java.io.IOException;
10 import java.io.InputStreamReader;
11 import java.io.OutputStream;
12 import java.util.StringTokenizer;
13 import java.util.Vector;
14 import java.util.regex.Matcher;
15 import java.util.regex.Pattern;
17 import dol.datamodel.pn.Channel;
18 import dol.datamodel.pn.Port;
19 import dol.datamodel.pn.Process;
20 import dol.datamodel.pn.ProcessNetwork;
21 import dol.datamodel.pn.SourceCode;
22 import dol.util.CodePrintStream;
24 import dol.visitor.PNVisitor;
29 public class ProtothreadProcessVisitor extends PNVisitor {
34 public ProtothreadProcessVisitor(String dir) {
41 public void visitComponent(ProcessNetwork x) {
43 Vector<String> processList = new Vector<String>();
44 for (Process p : x.getProcessList()) {
45 String basename = p.getBasename();
46 if (!processList.contains(basename)) {
47 processList.add(basename);
51 } catch (Exception e) {
52 System.out.println("Process Visitor: exception " +
53 "occured: " + e.getMessage());
61 public void visitComponent(Process p) {
68 System.out.println("Process Visitor: exception "
69 + "occured: " + e.getMessage());
77 private void _createCppFile(Process p)
79 String classname = p.getBasename() + "Wrapper";
80 String filename = _dir + _delimiter + classname + ".cpp";
81 OutputStream file = new FileOutputStream(filename);
82 CodePrintStream ps = new CodePrintStream(file);
84 ps.printPrefixln("#include \"" + classname + ".h\"");
85 ps.printPrefixln("#include \"dolSupport.h\"");
86 ps.printPrefixln("#include <string.h>");
88 for (SourceCode sr : p.getSrcList()) {
89 ps.printPrefixln("#include \"" + "../processes/"
90 + sr.getLocality() + "\"");
93 ps.printPrefixln(classname + "::" + classname
94 + "(char* name, int iteratorIndex[4]) :");
95 ps.printPrefixln(" ProcessWrapper(name, iteratorIndex)");
96 ps.printLeftBracket();
97 //ps.printPrefixln("_state = new struct _local_states;");
98 //ps.printPrefixln("memcpy(_state, " + p.getBasename() + ".local, "
99 // + "sizeof(struct _local_states));");
100 //ps.printPrefixln("memcpy(&_process, &" + p.getBasename()
101 // + ", sizeof(DOLProcess));");
102 ps.printPrefixln("_state = (LocalState)new "
103 + p.getBasename().substring(0, 1).toUpperCase()
104 + p.getBasename().substring(1) + "_State;");
105 ps.printPrefixln("_process.init = " + p.getBasename() + "_init;");
106 ps.printPrefixln("_process.fire = " + p.getBasename() + "_fire;");
107 ps.printPrefixln("_process.local = _state;");
108 ps.printPrefixln("_process.wptr = (void*)&_wrapper_data;");
109 ps.printPrefixln("_wrapper_data.wrapper = this;");
110 ps.printRightBracket();
112 ps.printPrefixln(classname + "::~" + classname + "()");
113 ps.printLeftBracket();
114 ps.printPrefixln("if (_state)");
115 ps.printPrefixln(" delete ("
116 + p.getBasename().substring(0, 1).toUpperCase()
117 + p.getBasename().substring(1) + "_State*)_state;");
118 //ps.printPrefixln(" delete _state;");
119 ps.printRightBracket();
125 private void _createHeaderFile(Process p)
127 String classname = p.getBasename() + "Wrapper";
128 String filename = _dir + _delimiter + classname + ".h";
129 OutputStream file = new FileOutputStream(filename);
130 CodePrintStream ps = new CodePrintStream(file);
132 ps.printPrefixln("#ifndef " + classname.toUpperCase()
134 ps.printPrefixln("#define " + classname.toUpperCase()
137 ps.printPrefixln("#include \"ProcessWrapper.h\"");
138 ps.printPrefixln("#include \"Fifo.h\"");
139 ps.printPrefixln("#include \"WindowedFifo.h\"");
141 ps.printPrefixln("class " + classname + ";");
143 ps.printPrefixln("typedef struct _" + p.getBasename()
145 ps.printPrefixln(" int lc;");
146 ps.printPrefixln(" " + classname + " *wrapper;");
147 ps.printPrefixln("} " + p.getBasename() + "_data;");
149 ps.printPrefixln("class " + classname +
150 " : public ProcessWrapper");
151 ps.printLeftBracket();
152 ps.printPrefixln("public:");
153 ps.printPrefixln(" " + classname + "(char* name, "
154 + "int iteratorIndex[4]);");
155 ps.printPrefixln(" virtual ~" + classname + "();");
158 Vector<String> basenames = new Vector<String>();
159 for (Port port : p.getPortList()) {
160 if (!basenames.contains(port.getBasename())) {
161 basenames.add(port.getBasename());
166 Channel c = (Channel)port.getPeerResource();
167 if (port.getName().equals(port.getBasename())) {
168 if (c.getType().equals("fifo")) {
169 ps.printPrefixln(" Fifo* _port" + port.getName()
171 } else if (c.getType().equals("wfifo")) {
172 ps.printPrefixln(" WindowedFifo* _port"
173 + port.getName() + "Fifo;");
176 if (c.getType().equals("fifo")) {
177 ps.printPrefix(" Fifo* _port"
180 } else if (c.getType().equals("wfifo")) {
181 ps.printPrefix(" WindowedFifo* _port"
185 StringTokenizer tokenizer =
186 new StringTokenizer(port.getRange(), ";");
187 while (tokenizer.hasMoreTokens()) {
188 ps.print("[" + tokenizer.nextToken()
195 ps.printPrefixln("protected:");
196 ps.printPrefixln(" struct _local_states *_state;");
197 ps.printPrefixln(" " + p.getBasename()
198 + "_data _wrapper_data;");
199 ps.printRightBracket();
201 ps.printPrefixln(";");
203 ps.printPrefixln("#endif");
207 * Make modifications to source files of a process.
208 * Port names need to be strings for the SystemC code generation.
209 * Therefore, in the header files integer port names are put into
212 * @param p process whose sources should be adapted
213 * @throws IOException
215 protected void _adaptSources(Process p) throws IOException {
218 for (Port port : p.getPortList()) {
219 String processHeaderFile;
221 for (SourceCode sr : p.getSrcList()) {
222 processHeaderFile = _dir + _delimiter + ".."
223 + _delimiter + "processes" + _delimiter
225 replaceAll("(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
227 sed.sed(processHeaderFile,
228 "(#define[ ]+PORT_\\w*[ ]+)\"?"
229 + port.getBasename() + "\"?",
230 "$1 " + "static_cast<" + p.getBasename()
231 + "Wrapper *>((static_cast<" + p.getBasename()
232 + "_data *>(p->wptr))->wrapper)->_port"
233 + port.getBasename() + "Fifo");
238 for (SourceCode sr : p.getSrcList()) {
239 String processSourceFile = _dir + _delimiter + ".."
240 + _delimiter + "processes" + _delimiter
244 StringBuffer buffer = new StringBuffer();
245 FileInputStream fileInputStream = new FileInputStream(
247 BufferedReader reader = new BufferedReader(
248 new InputStreamReader(fileInputStream));
249 while((line = reader.readLine()) != null) {
250 buffer.append(line + "\n");
254 String file = buffer.toString();
255 //insert PT_BEGIN() at beginning of fire() function
256 file = file.replaceAll(
257 "(int[ ]*" + p.getBasename()
258 + "_fire[ ]*\\([ ]*DOLProcess[ ]*\\*p[ ]*\\)"
259 + "[\\s\\S&&[^\\{]]*)\\{",
260 "$1" + System.getProperty("line.separator") + "{"
261 + System.getProperty("line.separator") +
262 " PT_BEGIN((pt*)(p->wptr));");
264 //replace last return statement in fire function by PT_END()
265 //find beginning of fire function
266 Matcher matcher = Pattern.compile(
267 "(int[ ]*" + p.getBasename()
268 + "_fire[ ]*\\([ ]*DOLProcess[ ]*\\*p[ ]*\\)"
269 + "[\\s\\S&&[^\\{]]*)\\{").matcher(file);
274 } catch (Exception e) {
275 System.out.println("Error: could not find "
276 + p.getBasename() + "_fire() function in "
277 + processSourceFile + ".");
280 int openBraces = 0; //counter for open curly braces
281 //position of last return statement
282 int lastReturnStartPosition = 0;
283 int lastReturnEndPosition = 0;
284 while (i < file.length()) {
285 //ignore single-line comments
286 if (i < (file.length() - 1) &&
287 file.substring(i, i + 2).equals("//")) {
288 while (!file.substring(i, i + 1).equals("\n")) {
292 //ignore multi-line comments
293 else if (i < (file.length() - 1) &&
294 file.substring(i, i + 2).equals("/*")) {
295 while (!file.substring(i, i + 2).equals("*/")) {
300 else if (file.substring(i, i + 1).equals("\"")) {
301 matcher = Pattern.compile("[\\s\\S&&[^\\\\]]\\\"").
304 i = matcher.start() + 1;
306 else if (i < (file.length() - 5) &&
307 file.substring(i, i + 6).equals("return")) {
308 lastReturnStartPosition = i;
309 while (!file.substring(i, i + 1).equals(";")) {
312 lastReturnEndPosition = i;
313 } else if (file.substring(i, i + 1).equals("{")) {
315 } else if (file.substring(i, i + 1).equals("}")) {
317 if (openBraces == 0) {
324 file = file.substring(0, lastReturnStartPosition) + "/* "
325 + file.substring(lastReturnStartPosition,
326 lastReturnEndPosition + 1)
327 + " (commented out by DOL) */"
328 + System.getProperty("line.separator")
329 + " PT_END((pt*)(p->wptr));"
330 + System.getProperty("line.separator")
331 + file.substring(lastReturnEndPosition + 2,
334 BufferedWriter out = new BufferedWriter(new
335 FileWriter(processSourceFile));
341 protected String _dir = null;
342 CodePrintStream _wrapperHeader;