fixed some bugs
[cdsspec-compiler.git] / src / edu / uci / eecs / specCompiler / codeGenerator / CodeGenerator.java
index d65258424fb63dea628b7eed8b11e572a59e9996..66bdca4ab408d740edb6a444ad684fc9fc48ee02 100644 (file)
@@ -6,6 +6,7 @@ import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 
@@ -19,6 +20,7 @@ import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
 import edu.uci.eecs.specCompiler.specExtraction.IDExtractor;
 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
 import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
+import edu.uci.eecs.specCompiler.specExtraction.ParserUtils;
 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
 import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
 import edu.uci.eecs.specCompiler.specExtraction.SourceFileInfo;
@@ -87,15 +89,48 @@ public class CodeGenerator {
 
        // Mainly rename and wrap the interface
        private void interface2Code(InterfaceConstruct construct) {
-               ArrayList<String> newCode = CodeVariables.generateInterfaceWrapper(
-                               _semantics, construct);
-               int lineNum = construct.beginLineNum;
-               // Add it to the codeAdditions
-               CodeAddition addition = new CodeAddition(lineNum, newCode);
-               if (!codeAdditions.containsKey(construct.file)) {
-                       codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
+               // First rename the interface
+               CodeVariables.renameInterface(_semantics, construct);
+
+               // If there's no define construct for it, we generate the wrapper just
+               // in place without declaration
+               InterfaceDefineConstruct defineConstruct = _semantics.interfaceName2DefineConstruct
+                               .get(construct.name);
+               ArrayList<String> newCode;
+               int lineNum;
+               CodeAddition addition;
+               // Then generate the wrapper if necessary
+               if (defineConstruct != null) { // Need to have a wrapper declaration
+                       newCode = CodeVariables.generateInterfaceWrapperDeclaration(_semantics, construct);
+                       lineNum = construct.beginLineNum;
+                       // Add the wrapper declaration
+                       addition = new CodeAddition(lineNum, newCode);
+                       if (!codeAdditions.containsKey(construct.file)) {
+                               codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
+                       }
+                       codeAdditions.get(construct.file).add(addition);
+                       
+                       // Add the wrapper definition
+                       newCode = CodeVariables.generateInterfaceWrapperDefinition(_semantics, construct);
+                       lineNum = defineConstruct.beginLineNum;
+                       // Add the wrapper declaration
+                       addition = new CodeAddition(lineNum, newCode);
+                       if (!codeAdditions.containsKey(defineConstruct.file)) {
+                               codeAdditions.put(defineConstruct.file, new ArrayList<CodeAddition>());
+                       }
+                       codeAdditions.get(defineConstruct.file).add(addition);
+               } else { // No declaration needed
+                       // Last generate the definition
+                       newCode = CodeVariables.generateInterfaceWrapperDefinition(_semantics, construct);
+                       lineNum = construct.beginLineNum;
+                       // Add the wrapper declaration
+                       addition = new CodeAddition(lineNum, newCode);
+                       if (!codeAdditions.containsKey(construct.file)) {
+                               codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
+                       }
+                       codeAdditions.get(construct.file).add(addition);
                }
-               codeAdditions.get(construct.file).add(addition);
+               
        }
 
        private void potentialCPDefine2Code(PotentialCPDefineConstruct construct) {
@@ -146,6 +181,28 @@ public class CodeGenerator {
                codeAdditions.get(construct.file).add(addition);
        }
 
+       private ArrayList<String> insertAnnotation2Src(
+                       ArrayList<CodeAddition> additions, ArrayList<String> content) {
+               int totalSize = content.size();
+               for (int i = 0; i < additions.size(); i++) {
+                       totalSize += additions.size();
+               }
+               ArrayList<String> newContent = new ArrayList<String>(totalSize);
+               int curSrcLine = 0;
+               for (int i = 0; i < additions.size(); i++) {
+                       CodeAddition addition = additions.get(i);
+                       if (curSrcLine < addition.lineNum) {
+                               // Be careful, subList is the interval [begin, end)
+                               newContent
+                                               .addAll(content.subList(curSrcLine, addition.lineNum));
+                               curSrcLine = addition.lineNum;
+                       }
+                       newContent.addAll(addition.newCode);
+               }
+               newContent.addAll(content.subList(curSrcLine, content.size()));
+               return newContent;
+       }
+
        public void generateCode() {
                for (int i = 0; i < _semantics.constructs.size(); i++) {
                        Construct construct = _semantics.constructs.get(i);
@@ -159,18 +216,38 @@ public class CodeGenerator {
                                CPDefine2Code((CPDefineConstruct) construct);
                        } else if (construct instanceof CPDefineCheckConstruct) {
                                CPDefineCheck2Code((CPDefineCheckConstruct) construct);
+                       } else if (construct instanceof EntryPointConstruct) {
+                               EntryPoint2Code((EntryPointConstruct) construct);
                        }
                }
+               // Sort code additions
+               for (File file : codeAdditions.keySet()) {
+                       ArrayList<CodeAddition> additions = codeAdditions.get(file);
+                       if (additions.size() == 0) // Simply do nothing, already written
+                                                                               // once
+                               continue;
+                       ArrayList<String> content = _semantics.srcFilesInfo.get(file).content;
+                       Collections.sort(additions, CodeAddition.lineNumComparator);
+                       // Insert generated annotation to the source files
+                       ArrayList<String> newContent = insertAnnotation2Src(additions,
+                                       content);
+                       // Write it back to file
+                       ParserUtils.write2File(file, newContent);
+               }
+
        }
 
        public static void main(String[] argvs) {
                String homeDir = Environment.HOME_DIRECTORY;
                File[] srcFiles = {
-               // new File(homeDir + "/benchmark/linuxrwlocks/linuxrwlocks.c"),
+               // new File(Environment.MODEL_CHECKER_TEST_DIR +
+               // "/backup_linuxrwlocks.c") };
+               // new File(homeDir + "/benchmark/linuxrwlocks/linuxrwlocks.c") };
                new File(homeDir
                                + "/benchmark/cliffc-hashtable/simplified_cliffc_hashtable.h"), };
-//              new File(homeDir + "/benchmark/ms-queue/my_queue.c"),
-//              new File(homeDir + "/benchmark/ms-queue/my_queue.h") };
+               // new File(homeDir + "/benchmark/ms-queue/my_queue.c"),
+               // new File(homeDir + "/benchmark/ms-queue/my_queue.c") };
+               // new File(homeDir + "/benchmark/test/test.c") };
                CodeGenerator gen = new CodeGenerator(srcFiles);
                gen.generateCode();
        }