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