1 package edu.uci.eecs.specCompiler.codeGenerator;
3 import java.io.BufferedReader;
5 import java.io.FileNotFoundException;
6 import java.io.FileReader;
7 import java.io.IOException;
8 import java.util.ArrayList;
9 import java.util.HashMap;
10 import java.util.Iterator;
12 import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct.DefineVar;
13 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
14 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
15 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
16 import edu.uci.eecs.specCompiler.specExtraction.Construct;
17 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
18 import edu.uci.eecs.specCompiler.specExtraction.IDExtractor;
19 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
20 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
21 import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
22 import edu.uci.eecs.specCompiler.specExtraction.SpecExtractor;
26 * This class will generate the annotated C code that can run on the current
33 public class CodeGenerator {
34 private SemanticsChecker _semantics;
35 private SpecExtractor _extractor;
37 private File[] srcFiles;
39 private HashMap<File, ArrayList<String>> contents;
41 private HashMap<File, ArrayList<CodeAddition>> codeAdditions;
43 private ArrayList<String> globalContent;
45 public CodeGenerator(File[] srcFiles) {
46 this.srcFiles = srcFiles;
47 _extractor = new SpecExtractor();
48 _extractor.extract(srcFiles);
50 this.contents = _extractor.contents;
52 this.globalContent = null;
53 this.codeAdditions = new HashMap<File, ArrayList<CodeAddition>>();
56 _semantics = new SemanticsChecker(_extractor.constructs);
59 System.out.println(_semantics);
60 } catch (SemanticsCheckerException e) {
65 private ArrayList<String> readSrcFile(File f) throws IOException {
66 BufferedReader bf = new BufferedReader(new FileReader(f));
67 ArrayList<String> content = new ArrayList<String>();
69 while ((curLine = bf.readLine()) != null) {
77 * Generate all the global code, including the "@DefineVar" in each
81 private void globalConstruct2Code(GlobalConstruct construct) {
82 ArrayList<String> newCode = CodeVariables.generateGlobalVarDeclaration(
83 _semantics, construct);
84 // Record the global content array to generate the new file
85 globalContent = newCode;
88 // Mainly rename and wrap the interface
89 private void interface2Code(InterfaceConstruct construct)
90 throws InterfaceWrongFormatException {
91 int lineNum = construct.begin + 1;
93 // Rename the interface name
94 File file = inst.file;
95 String funcDecl = inst.interfaceDeclBody;
96 // Rename the function declaration
97 String funcName = renameInterface(inst);
98 // Also rename the function definition if it's separated from the
100 SpecConstruct definition = _semantics.interfaceName2DefineConstruct
101 .get(construct.name);
102 if (definition != null) {
103 String funcDefintionName = renameInterface(definition);
104 assert (funcDefintionName.equals(funcName));
107 // Generate new wrapper
108 ArrayList<String> newCode = CodeVariables.generateInterfaceWrapper(
110 // Add it to the codeAdditions
111 CodeAddition addition = new CodeAddition(lineNum, newCode);
112 if (!codeAdditions.containsKey(inst.file)) {
113 codeAdditions.put(inst.file, new ArrayList<CodeAddition>());
115 codeAdditions.get(inst.file).add(addition);
118 // Returns the function name that has been renamed and replace the old line
119 private String renameInterface(Construct inst)
120 throws InterfaceWrongFormatException {
121 String funcDecl = inst.interfaceDeclBody;
122 ArrayList<String> content = contents.get(inst.file);
124 // Depending on "(" to find the function name, so it doesn't matter if
125 // there's any template
126 int beginIdx = funcDecl.indexOf('(');
127 if (beginIdx == -1) {
128 throw new InterfaceWrongFormatException(funcDecl
129 + "\n has wrong format!");
131 IDExtractor idExtractor = new IDExtractor(funcDecl, beginIdx);
132 String funcName = idExtractor.getPrevID();
133 int idBeginIdx = idExtractor.getIDBeginIdx(), idEndIdx = idExtractor
134 .getIDEndIdx(), idLineBeginIdx = idExtractor.lineBeginIdxOfID(), idLineEndIdx = idExtractor
136 String newLine = funcDecl.substring(idLineBeginIdx, idBeginIdx)
137 + CodeVariables.SPEC_INTERFACE_WRAPPER + funcName
138 + funcDecl.substring(idEndIdx + 1, idLineEndIdx + 1);
140 int lineNumOfID = idExtractor.lineNumOfID();
141 // Be careful: lineNum - 1 -> index of content array
142 content.set(inst.endLineNum + lineNumOfID, newLine);
146 private void potentialCPDefine2Code(PotentialCPDefineConstruct construct) {
147 int lineNum = construct.beginLineNum;
148 ArrayList<String> newCode = new ArrayList<String>();
150 CodeAddition addition = new CodeAddition(lineNum, newCode);
151 if (!codeAdditions.containsKey(construct.file)) {
152 codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
154 codeAdditions.get(construct.file).add(addition);
157 private void CPDefine2Code(CPDefineConstruct construct) {
158 int lineNum = construct.beginLineNum;
159 ArrayList<String> newCode = new ArrayList<String>();
161 CodeAddition addition = new CodeAddition(lineNum, newCode);
162 if (!codeAdditions.containsKey(construct.file)) {
163 codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
165 codeAdditions.get(construct.file).add(addition);
168 private void CPDefineCheck2Code(CPDefineCheckConstruct construct) {
169 int lineNum = construct.beginLineNum;
170 ArrayList<String> newCode = new ArrayList<String>();
172 CodeAddition addition = new CodeAddition(lineNum, newCode);
173 if (!codeAdditions.containsKey(construct.file)) {
174 codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
176 codeAdditions.get(construct.file).add(addition);
179 public void generateCode() {
180 for (int i = 0; i < _semantics.constructs.size(); i++) {
181 Construct construct = _semantics.constructs.get(i);
182 if (construct instanceof GlobalConstruct) {
183 globalConstruct2Code((GlobalConstruct) construct);
184 } else if (construct instanceof InterfaceConstruct) {
186 interface2Code((InterfaceConstruct) construct);
187 } catch (InterfaceWrongFormatException e) {
190 } else if (construct instanceof PotentialCPDefineConstruct) {
191 // potentialCP2Code(inst);
192 } else if (construct instanceof CPDefineConstruct) {
193 // CPDefine2Code(inst);
194 } else if (construct instanceof CPDefineCheckConstruct) {
195 // CPDefineCheck2Code(inst);
200 public static void main(String[] argvs) {
201 String homeDir = Environment.HOME_DIRECTORY;
203 // new File(homeDir + "/benchmark/linuxrwlocks/linuxrwlocks.c"),
205 + "/benchmark/cliffc-hashtable/simplified_cliffc_hashtable.h"), };
206 // new File(homeDir + "/benchmark/ms-queue/my_queue.c"),
207 // new File(homeDir + "/benchmark/ms-queue/my_queue.h") };
208 CodeGenerator gen = new CodeGenerator(srcFiles);