005397e5c68b200c9ab244ea583dfa894e54a042
[cdsspec-compiler.git] / src / edu / uci / eecs / codeGenerator / CodeGeneratorUtils.java
1 package edu.uci.eecs.codeGenerator;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.HashSet;
6 import java.util.regex.Matcher;
7 import java.util.regex.Pattern;
8 import java.io.BufferedWriter;
9 import java.io.File;
10 import java.io.FileWriter;
11 import java.io.IOException;
12
13 import edu.uci.eecs.specExtraction.Code;
14 import edu.uci.eecs.specExtraction.CommutativityRule;
15 import edu.uci.eecs.specExtraction.EntryConstruct;
16 import edu.uci.eecs.specExtraction.FunctionHeader;
17 import edu.uci.eecs.specExtraction.GlobalConstruct;
18 import edu.uci.eecs.specExtraction.InterfaceConstruct;
19 import edu.uci.eecs.specExtraction.OPConstruct;
20 import edu.uci.eecs.specExtraction.SpecExtractor;
21 import edu.uci.eecs.specExtraction.SpecNaming;
22 import edu.uci.eecs.specExtraction.VariableDeclaration;
23
24 /**
25  * <p>
26  * Some utility functions for generating specification checking code.
27  * </p>
28  * 
29  * @author Peizhao Ou
30  * 
31  */
32 public class CodeGeneratorUtils {
33
34         public static void PrintCode(ArrayList<String> code) {
35                 for (int i = 0; i < code.size(); i++) {
36                         System.out.println(code.get(i));
37                 }
38         }
39
40         public static String Comment(String comment) {
41                 return "/** " + comment + " */";
42         }
43
44         public static String ShortComment(String comment) {
45                 return "// " + comment;
46         }
47
48         public static String IncludeHeader(String header) {
49                 return "#include " + header;
50         }
51
52         public static String Brace(String val) {
53                 return "(" + val + ")";
54         }
55
56         public static String Quote(String val) {
57                 return "\"" + val + "\"";
58         }
59
60         public static String Assign(String varName, String val) {
61                 return varName + " = " + val + ";";
62         }
63
64         public static String AssignToPtr(String structName, String field, String val) {
65                 return structName + "->" + field + " = " + val + ";";
66         }
67
68         public static String Declare(String type, String name) {
69                 return type + " " + name + ";";
70         }
71
72         public static String Declare(VariableDeclaration varDecl) {
73                 return Declare(varDecl.type, varDecl.name);
74         }
75
76         public static String DeclareDefine(String type, String var, String val) {
77                 return type + " " + var + " = " + val + ";";
78         }
79
80         /**
81          * <p>
82          * Insert a number of tabs at the beginning of the line.
83          * </p>
84          * 
85          * @param line
86          *            Input line
87          * @param tabCnt
88          *            The number of tabs to be inserted
89          * @return A line that starts with the specific inserted tabs
90          */
91         public static String TabbedLine(String line, int tabCnt) {
92                 String res = "";
93                 for (int i = 0; i < tabCnt; i++)
94                         res = "\t" + res;
95                 res = res + line;
96                 return res;
97         }
98
99         /**
100          * <p>
101          * Insert a tab at the beginning of the line.
102          * </p>
103          * 
104          * @param line
105          *            Input line
106          * @return A line that starts with one inserted tab
107          */
108         public static String TabbedLine(String line) {
109                 return "\t" + line;
110         }
111
112         /**
113          * <p>
114          * This function generates the code for the header file that our
115          * specification generates automatically --- cdsspec-generated.h.
116          * </p>
117          * 
118          * @param extractor
119          *            The SpecExtractor that contains the extracted information
120          * @return The generated code
121          */
122         public static Code GenerateCDSSpecHeaderFile(SpecExtractor extractor) {
123                 HashSet<String> headerFiles = extractor.headerFiles;
124                 GlobalConstruct globalConstruct = extractor.getGlobalConstruct();
125                 HashMap<File, ArrayList<InterfaceConstruct>> interfaceListMap = extractor.interfaceListMap;
126                 HashSet<String> OPLabelSet = extractor.OPLabelSet;
127
128                 Code code = new Code();
129
130                 // Add auto-generated comments
131                 code.addLine("/**");
132                 code.addLine(TabbedLine("This is a header file auto-generated by CDSSpec compiler; together, CDSSpec"));
133                 code.addLine(TabbedLine("compiler should have generated the accompanying implementation file that"));
134                 code.addLine(TabbedLine("implements the some functions declared in this file. In order to instrument"));
135                 code.addLine(TabbedLine("your benchmark for CDSSpec checker to check, you should include this header"));
136                 code.addLine(TabbedLine("file in every file you use an CDSSpec annotation. Note that it should be"));
137                 code.addLine(TabbedLine("placed in the end of all other header files. Currently we require a C++"));
138                 code.addLine(TabbedLine("compiler that supports C++11."));
139                 code.addLine("*/");
140                 code.addLine("");
141
142                 code.addLine("#ifndef _"
143                                 + SpecNaming.CDSSpecGeneratedName.toUpperCase().replace('-',
144                                                 '_') + "_H");
145                 code.addLine("#define _"
146                                 + SpecNaming.CDSSpecGeneratedName.toUpperCase().replace('-',
147                                                 '_') + "_H");
148                 code.addLine("");
149
150                 // System included headers
151                 code.addLine(ShortComment("System included headers go here"));
152                 for (String header : SpecNaming.includedHeadersList) {
153                         code.addLine(IncludeHeader(header));
154                 }
155                 code.addLine("");
156
157                 // Users included headers
158                 // FIXME: We don't add user-defined headers, but as a workaround we only add forward class.
159                 code.addLine(ShortComment("User included headers go here"));
160                 for (String header : headerFiles) {
161                         code.addLine(IncludeHeader(header));
162                 }
163                 code.addLine("");
164                 
165 //              code.addLine(ShortComment("Forward declaration goes here"));
166 //              for (String type : extractor.forwardClass) {
167 //                      code.addLine("class " + type + ";");
168 //              }
169 //              code.addLine("");
170
171                 code.addLine("using namespace std;");
172                 code.addLine("");
173                 code.addLine("");
174
175                 code.addLine(ShortComment("Declaration of some c-strings (CSTR)"));
176                 code.addLine(ShortComment("A special empty string"));
177                 code.addLine(Declare("extern " + SpecNaming.CString,
178                                 SpecNaming.EmptyCString));
179                 code.addLine("");
180
181                 // Interface name strings
182                 code.addLine(ShortComment("Interface name strings"));
183                 for (File file : interfaceListMap.keySet()) {
184                         ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
185                         for (InterfaceConstruct construct : list) {
186                                 String name = construct.getName();
187                                 code.addLine(Declare("extern " + SpecNaming.CString,
188                                                 SpecNaming.AppendStr(name)));
189                         }
190                 }
191                 code.addLine("");
192
193                 // Commutativity rule strings
194                 code.addLine(ShortComment("Commutativity rule strings"));
195                 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
196                         code.addLine(Declare("extern " + SpecNaming.CString,
197                                         SpecNaming.AppendStr(SpecNaming.Commutativity + i)));
198                 }
199                 code.addLine("");
200
201                 // Ordering points label strings
202                 code.addLine(ShortComment("Ordering points label strings"));
203                 for (String label : OPLabelSet) {
204                         code.addLine(Declare("extern " + SpecNaming.CString,
205                                         SpecNaming.AppendStr(label)));
206                 }
207                 code.addLine("");
208
209                 // Special function name strings
210                 code.addLine(ShortComment("Special function name strings"));
211                 code.addLine(Declare("extern " + SpecNaming.CString,
212                                 SpecNaming.AppendStr(SpecNaming.InitalState)));
213                 code.addLine(Declare("extern " + SpecNaming.CString,
214                                 SpecNaming.AppendStr(SpecNaming.CopyState)));
215                 code.addLine(Declare("extern " + SpecNaming.CString,
216                                 SpecNaming.AppendStr(SpecNaming.FinalState)));
217                 code.addLine(Declare("extern " + SpecNaming.CString,
218                                 SpecNaming.AppendStr(SpecNaming.PrintState)));
219                 code.addLine("");
220
221                 // Interface name strings
222                 for (File file : interfaceListMap.keySet()) {
223                         ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
224                         for (InterfaceConstruct construct : list) {
225                                 String name = construct.getName();
226                                 code.addLine(ShortComment(name + " function strings"));
227                                 // Transition
228                                 String tmpFunc = name + "_" + SpecNaming.Transition;
229                                 code.addLine(Declare("extern " + SpecNaming.CString,
230                                                 SpecNaming.AppendStr(tmpFunc)));
231                                 // PreCondition
232                                 tmpFunc = name + "_" + SpecNaming.PreCondition;
233                                 code.addLine(Declare("extern " + SpecNaming.CString,
234                                                 SpecNaming.AppendStr(tmpFunc)));
235                                 // SideEffect
236                                 tmpFunc = name + "_" + SpecNaming.SideEffect;
237                                 code.addLine(Declare("extern " + SpecNaming.CString,
238                                                 SpecNaming.AppendStr(tmpFunc)));
239                                 // PostCondition
240                                 tmpFunc = name + "_" + SpecNaming.PostCondition;
241                                 code.addLine(Declare("extern " + SpecNaming.CString,
242                                                 SpecNaming.AppendStr(tmpFunc)));
243                                 // Print
244                                 tmpFunc = name + "_" + SpecNaming.PrintValue;
245                                 code.addLine(Declare("extern " + SpecNaming.CString,
246                                                 SpecNaming.AppendStr(tmpFunc)));
247                                 code.addLine("");
248                         }
249                 }
250
251                 // Declare customized StateStruct
252                 code.addLine(ShortComment("Declare customized StateStruct"));
253                 code.addLine("typedef struct " + SpecNaming.StateStruct + " {");
254                 for (VariableDeclaration decl : globalConstruct.declState) {
255                         code.addLine(TabbedLine(Declare(decl)));
256                 }
257                 code.addLine("");
258                 code.addLine(TabbedLine("SNAPSHOTALLOC"));
259                 code.addLine("} " + SpecNaming.StateStruct + ";");
260                 code.addLine("");
261
262                 // Declare customized value struct
263                 for (File file : interfaceListMap.keySet()) {
264                         ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
265                         for (InterfaceConstruct construct : list) {
266                                 // Declare custom value struct for the interface
267                                 String name = construct.getName();
268                                 code.addLine(ShortComment("Declare custom value struct for "
269                                                 + name));
270                                 code.addLine("typedef struct " + name + " {");
271                                 FunctionHeader funcHeader = construct.getFunctionHeader();
272                                 // RET
273                                 if (!funcHeader.returnType.equals("void"))
274                                         code.addLine(TabbedLine(Declare(funcHeader.returnType,
275                                                         SpecNaming.RET)));
276                                 // Arguments
277                                 for (VariableDeclaration decl : funcHeader.args) {
278                                         code.addLine(TabbedLine(Declare(decl)));
279                                 }
280                                 code.addLine("} " + name + ";");
281                                 code.addLine("");
282                         }
283                 }
284
285                 // Declare @Initial
286                 code.addLine(ShortComment("Declare @" + SpecNaming.InitalState));
287                 code.addLine("void _" + SpecNaming.InitalState.toLowerCase() + "("
288                                 + SpecNaming.Method + " " + SpecNaming.Method1 + ");");
289                 code.addLine("");
290                 // Declare @Copy
291                 code.addLine(ShortComment("Declare @" + SpecNaming.CopyState));
292                 code.addLine("void _" + SpecNaming.CopyState.toLowerCase() + "("
293                                 + SpecNaming.Method + " " + "dest, " + SpecNaming.Method
294                                 + " src);");
295                 code.addLine("");
296                 // Declare @Print
297                 code.addLine(ShortComment("Declare @" + SpecNaming.PrintState));
298                 if (!globalConstruct.printState.isEmpty()) {
299                         code.addLine("void _" + SpecNaming.PrintState.toLowerCase() + "("
300                                         + SpecNaming.Method + " " + SpecNaming.Method1 + ");");
301                         code.addLine("");
302                 }
303
304                 // Declare @Commutativity
305                 code.addLine(ShortComment("Declare commutativity checking functions"));
306                 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
307                         code.addLine("bool _check" + SpecNaming.Commutativity + i + "("
308                                         + SpecNaming.Method + " m1, " + SpecNaming.Method + " m2);");
309                 }
310                 code.addLine("");
311
312                 // Declare customized interface functions
313                 for (File file : interfaceListMap.keySet()) {
314                         ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
315                         for (InterfaceConstruct construct : list) {
316                                 // Declare interface functions
317                                 String name = construct.getName();
318                                 code.addLine("/**********    " + name
319                                                 + " functions    **********/");
320                                 // Declare @Transition for INTERFACE
321                                 code.addLine(ShortComment("Declare @" + SpecNaming.Transition
322                                                 + " for " + name));
323                                 code.addLine("void _" + name + "_" + SpecNaming.Transition
324                                                 + "(" + SpecNaming.Method + " " + SpecNaming.Method1
325                                                 + ", " + SpecNaming.Method + " " + SpecNaming.Method2
326                                                 + ");");
327                                 code.addLine("");
328                                 // Declare @PreCondition
329                                 if (!construct.preCondition.isEmpty()) {
330                                         code.addLine(ShortComment("Declare @"
331                                                         + SpecNaming.PreCondition + " for " + name));
332                                         code.addLine("bool _" + name + "_"
333                                                         + SpecNaming.PreCondition + "(" + SpecNaming.Method
334                                                         + " " + SpecNaming.Method1 + ");");
335                                         code.addLine("");
336                                 }
337                                 // Declare @SideEffect
338                                 if (!construct.sideEffect.isEmpty()) {
339                                         code.addLine(ShortComment("Declare @"
340                                                         + SpecNaming.SideEffect + " for " + name));
341                                         code.addLine("void _" + name + "_" + SpecNaming.SideEffect
342                                                         + "(" + SpecNaming.Method + " "
343                                                         + SpecNaming.Method1 + ");");
344                                         code.addLine("");
345                                 }
346                                 // Declare @PostCondition
347                                 if (!construct.postCondition.isEmpty()) {
348                                         code.addLine(ShortComment("Declare @"
349                                                         + SpecNaming.PostCondition + " for " + name));
350                                         code.addLine("bool _" + name + "_"
351                                                         + SpecNaming.PostCondition + "("
352                                                         + SpecNaming.Method + " " + SpecNaming.Method1
353                                                         + ");");
354                                         code.addLine("");
355                                 }
356                                 // Declare @Print
357                                 if (!construct.print.isEmpty()) {
358                                         code.addLine(ShortComment("Declare @"
359                                                         + SpecNaming.PrintValue + " for " + name));
360                                         code.addLine("void _" + name + "_" + SpecNaming.PrintValue
361                                                         + "(" + SpecNaming.Method + " "
362                                                         + SpecNaming.Method1 + ");");
363                                         code.addLine("");
364                                 }
365                         }
366                 }
367
368                 // Declare INIT annotation instrumentation function
369                 code.addLine(ShortComment("Declare INIT annotation instrumentation function"));
370                 code.addLine("void _createInitAnnotation();");
371                 code.addLine("");
372                 code.addLine("#endif");
373
374                 return code;
375         }
376
377         /**
378          * <p>
379          * This function generates the code for the CPP file that our specification
380          * generates automatically --- cdsspec-generated.cc.
381          * </p>
382          * 
383          * @param extractor
384          *            The SpecExtractor that contains the extracted information
385          * @return The generated code
386          */
387         public static Code GenerateCDSSpecCPPFile(SpecExtractor extractor) {
388                 GlobalConstruct globalConstruct = extractor.getGlobalConstruct();
389                 HashMap<File, ArrayList<InterfaceConstruct>> interfaceListMap = extractor.interfaceListMap;
390                 HashSet<String> OPLabelSet = extractor.OPLabelSet;
391
392                 Code code = new Code();
393                 String line = null;
394
395                 // Add auto-generated comments
396                 code.addLine("/**");
397                 code.addLine(TabbedLine("This is an implementation file auto-generated by CDSSpec compiler to"));
398                 code.addLine(TabbedLine("instrument your benchmark for CDSSpec checker to check. Currently we require"));
399                 code.addLine(TabbedLine("a C++ compiler that supports C++11."));
400                 code.addLine("*/");
401                 code.addLine("");
402
403                 code.addLine("#include " + SpecNaming.CDSSpecGeneratedHeader);
404                 code.addLine("");
405                 code.addLine("");
406
407                 code.addLine(ShortComment("Definition of some c-strings (CSTR)"));
408                 code.addLine(ShortComment("A special empty string"));
409                 code.addLine(DeclareDefine(SpecNaming.CString, SpecNaming.EmptyCString,
410                                 "\"\""));
411                 code.addLine("");
412
413                 // Interface name strings
414                 code.addLine(ShortComment("Interface name strings"));
415                 for (File file : interfaceListMap.keySet()) {
416                         ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
417                         for (InterfaceConstruct construct : list) {
418                                 String name = construct.getName();
419                                 code.addLine(DeclareDefine(SpecNaming.CString,
420                                                 SpecNaming.AppendStr(name), Quote(name)));
421                         }
422                 }
423                 code.addLine("");
424
425                 // Commutativity rule strings
426                 code.addLine(ShortComment("Commutativity rule strings"));
427                 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
428                         CommutativityRule rule = globalConstruct.commutativityRules
429                                         .get(i - 1);
430                         code.addLine(DeclareDefine(SpecNaming.CString,
431                                         SpecNaming.AppendStr(SpecNaming.Commutativity + i),
432                                         Quote(rule.toString())));
433                 }
434                 code.addLine("");
435
436                 // Ordering points label strings
437                 code.addLine(ShortComment("Ordering points label strings"));
438                 for (String label : OPLabelSet) {
439                         code.addLine(DeclareDefine(SpecNaming.CString,
440                                         SpecNaming.AppendStr(label), Quote(label)));
441                 }
442                 code.addLine("");
443
444                 // Special function name strings
445                 code.addLine(ShortComment("Special function name strings"));
446                 code.addLine(DeclareDefine(SpecNaming.CString,
447                                 SpecNaming.AppendStr(SpecNaming.InitalState), Quote("_"
448                                                 + SpecNaming.InitalState.toLowerCase())));
449                 code.addLine(DeclareDefine(SpecNaming.CString,
450                                 SpecNaming.AppendStr(SpecNaming.CopyState), Quote("_"
451                                                 + SpecNaming.CopyState.toLowerCase())));
452                 code.addLine(DeclareDefine(SpecNaming.CString,
453                                 SpecNaming.AppendStr(SpecNaming.FinalState), Quote("_"
454                                                 + SpecNaming.FinalState.toLowerCase())));
455                 code.addLine(DeclareDefine(SpecNaming.CString,
456                                 SpecNaming.AppendStr(SpecNaming.PrintState), Quote("_"
457                                                 + SpecNaming.PrintState.toLowerCase())));
458                 code.addLine("");
459
460                 // Interface name strings
461                 for (File file : interfaceListMap.keySet()) {
462                         ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
463                         for (InterfaceConstruct construct : list) {
464                                 String name = construct.getName();
465                                 code.addLine(ShortComment(name + " function strings"));
466                                 // Transition
467                                 String tmpFunc = name + "_" + SpecNaming.Transition;
468                                 code.addLine(DeclareDefine(SpecNaming.CString,
469                                                 SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
470                                 // PreCondition
471                                 tmpFunc = name + "_" + SpecNaming.PreCondition;
472                                 if (!construct.preCondition.isEmpty())
473                                         code.addLine(DeclareDefine(SpecNaming.CString,
474                                                         SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
475                                 else
476                                         code.addLine(DeclareDefine(SpecNaming.CString,
477                                                         SpecNaming.AppendStr(tmpFunc),
478                                                         SpecNaming.EmptyCString));
479                                 // SideEffect
480                                 tmpFunc = name + "_" + SpecNaming.SideEffect;
481                                 if (!construct.sideEffect.isEmpty())
482                                         code.addLine(DeclareDefine(SpecNaming.CString,
483                                                         SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
484                                 else
485                                         code.addLine(DeclareDefine(SpecNaming.CString,
486                                                         SpecNaming.AppendStr(tmpFunc),
487                                                         SpecNaming.EmptyCString));
488                                 // PostCondition
489                                 tmpFunc = name + "_" + SpecNaming.PostCondition;
490                                 if (!construct.postCondition.isEmpty())
491                                         code.addLine(DeclareDefine(SpecNaming.CString,
492                                                         SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
493                                 else
494                                         code.addLine(DeclareDefine(SpecNaming.CString,
495                                                         SpecNaming.AppendStr(tmpFunc),
496                                                         SpecNaming.EmptyCString));
497                                 // Print
498                                 tmpFunc = name + "_" + SpecNaming.PrintValue;
499                                 if (!construct.print.isEmpty())
500                                         code.addLine(DeclareDefine(SpecNaming.CString,
501                                                         SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
502                                 else
503                                         code.addLine(DeclareDefine(SpecNaming.CString,
504                                                         SpecNaming.AppendStr(tmpFunc),
505                                                         SpecNaming.EmptyCString));
506                                 code.addLine("");
507                         }
508                 }
509
510                 // Define @Initial
511                 code.addLine(ShortComment("Define @" + SpecNaming.InitalState));
512                 code.addLine("void _" + SpecNaming.InitalState.toLowerCase() + "("
513                                 + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
514                 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
515                                 + SpecNaming.StateInst, "new " + SpecNaming.StateStruct)));
516                 // Define macros
517                 for (VariableDeclaration decl : globalConstruct.declState) {
518                         code.addLine(TabbedLine("#define " + decl.name + " "
519                                         + SpecNaming.StateInst + "->" + decl.name));
520                 }
521                 code.addLine(TabbedLine(ShortComment("User-defined intial state code")));
522                 // Align the code with one tab
523                 globalConstruct.initState.align(1);
524                 code.addLines(globalConstruct.initState);
525                 // Undefine macros
526                 for (VariableDeclaration decl : globalConstruct.declState) {
527                         code.addLine(TabbedLine("#undef " + decl.name));
528                 }
529                 code.addLine("");
530                 code.addLine(TabbedLine(AssignToPtr(SpecNaming.Method1,
531                                 SpecNaming.StateInst, SpecNaming.StateInst)));
532                 code.addLine("}");
533                 code.addLine("");
534
535                 // Define @Copy
536                 code.addLine(ShortComment("Define @" + SpecNaming.CopyState));
537                 code.addLine("void _" + SpecNaming.CopyState.toLowerCase() + "("
538                                 + SpecNaming.Method + " " + "dest, " + SpecNaming.Method
539                                 + " src) {");
540                 // StateStruct *OLD = (StateStruct*) src->state;
541                 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
542                                 + SpecNaming.OldStateInst, Brace(SpecNaming.StateStruct + "*")
543                                 + " src->" + SpecNaming.StateInst)));
544                 // StateStruct *NEW = new StateStruct;
545                 code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
546                                 + SpecNaming.NewStateInst, "new " + SpecNaming.StateStruct)));
547                 if (!globalConstruct.autoGenCopy)
548                         code.addLine(TabbedLine(ShortComment("User-defined state copy statements")));
549                 else
550                         // Auto-generated the copy function
551                         code.addLine(TabbedLine(ShortComment("Auto-generated state copy statements")));
552                 globalConstruct.copyState.align(1);
553                 code.addLines(globalConstruct.copyState);
554                 code.addLine("");
555                 code.addLine(TabbedLine(AssignToPtr("dest", SpecNaming.StateInst,
556                                 SpecNaming.NewStateInst)));
557                 code.addLine("}");
558                 code.addLine("");
559
560                 // Define @Print
561                 if (!globalConstruct.printState.isEmpty()) {
562                         code.addLine(ShortComment("Define @" + SpecNaming.PrintState));
563                         code.addLine("void _" + SpecNaming.PrintState.toLowerCase() + "("
564                                         + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
565
566                         // Initialize state struct fields
567                         Code fieldsInit = GenerateStateFieldsInitialization(
568                                         SpecNaming.Method1, SpecNaming.StateInst, globalConstruct);
569                         fieldsInit.align(1);
570                         code.addLines(fieldsInit);
571                         code.addLine("");
572                         code.addLine(TabbedLine(ShortComment("Execute the print-out")));
573                         // Align the code with one tab
574                         globalConstruct.printState.align(1);
575                         code.addLines(globalConstruct.printState);
576                         code.addLine("}");
577                         code.addLine("");
578                 }
579
580                 // Define @Commutativity
581                 code.addLine(ShortComment("Define commutativity checking functions"));
582                 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
583                         CommutativityRule rule = globalConstruct.commutativityRules
584                                         .get(i - 1);
585                         code.addLine("bool _check" + SpecNaming.Commutativity + i + "("
586                                         + SpecNaming.Method + " m1, " + SpecNaming.Method
587                                         + " m2) {");
588                         // if (m1->name == _ENQ_str && m2->name == _DEQ_str) {
589                         code.addLine(TabbedLine("if (m1->name == "
590                                         + SpecNaming.AppendStr(rule.method1) + " && m2->name == "
591                                         + SpecNaming.AppendStr(rule.method2) + ") {"));
592                         // Initialize M1 & M2 in commutativity rule
593                         // e.g. ENQ *M1 = (ENQ*) m1->value;
594                         code.addLine(TabbedLine(
595                                         DeclareDefine(rule.method1, "*M1", "(" + rule.method1
596                                                         + "*) m1->value"), 2));
597                         code.addLine(TabbedLine(
598                                         DeclareDefine(rule.method2, "*M2", "(" + rule.method2
599                                                         + "*) m2->value"), 2));
600                         code.addLine(TabbedLine("return " + rule.condition + ";", 2));
601                         code.addLine(TabbedLine("}"));
602                         code.addLine(TabbedLine("return false;"));
603
604                         code.addLine("}");
605                         code.addLine("");
606                 }
607
608                 // Define customized interface functions
609                 for (File file : interfaceListMap.keySet()) {
610                         ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
611                         for (InterfaceConstruct construct : list) {
612                                 Code fieldsInit = null;
613
614                                 // Define interface functions
615                                 String name = construct.getName();
616                                 code.addLine("/**********    " + name
617                                                 + " functions    **********/");
618                                 // Define @Transition for INTERFACE
619                                 code.addLine(ShortComment("Define @" + SpecNaming.Transition
620                                                 + " for " + name));
621                                 code.addLine("void _" + name + "_" + SpecNaming.Transition
622                                                 + "(" + SpecNaming.Method + " " + SpecNaming.Method1
623                                                 + ", " + SpecNaming.Method + " " + SpecNaming.Method2
624                                                 + ") {");
625
626                                 // Initialize value struct fields
627                                 fieldsInit = GenerateInterfaceFieldsInitialization(
628                                                 SpecNaming.Method2, "value", construct);
629                                 fieldsInit.align(1);
630                                 code.addLines(fieldsInit);
631
632                                 construct.transition.align(1);
633                                 code.addLine(TabbedLine(ShortComment("Execute Transition")));
634                                 code.addLines(construct.transition);
635
636                                 code.addLine("}");
637                                 code.addLine("");
638
639                                 // Define @PreCondition
640                                 if (!construct.preCondition.isEmpty()) {
641                                         code.addLine(ShortComment("Define @"
642                                                         + SpecNaming.PreCondition + " for " + name));
643                                         code.addLine("bool _" + name + "_"
644                                                         + SpecNaming.PreCondition + "(" + SpecNaming.Method
645                                                         + " " + SpecNaming.Method1 + ") {");
646
647                                         // Initialize value struct fields
648                                         fieldsInit = GenerateInterfaceFieldsInitialization(
649                                                         SpecNaming.Method1, "value", construct);
650                                         fieldsInit.align(1);
651                                         code.addLines(fieldsInit);
652
653                                         construct.preCondition.align(1);
654                                         code.addLine(TabbedLine(ShortComment("Execute PreCondition")));
655                                         code.addLines(construct.preCondition);
656
657                                         code.addLine("}");
658                                         code.addLine("");
659
660                                 }
661                                 // Define @SideEffect
662                                 if (!construct.sideEffect.isEmpty()) {
663                                         code.addLine(ShortComment("Define @"
664                                                         + SpecNaming.SideEffect + " for " + name));
665                                         code.addLine("void _" + name + "_" + SpecNaming.SideEffect
666                                                         + "(" + SpecNaming.Method + " "
667                                                         + SpecNaming.Method1 + ") {");
668
669                                         // Initialize value struct fields
670                                         fieldsInit = GenerateInterfaceFieldsInitialization(
671                                                         SpecNaming.Method1, "value", construct);
672                                         fieldsInit.align(1);
673                                         code.addLines(fieldsInit);
674
675                                         construct.sideEffect.align(1);
676                                         code.addLine(TabbedLine(ShortComment("Execute SideEffect")));
677                                         code.addLines(construct.sideEffect);
678
679                                         code.addLine("}");
680                                         code.addLine("");
681                                 }
682                                 // Define @PostCondition
683                                 if (!construct.postCondition.isEmpty()) {
684                                         code.addLine(ShortComment("Define @"
685                                                         + SpecNaming.PostCondition + " for " + name));
686                                         code.addLine("bool _" + name + "_"
687                                                         + SpecNaming.PostCondition + "("
688                                                         + SpecNaming.Method + " " + SpecNaming.Method1
689                                                         + ") {");
690
691                                         // Initialize value struct fields
692                                         fieldsInit = GenerateInterfaceFieldsInitialization(
693                                                         SpecNaming.Method1, "value", construct);
694                                         fieldsInit.align(1);
695                                         code.addLines(fieldsInit);
696
697                                         construct.postCondition.align(1);
698                                         code.addLine(TabbedLine(ShortComment("Execute PostCondition")));
699                                         code.addLines(construct.postCondition);
700
701                                         code.addLine("}");
702                                         code.addLine("");
703                                 }
704                                 // Define @Print
705                                 if (!construct.print.isEmpty()) {
706                                         code.addLine(ShortComment("Define @"
707                                                         + SpecNaming.PrintValue + " for " + name));
708                                         code.addLine("void _" + name + "_" + SpecNaming.PrintValue
709                                                         + "(" + SpecNaming.Method + " "
710                                                         + SpecNaming.Method1 + ") {");
711                                         // Initialize value struct fields
712                                         fieldsInit = GenerateInterfaceFieldsInitialization(
713                                                         SpecNaming.Method1, "value", construct);
714                                         fieldsInit.align(1);
715                                         code.addLines(fieldsInit);
716
717                                         construct.print.align(1);
718                                         code.addLine(TabbedLine(ShortComment("Execute Print")));
719                                         code.addLines(construct.print);
720
721                                         code.addLine("}");
722                                         code.addLine("");
723                                 }
724                         }
725                 }
726
727                 // Define INIT annotation instrumentation function
728                 code.addLine(ShortComment("Define INIT annotation instrumentation function"));
729                 code.addLine("void _createInitAnnotation() {");
730
731                 // Init commutativity rules
732                 code.addLine(TabbedLine(ShortComment("Init commutativity rules")));
733                 code.addLine(TabbedLine(DeclareDefine("int",
734                                 SpecNaming.CommutativityRuleSizeInst,
735                                 Integer.toString(globalConstruct.commutativityRules.size()))));
736                 String tmp = SpecNaming.NewSize
737                                 + Brace(SpecNaming.CommutativityRule + ", sizeof"
738                                                 + Brace(SpecNaming.CommutativityRule) + " * "
739                                                 + SpecNaming.CommutativityRuleSizeInst);
740                 code.addLine(TabbedLine(DeclareDefine(SpecNaming.CommutativityRule, "*"
741                                 + SpecNaming.CommutativityRuleInst, tmp)));
742                 for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
743                         CommutativityRule rule = globalConstruct.commutativityRules
744                                         .get(i - 1);
745                         code.addLine(TabbedLine(ShortComment("Initialize commutativity rule ")
746                                         + i));
747                         // new( &commuteRules[0] )CommutativityRule(_ENQ_str, _DEQ_str,
748                         // _Commutativity1_str, _checkCommutativity1)
749                         line = "new"
750                                         + Brace(" &" + SpecNaming.CommutativityRuleInst + "["
751                                                         + (i - 1) + "] ") + SpecNaming.CommutativityRule
752                                         + "(" + SpecNaming.AppendStr(rule.method1) + ", "
753                                         + SpecNaming.AppendStr(rule.method2) + ", "
754                                         + SpecNaming.AppendStr(SpecNaming.Commutativity + i) + ", "
755                                         + "_check" + SpecNaming.Commutativity + i + ");";
756                         code.addLine(TabbedLine(line));
757                 }
758
759                 // Initialize AnnoInit
760                 code.addLine(TabbedLine(ShortComment("Initialize AnnoInit")));
761                 // AnnoInit *init = new AnnoInit(
762                 code.addLine(TabbedLine(SpecNaming.AnnoInit + " *"
763                                 + SpecNaming.AnnoInitInst + " = new " + SpecNaming.AnnoInit
764                                 + "("));
765                 // new NamedFunction(_Initial_str, INITIAL, (void*) _initial),
766                 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
767                                 + SpecNaming.AppendStr(SpecNaming.InitalState) + ", "
768                                 + SpecNaming.InitalState.toUpperCase() + ", " + "(void*) _"
769                                 + SpecNaming.InitalState.toLowerCase() + "),", 2));
770                 // new NamedFunction(_Final_str, FINAL, (void*) NULL_FUNC),
771                 line = "new " + SpecNaming.NamedFunction + "("
772                                 + SpecNaming.AppendStr(SpecNaming.FinalState) + ", "
773                                 + SpecNaming.FinalState.toUpperCase() + ", " + "(void*) ";
774                 if (globalConstruct.finalState.isEmpty()) {
775                         line = line + SpecNaming.NullFunc + "),";
776                 } else {
777                         line = line + "_" + SpecNaming.FinalState.toUpperCase();
778                 }
779                 code.addLine(TabbedLine(line, 2));
780                 // new NamedFunction(_Copy_str, COPY, (void*) _copy),
781                 code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
782                                 + SpecNaming.AppendStr(SpecNaming.CopyState) + ", "
783                                 + SpecNaming.CopyState.toUpperCase() + ", " + "(void*) _"
784                                 + SpecNaming.CopyState.toLowerCase() + "),", 2));
785                 // new NamedFunction(_Print_str, PRINT_STATE, (void*) _print),
786                 line = "new " + SpecNaming.NamedFunction + "("
787                                 + SpecNaming.AppendStr(SpecNaming.PrintState) + ", "
788                                 + SpecNaming.PrintStateType + ", " + "(void*)";
789                 if (globalConstruct.printState.isEmpty()) {
790                         line = line + SpecNaming.NullFunc + "),";
791                 } else {
792                         line = line + "_" + SpecNaming.PrintState.toLowerCase() + "),";
793                 }
794                 code.addLine(TabbedLine(line, 2));
795                 // commuteRules, CommuteRuleSize);
796                 code.addLine(TabbedLine(SpecNaming.CommutativityRuleInst + ", "
797                                 + SpecNaming.CommutativityRuleSizeInst + ");", 2));
798                 code.addLine("");
799
800                 // Declare StateFunctions map
801                 code.addLine(TabbedLine(ShortComment("Declare StateFunctions map")));
802                 code.addLine(TabbedLine(Declare(SpecNaming.StateFunctions, "*"
803                                 + SpecNaming.StateFunctionsInst)));
804                 code.addLine("");
805
806                 // StateFunction for interface
807                 for (File file : interfaceListMap.keySet()) {
808                         ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
809                         for (InterfaceConstruct construct : list) {
810                                 String name = construct.getName();
811                                 code.addLine(TabbedLine(ShortComment("StateFunction for "
812                                                 + name)));
813                                 // stateFuncs = new StateFunctions(
814                                 code.addLine(TabbedLine(SpecNaming.StateFunctionsInst
815                                                 + " = new " + SpecNaming.StateFunctions + "("));
816                                 // new NamedFunction(_ENQ_Transition_str, TRANSITION, (void*)
817                                 // _ENQ_Transition),
818                                 // Transition
819                                 code.addLine(TabbedLine(
820                                                 "new "
821                                                                 + SpecNaming.NamedFunction
822                                                                 + "("
823                                                                 + SpecNaming.AppendStr(name + "_"
824                                                                                 + SpecNaming.Transition) + ", "
825                                                                 + SpecNaming.TransitionType + ", (void*) _"
826                                                                 + name + "_" + SpecNaming.Transition + "),", 2));
827                                 // PreCondition
828                                 line = "new "
829                                                 + SpecNaming.NamedFunction
830                                                 + "("
831                                                 + SpecNaming.AppendStr(name + "_"
832                                                                 + SpecNaming.PreCondition) + ", "
833                                                 + SpecNaming.PreConditionType + ", (void*) ";
834                                 if (construct.preCondition.isEmpty()) {
835                                         line = line + SpecNaming.NullFunc + "),";
836                                 } else {
837                                         line = line + "_" + name + "_" + SpecNaming.PreCondition
838                                                         + "),";
839                                 }
840                                 code.addLine(TabbedLine(line, 2));
841                                 // SideEffect
842                                 line = "new "
843                                                 + SpecNaming.NamedFunction
844                                                 + "("
845                                                 + SpecNaming.AppendStr(name + "_"
846                                                                 + SpecNaming.SideEffect) + ", "
847                                                 + SpecNaming.SideEffectType + ", (void*) ";
848                                 if (construct.sideEffect.isEmpty()) {
849                                         line = line + SpecNaming.NullFunc + "),";
850                                 } else {
851                                         line = line + "_" + name + "_" + SpecNaming.SideEffect
852                                                         + "),";
853                                 }
854                                 code.addLine(TabbedLine(line, 2));
855                                 // PostCondition
856                                 line = "new "
857                                                 + SpecNaming.NamedFunction
858                                                 + "("
859                                                 + SpecNaming.AppendStr(name + "_"
860                                                                 + SpecNaming.PostCondition) + ", "
861                                                 + SpecNaming.PostConditionType + ", (void*) ";
862                                 if (construct.postCondition.isEmpty()) {
863                                         line = line + SpecNaming.NullFunc + "),";
864                                 } else {
865                                         line = line + "_" + name + "_" + SpecNaming.PostCondition
866                                                         + "),";
867                                 }
868                                 code.addLine(TabbedLine(line, 2));
869                                 // Print (PrintValue
870                                 line = "new "
871                                                 + SpecNaming.NamedFunction
872                                                 + "("
873                                                 + SpecNaming.AppendStr(name + "_"
874                                                                 + SpecNaming.PrintValue) + ", "
875                                                 + SpecNaming.PrintValueType + ", (void*) ";
876                                 if (construct.print.isEmpty()) {
877                                         line = line + SpecNaming.NullFunc + ")";
878                                 } else {
879                                         line = line + "_" + name + "_" + SpecNaming.PrintValue
880                                                         + ")";
881                                 }
882                                 code.addLine(TabbedLine(line, 2));
883                                 code.addLine(TabbedLine(");"));
884
885                                 // init->addInterfaceFunctions(_ENQ_str, stateFuncs);
886                                 code.addLine(TabbedLine(SpecNaming.AnnoInitInst
887                                                 + "->"
888                                                 + SpecNaming.AddInterfaceFunctions
889                                                 + Brace(SpecNaming.AppendStr(name) + ", "
890                                                                 + SpecNaming.StateFunctionsInst) + ";"));
891                                 code.addLine("");
892                         }
893                 }
894
895                 // Create and instrument with the INIT annotation
896                 code.addLine(TabbedLine(ShortComment("Create and instrument with the INIT annotation")));
897                 // cdsannotate(SPEC_ANALYSIS, new SpecAnnotation(INIT, init));
898                 code.addLine(TabbedLine(SpecNaming.CDSAnnotateFunc
899                                 + Brace(SpecNaming.SPEC_ANALYSIS
900                                                 + ", new "
901                                                 + SpecNaming.SpecAnnotation
902                                                 + Brace(SpecNaming.AnnoTypeInit + ", "
903                                                                 + SpecNaming.AnnoInitInst)) + ";"));
904
905                 code.addLine("}");
906                 code.addLine("");
907
908                 return code;
909         }
910
911         /**
912          * <p>
913          * This function generates a list of lines that initialize the fields of the
914          * global state struct. See below.
915          * </p>
916          * 
917          * <p>
918          * <code>
919          * StateStruct *state = (StateStruct*) _M->state;
920          * <br>
921          * IntList * q = state->q;
922          * </code>
923          * </p>
924          * 
925          * <p>
926          * In this example, _M --> methodInst, state --> inst.
927          * </p>
928          * 
929          * @param methodInst
930          *            See description
931          * @param inst
932          *            See description
933          * @param construct
934          *            The global state construct
935          * @return The generated code
936          */
937         public static Code GenerateStateFieldsInitialization(String methodInst,
938                         String inst, GlobalConstruct construct) {
939                 Code res = new Code();
940                 res.addLine(ShortComment("Initialize " + SpecNaming.StateStruct
941                                 + " fields"));
942                 res.addLine(DeclareDefine(SpecNaming.StateStruct, "*" + inst, "("
943                                 + SpecNaming.StateStruct + "*) " + methodInst + "->state"));
944                 for (VariableDeclaration decl : construct.declState) {
945                         res.addLine(DeclareDefine(decl.type, decl.name, inst + "->"
946                                         + decl.name));
947                 }
948                 return res;
949         }
950
951         /**
952          * <p>
953          * This function generates a list of lines that initialize the fields of a
954          * specific interface struct. See below.
955          * </p>
956          * 
957          * <p>
958          * <code>
959          * ENQ *info = (ENQ*) _M->value;
960          * <br>
961          * IntList * q = info->q;
962          * </code>
963          * </p>
964          * 
965          * <p>
966          * In this example, ENQ --> structType, _M --> methodInst, info --> inst
967          * </p>
968          * 
969          * @param methodInst
970          *            See description
971          * @param inst
972          *            See description
973          * @param construct
974          *            The corresponding interface construct
975          * @return The generated code
976          */
977         public static Code GenerateInterfaceFieldsInitialization(String methodInst,
978                         String inst, InterfaceConstruct construct) {
979                 Code res = new Code();
980                 String name = construct.getName();
981                 res.addLine(ShortComment("Initialize fields for " + name));
982                 // The very first assignment "
983                 res.addLine(DeclareDefine(name, "*" + inst, "(" + name + "*) "
984                                 + methodInst + "->value"));
985                 // Don't leave out the RET field
986                 if (!construct.getFunctionHeader().isReturnVoid()) {
987                         res.addLine(DeclareDefine(construct.getFunctionHeader().returnType,
988                                         SpecNaming.RET, "value->" + SpecNaming.RET));
989                 }
990                 // For arguments
991                 for (VariableDeclaration decl : construct.getFunctionHeader().args) {
992                         res.addLine(DeclareDefine(decl.type, decl.name, inst + "->"
993                                         + decl.name));
994                 }
995                 return res;
996         }
997
998         /**
999          * <p>
1000          * This function generates the code to be inserted right after the ordering
1001          * point construct (instrumentation code)
1002          * </p>
1003          * 
1004          * @param construct
1005          *            The corresponding ordering point construct
1006          * @return The generated code
1007          */
1008         public static Code Generate4OPConstruct(OPConstruct construct) {
1009                 Code code = new Code();
1010                 String curLine = construct.annotation;
1011                 String label = construct.label;
1012                 String prefixTabs = curLine.substring(0, curLine.indexOf("/**"));
1013                 code.addLine(prefixTabs + "if (" + construct.condition + ")");
1014                 switch (construct.type) {
1015                 case OPDefine:
1016                         code.addLine(prefixTabs + "\t" + SpecNaming.CreateOPDefineAnnoFunc
1017                                         + "();");
1018                         break;
1019                 case PotentialOP:
1020                         code.addLine(prefixTabs + "\t"
1021                                         + SpecNaming.CreatePotentialOPAnnoFunc + "("
1022                                         + SpecNaming.AppendStr(label) + ");");
1023                         break;
1024                 case OPCheck:
1025                         code.addLine(prefixTabs + "\t" + SpecNaming.CreateOPCheckAnnoFunc
1026                                         + "(" + SpecNaming.AppendStr(label) + ");");
1027                         break;
1028                 case OPClear:
1029                         code.addLine(prefixTabs + "\t" + SpecNaming.CreateOPClearAnnoFunc
1030                                         + "();");
1031                         break;
1032                 case OPClearDefine:
1033                         code.addLine(prefixTabs + "\t"
1034                                         + SpecNaming.CreateOPClearDefineAnnoFunc + "();");
1035                         break;
1036                 default:
1037                         break;
1038                 }
1039                 return code;
1040         }
1041
1042         /**
1043          * <p>
1044          * This function generates the code to be inserted right after the entry
1045          * construct (instrumentation code)
1046          * </p>
1047          * 
1048          * @param construct
1049          *            The corresponding entry construct
1050          * @return
1051          */
1052         public static Code Generate4Entry(EntryConstruct construct) {
1053                 Code res = new Code();
1054                 String curLine = construct.annotation;
1055                 String prefixTabs = curLine.substring(0, curLine.indexOf("/**"));
1056                 // _createInitAnnotation();
1057                 res.addLine(prefixTabs + SpecNaming.CreateInitAnnoFunc + "();");
1058                 return res;
1059         }
1060
1061         /**
1062          * <p>
1063          * This function generates the new interface wrapper code to be inserted
1064          * right after the end of the interface definition
1065          * </p>
1066          * 
1067          * @param construct
1068          *            The corresponding interface construct
1069          * @return The generated code
1070          */
1071         public static Code GenerateInterfaceWrapper(InterfaceConstruct construct) {
1072                 Code code = new Code();
1073
1074                 String name = construct.getName();
1075                 String beginLine = construct.getFunctionHeader().getHeaderLine();
1076                 Pattern regexpSpace = Pattern.compile("^(\\s*)\\S.*$");
1077                 Matcher matcherSpace = regexpSpace.matcher(beginLine);
1078                 String prefixTabs = "";
1079                 if (matcherSpace.find())
1080                         prefixTabs = matcherSpace.group(1);
1081
1082                 // Add one line to separate
1083                 code.addLine("");
1084                 code.addLine(prefixTabs
1085                                 + ShortComment("Generated wrapper interface for " + name));
1086                 if (beginLine.indexOf('{') == -1) { // We need to add the '{' to the end
1087                                                                                         // of the line
1088                         code.addLine(beginLine + " {");
1089                 } else {
1090                         code.addLine(beginLine);
1091                 }
1092                 // Instrument with the INTERFACE_BEGIN annotation
1093                 code.addLine(prefixTabs
1094                                 + "\t"
1095                                 + ShortComment("Instrument with the INTERFACE_BEGIN annotation"));
1096                 // AnnoInterfaceInfo *info = _createInterfaceBeginAnnotation(_DEQ_str);
1097                 code.addLine(prefixTabs
1098                                 + "\t"
1099                                 + DeclareDefine(SpecNaming.AnnoInterfaceInfo, "*"
1100                                                 + SpecNaming.AnnoInterfaceInfoInst,
1101                                                 SpecNaming.CreateInterfaceBeginAnnoFunc
1102                                                                 + Brace(SpecNaming.AppendStr(name))));
1103                 // Call the actual function
1104                 code.addLine(prefixTabs + "\t"
1105                                 + ShortComment("Call the actual function"));
1106                 // bool RET = dequeue_ORIGINAL__(q, retVal, reclaimNode);
1107                 code.addLine(prefixTabs + "\t"
1108                                 + construct.getFunctionHeader().getRenamedCall() + ";");
1109                 code.addLine("");
1110
1111                 // Initialize the value struct
1112                 code.addLine(prefixTabs + "\t"
1113                                 + ShortComment("Initialize the value struct"));
1114                 // The very first assignment "
1115                 code.addLine(prefixTabs + "\t"
1116                                 + DeclareDefine(name, "*value", "new " + name));
1117                 // Don't leave out the RET field
1118                 if (!construct.getFunctionHeader().isReturnVoid())
1119                         code.addLine(prefixTabs + "\t"
1120                                         + AssignToPtr("value", SpecNaming.RET, SpecNaming.RET));
1121                 // For arguments
1122                 for (VariableDeclaration decl : construct.getFunctionHeader().args)
1123                         code.addLine(prefixTabs + "\t"
1124                                         + AssignToPtr("value", decl.name, decl.name));
1125                 code.addLine("");
1126
1127                 // Store the value info into the current MethodCall
1128                 code.addLine(prefixTabs
1129                                 + "\t"
1130                                 + ShortComment("Store the value info into the current MethodCall"));
1131                 code.addLine(prefixTabs
1132                                 + "\t"
1133                                 + AssignToPtr(SpecNaming.AnnoInterfaceInfoInst, "value",
1134                                                 "value"));
1135                 code.addLine("");
1136
1137                 // Return if necessary
1138                 if (!construct.getFunctionHeader().isReturnVoid())
1139                         code.addLine(prefixTabs + "\treturn " + SpecNaming.RET + ";");
1140                 code.addLine(prefixTabs + "}");
1141
1142                 return code;
1143         }
1144
1145         /**
1146          * <p>
1147          * Write a list of lines (as the whole of the file) to a file ---
1148          * newFileName. If that file does not exist, we create that file and then
1149          * write the lines.
1150          * </p>
1151          * 
1152          * @param newFileName
1153          *            The name of the file to be written
1154          * @param content
1155          *            The list of lines that as a whole become the content of the
1156          *            file
1157          */
1158         public static void write2File(String newFileName, ArrayList<String> content) {
1159                 File newFile = new File(newFileName);
1160                 newFile.getParentFile().mkdirs();
1161                 if (!newFile.exists()) {
1162                         try {
1163                                 newFile.createNewFile();
1164                         } catch (IOException e) {
1165                                 e.printStackTrace();
1166                         }
1167                 }
1168                 BufferedWriter bw = null;
1169                 try {
1170                         bw = new BufferedWriter(new FileWriter(newFile));
1171                         for (int i = 0; i < content.size(); i++) {
1172                                 bw.write(content.get(i) + "\n");
1173                         }
1174                         bw.flush();
1175                 } catch (IOException e) {
1176                         e.printStackTrace();
1177                 } finally {
1178                         if (bw != null)
1179                                 try {
1180                                         bw.close();
1181                                 } catch (IOException e) {
1182                                         e.printStackTrace();
1183                                 }
1184                 }
1185         }
1186 }