import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
+import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct.DefineVar;
import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
+import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
import edu.uci.eecs.specCompiler.specExtraction.Construct;
import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
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.SpecExtractor;
-import edu.uci.eecs.specCompiler.specExtraction.SpecNotMatchException;
/**
* <p>
private HashMap<File, ArrayList<CodeAddition>> codeAdditions;
+ private ArrayList<String> globalContent;
+
public CodeGenerator(File[] srcFiles) {
this.srcFiles = srcFiles;
this.contents = new HashMap<File, ArrayList<String>>();
+ this.globalContent = null;
readSrcFiles();
this.codeAdditions = new HashMap<File, ArrayList<CodeAddition>>();
_extractor = new SpecExtractor();
- try {
- _extractor.extract(srcFiles);
- } catch (SpecNotMatchException e1) {
- e1.printStackTrace();
- }
+ _extractor.extract(srcFiles);
_semantics = new SemanticsChecker(_extractor.getConstructs());
try {
* "@Interface" define
* </p>
*/
- private void globalConstruct2Code(SpecConstruct inst) {
- int lineNum = inst.endLineNum + 1;
- GlobalConstruct construct = (GlobalConstruct) inst.construct;
- ArrayList<String> newCode = new ArrayList<String>();
-
- // 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<CodeAddition>());
- }
- codeAdditions.get(inst.file).add(addition);
+ private void globalConstruct2Code(GlobalConstruct construct) {
+ ArrayList<String> newCode = CodeVariables.generateGlobalVarDeclaration(
+ _semantics, construct);
+ // Record the global content array to generate the new file
+ globalContent = newCode;
}
-
- private void breakCodeLines(ArrayList<String> 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;
- }
- end++;
- }
- }
-
- private void printCode(ArrayList<String> code) {
- for (int i = 0; i < code.size(); i++) {
- System.out.println(code.get(i));
+
+ // Mainly rename and wrap the interface
+ private void interface2Code(InterfaceConstruct construct)
+ throws InterfaceWrongFormatException {
+ int lineNum = construct.begin + 1;
+
+ // Rename the interface name
+ File file = inst.file;
+ String funcDecl = inst.interfaceDeclBody;
+ // Rename the function declaration
+ String funcName = renameInterface(inst);
+ // Also rename the function definition if it's separated from the
+ // declaration
+ SpecConstruct definition = _semantics.interfaceName2DefineConstruct
+ .get(construct.name);
+ if (definition != null) {
+ String funcDefintionName = renameInterface(definition);
+ assert (funcDefintionName.equals(funcName));
}
- }
- private void interface2Code(SpecConstruct inst) {
- int lineNum = inst.endLineNum + 1;
- GlobalConstruct construct = (GlobalConstruct) inst.construct;
- ArrayList<String> newCode = new ArrayList<String>();
-
-
+ // Generate new wrapper
+ ArrayList<String> newCode = CodeVariables.generateInterfaceWrapper(
+ _semantics, inst);
+ // Add it to the codeAdditions
CodeAddition addition = new CodeAddition(lineNum, newCode);
if (!codeAdditions.containsKey(inst.file)) {
codeAdditions.put(inst.file, new ArrayList<CodeAddition>());
codeAdditions.get(inst.file).add(addition);
}
- private void potentialCP2Code(SpecConstruct inst) {
- int lineNum = inst.endLineNum + 1;
- GlobalConstruct construct = (GlobalConstruct) inst.construct;
+ // Returns the function name that has been renamed and replace the old line
+ private String renameInterface(Construct inst)
+ throws InterfaceWrongFormatException {
+ String funcDecl = inst.interfaceDeclBody;
+ ArrayList<String> content = contents.get(inst.file);
+
+ // Depending on "(" to find the function name, so it doesn't matter if
+ // there's any template
+ int beginIdx = funcDecl.indexOf('(');
+ if (beginIdx == -1) {
+ throw new InterfaceWrongFormatException(funcDecl
+ + "\n has wrong format!");
+ }
+ IDExtractor idExtractor = new IDExtractor(funcDecl, beginIdx);
+ String funcName = idExtractor.getPrevID();
+ int idBeginIdx = idExtractor.getIDBeginIdx(), idEndIdx = idExtractor
+ .getIDEndIdx(), idLineBeginIdx = idExtractor.lineBeginIdxOfID(), idLineEndIdx = idExtractor
+ .lineEndIdxOfID();
+ String newLine = funcDecl.substring(idLineBeginIdx, idBeginIdx)
+ + CodeVariables.SPEC_INTERFACE_WRAPPER + funcName
+ + funcDecl.substring(idEndIdx + 1, idLineEndIdx + 1);
+
+ int lineNumOfID = idExtractor.lineNumOfID();
+ // Be careful: lineNum - 1 -> index of content array
+ content.set(inst.endLineNum + lineNumOfID, newLine);
+ return funcName;
+ }
+
+ private void potentialCPDefine2Code(PotentialCPDefineConstruct construct) {
+ int lineNum = construct.beginLineNum;
ArrayList<String> newCode = new ArrayList<String>();
-
-
+
CodeAddition addition = new CodeAddition(lineNum, newCode);
- if (!codeAdditions.containsKey(inst.file)) {
- codeAdditions.put(inst.file, new ArrayList<CodeAddition>());
+ if (!codeAdditions.containsKey(construct.file)) {
+ codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
}
- 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;
+ private void CPDefine2Code(CPDefineConstruct construct) {
+ int lineNum = construct.beginLineNum;
ArrayList<String> newCode = new ArrayList<String>();
-
-
+
CodeAddition addition = new CodeAddition(lineNum, newCode);
- if (!codeAdditions.containsKey(inst.file)) {
- codeAdditions.put(inst.file, new ArrayList<CodeAddition>());
+ if (!codeAdditions.containsKey(construct.file)) {
+ codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
}
- 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 CPDefineCheck2Code(CPDefineCheckConstruct construct) {
+ int lineNum = construct.beginLineNum;
ArrayList<String> newCode = new ArrayList<String>();
-
-
+
CodeAddition addition = new CodeAddition(lineNum, newCode);
- if (!codeAdditions.containsKey(inst.file)) {
- codeAdditions.put(inst.file, new ArrayList<CodeAddition>());
+ if (!codeAdditions.containsKey(construct.file)) {
+ codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
}
- codeAdditions.get(inst.file).add(addition);
+ codeAdditions.get(construct.file).add(addition);
}
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);
+ try {
+ interface2Code((InterfaceConstruct) construct);
+ } catch (InterfaceWrongFormatException e) {
+ e.printStackTrace();
+ }
} else if (construct instanceof PotentialCPDefineConstruct) {
- potentialCP2Code(inst);
+ // potentialCP2Code(inst);
} else if (construct instanceof CPDefineConstruct) {
- CPDefine2Code(inst);
+ // CPDefine2Code(inst);
} else if (construct instanceof CPDefineCheckConstruct) {
- CPDefineCheck2Code(inst);
+ // CPDefineCheck2Code(inst);
}
}
}
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")
- };
+ + "/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") };
CodeGenerator gen = new CodeGenerator(srcFiles);
gen.generateCode();
}