X-Git-Url: http://plrg.eecs.uci.edu/git/?p=cdsspec-compiler.git;a=blobdiff_plain;f=src%2Fedu%2Fuci%2Feecs%2FspecCompiler%2FcodeGenerator%2FCodeGenerator.java;h=30e185d71ff7303d1e2c4b79c28001977b8330d5;hp=ab3e7ec9b7b50ba0f5ae2f4a160ed69841a9c305;hb=0332e0e5575b7d717bccad0b53f7a4b87c1ca969;hpb=1ea8394d222ead2d8e413359d536fb5c2b1f14f4 diff --git a/src/edu/uci/eecs/specCompiler/codeGenerator/CodeGenerator.java b/src/edu/uci/eecs/specCompiler/codeGenerator/CodeGenerator.java index ab3e7ec..30e185d 100644 --- a/src/edu/uci/eecs/specCompiler/codeGenerator/CodeGenerator.java +++ b/src/edu/uci/eecs/specCompiler/codeGenerator/CodeGenerator.java @@ -6,18 +6,27 @@ 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.HashSet; +import java.util.Iterator; import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct; import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct; +import edu.uci.eecs.specCompiler.specExtraction.ClassEndConstruct; +import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface; import edu.uci.eecs.specCompiler.specExtraction.Construct; +import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct; +import edu.uci.eecs.specCompiler.specExtraction.FunctionHeader; 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.SpecConstruct; +import edu.uci.eecs.specCompiler.specExtraction.SourceFileInfo; import edu.uci.eecs.specCompiler.specExtraction.SpecExtractor; -import edu.uci.eecs.specCompiler.specExtraction.SpecNotMatchException; /** *

@@ -34,25 +43,20 @@ public class CodeGenerator { private File[] srcFiles; - private HashMap> contents; + private HashMap srcFilesInfo; private HashMap> codeAdditions; public CodeGenerator(File[] srcFiles) { this.srcFiles = srcFiles; - this.contents = new HashMap>(); - readSrcFiles(); - this.codeAdditions = new HashMap>(); - _extractor = new SpecExtractor(); + _extractor.extract(srcFiles); - try { - _extractor.extract(srcFiles); - } catch (SpecNotMatchException e1) { - e1.printStackTrace(); - } + this.srcFilesInfo = _extractor.srcFilesInfo; - _semantics = new SemanticsChecker(_extractor.getConstructs()); + this.codeAdditions = new HashMap>(); + + _semantics = new SemanticsChecker(_extractor); try { _semantics.check(); System.out.println(_semantics); @@ -61,159 +65,250 @@ public class CodeGenerator { } } - private ArrayList readSrcFile(File f) throws IOException { - BufferedReader bf = new BufferedReader(new FileReader(f)); - ArrayList content = new ArrayList(); - String curLine; - while ((curLine = bf.readLine()) != null) { - content.add(curLine); - } - return content; - } - - private void readSrcFiles() { - for (int i = 0; i < srcFiles.length; i++) { - File f = srcFiles[i]; - if (!contents.containsKey(f)) { - try { - contents.put(f, readSrcFile(f)); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } - /** *

* Generate all the global code, including the "@DefineVar" in each * "@Interface" define *

*/ - private void globalConstruct2Code(SpecConstruct inst) { - int lineNum = inst.endLineNum + 1; - GlobalConstruct construct = (GlobalConstruct) inst.construct; - ArrayList newCode = new ArrayList(); - - // Generate the inner class definition - newCode.add("class Sequential {\n"); - newCode.add("public:\n"); - - // Generate the code in global construct first - SequentialDefineSubConstruct globalCode = construct.code; - breakCodeLines(newCode, globalCode.declareVar); - breakCodeLines(newCode, globalCode.defineFunc); - - // Generate code from the DefineVar, __COND_SAT__ and __ID__ - - - // Generate the end of the inner class definition - newCode.add("};\n"); -// printCode(newCode); - - CodeAddition addition = new CodeAddition(lineNum, newCode); - if (!codeAdditions.containsKey(inst.file)) { - codeAdditions.put(inst.file, new ArrayList()); + private void globalConstruct2Code(GlobalConstruct construct) { + ArrayList newCode = CodeVariables.generateGlobalVarDeclaration( + _semantics, construct); + // Add it to the codeAdditions + if (!codeAdditions.containsKey(construct.file)) { + codeAdditions.put(construct.file, new ArrayList()); + } + CodeAddition addition = new CodeAddition(construct.beginLineNum, + newCode); + codeAdditions.get(construct.file).add(addition); + newCode = CodeVariables.generateStaticVarDefine(_semantics, construct); + if (newCode.size() > 0) { + addition = new CodeAddition( + _semantics.getClassEndConstruct().beginLineNum, newCode); + codeAdditions.get(construct.file).add(addition); } - codeAdditions.get(inst.file).add(addition); } - - private void breakCodeLines(ArrayList newCode, String code) { - int begin = 0, end = 0; - while (end < code.length()) { - if (code.charAt(end) == '\n') { - String line = code.substring(begin, end); - newCode.add(line); - begin = end + 1; + + // Wrap the interface and then renaem it + private void interface2Code(InterfaceConstruct 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 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()); + } + 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()); } - end++; + codeAdditions.get(defineConstruct.file).add(addition); + } else { // No declaration needed but should add forward declaration in + // Class + // Last generate the definition + newCode = new ArrayList(); + if (_semantics.getOption("CLASS") == null) { + newCode.addAll(CodeVariables + .generateInterfaceWrapperDeclaration(_semantics, + construct)); + } + newCode.addAll(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()); + } + codeAdditions.get(construct.file).add(addition); } + + // Don't forget to rename the interface + CodeVariables.renameInterface(_semantics, construct); } - - private void printCode(ArrayList code) { - for (int i = 0; i < code.size(); i++) { - System.out.println(code.get(i)); + + private void potentialCPDefine2Code(PotentialCPDefineConstruct construct) { + int lineNum = construct.beginLineNum; + ArrayList newCode = CodeVariables.generatePotentialCPDefine( + _semantics, construct); + + CodeAddition addition = new CodeAddition(lineNum, newCode); + if (!codeAdditions.containsKey(construct.file)) { + codeAdditions.put(construct.file, new ArrayList()); } + codeAdditions.get(construct.file).add(addition); } - private void interface2Code(SpecConstruct inst) { - int lineNum = inst.endLineNum + 1; - GlobalConstruct construct = (GlobalConstruct) inst.construct; - ArrayList newCode = new ArrayList(); - - + private void CPDefine2Code(CPDefineConstruct construct) { + int lineNum = construct.beginLineNum; + ArrayList newCode = CodeVariables.generateCPDefine(_semantics, + construct); + CodeAddition addition = new CodeAddition(lineNum, newCode); - if (!codeAdditions.containsKey(inst.file)) { - codeAdditions.put(inst.file, new ArrayList()); + if (!codeAdditions.containsKey(construct.file)) { + codeAdditions.put(construct.file, new ArrayList()); } - codeAdditions.get(inst.file).add(addition); + codeAdditions.get(construct.file).add(addition); } - private void potentialCP2Code(SpecConstruct inst) { - int lineNum = inst.endLineNum + 1; - GlobalConstruct construct = (GlobalConstruct) inst.construct; - ArrayList newCode = new ArrayList(); - - + private void CPDefineCheck2Code(CPDefineCheckConstruct construct) { + int lineNum = construct.beginLineNum; + ArrayList newCode = CodeVariables.generateCPDefineCheck( + _semantics, construct); + CodeAddition addition = new CodeAddition(lineNum, newCode); - if (!codeAdditions.containsKey(inst.file)) { - codeAdditions.put(inst.file, new ArrayList()); + if (!codeAdditions.containsKey(construct.file)) { + codeAdditions.put(construct.file, new ArrayList()); } - codeAdditions.get(inst.file).add(addition); + codeAdditions.get(construct.file).add(addition); } - private void CPDefine2Code(SpecConstruct inst) { - int lineNum = inst.endLineNum + 1; - GlobalConstruct construct = (GlobalConstruct) inst.construct; - ArrayList newCode = new ArrayList(); - - + /** + private void ClassEnd2Code(ClassEndConstruct construct) { + int lineNum = construct.beginLineNum; + ArrayList newCode = CodeVariables.generateStaticVarDefine(_semantics, + _semantics.getGlobalConstruct()); + CodeAddition addition = new CodeAddition(lineNum, newCode); - if (!codeAdditions.containsKey(inst.file)) { - codeAdditions.put(inst.file, new ArrayList()); + if (!codeAdditions.containsKey(construct.file)) { + codeAdditions.put(construct.file, new ArrayList()); } - codeAdditions.get(inst.file).add(addition); + codeAdditions.get(construct.file).add(addition); } - - private void CPDefineCheck2Code(SpecConstruct inst) { - int lineNum = inst.endLineNum + 1; - GlobalConstruct construct = (GlobalConstruct) inst.construct; + */ + + private void EntryPoint2Code(EntryPointConstruct construct) { + int lineNum = construct.beginLineNum; ArrayList newCode = new ArrayList(); - - + newCode.addAll(CodeVariables.generateEntryPointInitCall()); + CodeAddition addition = new CodeAddition(lineNum, newCode); - if (!codeAdditions.containsKey(inst.file)) { - codeAdditions.put(inst.file, new ArrayList()); + if (!codeAdditions.containsKey(construct.file)) { + codeAdditions.put(construct.file, new ArrayList()); } - codeAdditions.get(inst.file).add(addition); + codeAdditions.get(construct.file).add(addition); + } + + private ArrayList insertAnnotation2Src( + ArrayList additions, ArrayList content) { + int totalSize = content.size(); + for (int i = 0; i < additions.size(); i++) { + totalSize += additions.size(); + } + ArrayList newContent = new ArrayList(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++) { - SpecConstruct inst = _semantics.constructs.get(i); - Construct construct = inst.construct; + Construct construct = _semantics.constructs.get(i); if (construct instanceof GlobalConstruct) { - globalConstruct2Code(inst); + globalConstruct2Code((GlobalConstruct) construct); } else if (construct instanceof InterfaceConstruct) { - interface2Code(inst); + interface2Code((InterfaceConstruct) construct); } else if (construct instanceof PotentialCPDefineConstruct) { - potentialCP2Code(inst); + potentialCPDefine2Code((PotentialCPDefineConstruct) construct); } else if (construct instanceof CPDefineConstruct) { - CPDefine2Code(inst); + CPDefine2Code((CPDefineConstruct) construct); } else if (construct instanceof CPDefineCheckConstruct) { - CPDefineCheck2Code(inst); + CPDefineCheck2Code((CPDefineCheckConstruct) construct); + } else if (construct instanceof EntryPointConstruct) { + EntryPoint2Code((EntryPointConstruct) construct); } } + +// ClassEndConstruct endConstruct = _semantics.getClassEndConstruct(); +// if (endConstruct != null) { +// ClassEnd2Code(endConstruct); +// } + + // Sort code additions + HashSet headers = CodeVariables.getAllHeaders(_semantics); + ArrayList headerCode = new ArrayList(); + for (String header : headers) { + headerCode.add("#include " + header); + } + for (File file : codeAdditions.keySet()) { + ArrayList additions = codeAdditions.get(file); + + if (additions.size() == 0) // Simply do nothing + continue; + ArrayList content = _semantics.srcFilesInfo.get(file).content; + Collections.sort(additions, CodeAddition.lineNumComparator); + // Insert generated annotation to the source files + ArrayList newContent = insertAnnotation2Src(additions, + content); + ArrayList finalContent = new ArrayList( + headerCode.size() + newContent.size()); + finalContent.addAll(headerCode); + finalContent.addAll(newContent); + // Write it back to file + ParserUtils.write2File(file, finalContent); + } } public static void main(String[] argvs) { String homeDir = Environment.HOME_DIRECTORY; File[] srcFiles = { - // 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/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/main.c"), +// new File(homeDir + "/benchmark/ms-queue/my_queue.h") }; + +// new File(homeDir + "/benchmark/read-copy-update/rcu.cc") }; + +// new File(homeDir + +// "/benchmark/chase-lev-deque-bugfix/deque.c"), +// new File(homeDir + +// "/benchmark/chase-lev-deque-bugfix/main.c"), +// new File(homeDir + +// "/benchmark/chase-lev-deque-bugfix/deque.h") }; + +// new File(homeDir + "/benchmark/mcs-lock/mcs-lock.cc"), +// new File(homeDir + "/benchmark/mcs-lock/mcs-lock.h") }; + +// new File(homeDir + "/benchmark/spsc-bugfix/spsc-queue.cc"), +// new File(homeDir + "/benchmark/spsc-bugfix/eventcount.h"), +// new File(homeDir + "/benchmark/spsc-bugfix/queue.h") }; + + CodeGenerator gen = new CodeGenerator(srcFiles); gen.generateCode(); }