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