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.CPDefineCheckConstruct;
13 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
14 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
15 import edu.uci.eecs.specCompiler.specExtraction.Construct;
16 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
17 import edu.uci.eecs.specCompiler.specExtraction.IDExtractor;
18 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
19 import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
20 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
21 import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
22 import edu.uci.eecs.specCompiler.specExtraction.SourceFileInfo;
23 import edu.uci.eecs.specCompiler.specExtraction.SpecExtractor;
27 * This class will generate the annotated C code that can run on the current
34 public class CodeGenerator {
35 private SemanticsChecker _semantics;
36 private SpecExtractor _extractor;
38 private File[] srcFiles;
40 private HashMap<File, SourceFileInfo> srcFilesInfo;
42 private HashMap<File, ArrayList<CodeAddition>> codeAdditions;
44 private ArrayList<String> globalContent;
46 public CodeGenerator(File[] srcFiles) {
47 this.srcFiles = srcFiles;
48 _extractor = new SpecExtractor();
49 _extractor.extract(srcFiles);
51 this.srcFilesInfo = _extractor.srcFilesInfo;
53 this.globalContent = null;
54 this.codeAdditions = new HashMap<File, ArrayList<CodeAddition>>();
57 _semantics = new SemanticsChecker(_extractor.getConstructs());
60 System.out.println(_semantics);
61 } catch (SemanticsCheckerException e) {
68 * Generate all the global code, including the "@DefineVar" in each
72 private void globalConstruct2Code(GlobalConstruct construct) {
73 ArrayList<String> newCode = CodeVariables.generateGlobalVarDeclaration(
74 _semantics, construct);
75 // Record the global content array to generate the new file
76 globalContent = newCode;
79 // Mainly rename and wrap the interface
80 private void interface2Code(InterfaceConstruct construct)
81 throws InterfaceWrongFormatException {
82 int lineNum = construct.beginLineNum;
85 // Rename the interface name
87 // Rename the function declaration
89 // Also rename the function definition if it's separated from the
91 InterfaceDefineConstruct definition = (InterfaceDefineConstruct) _semantics.interfaceName2DefineConstruct
93 if (definition != null) {
94 String funcDefintionName = renameInterface(definition);
95 assert (funcDefintionName.equals(funcName));
98 // Generate new wrapper
99 ArrayList<String> newCode = CodeVariables.generateInterfaceWrapper(
100 _semantics, construct);
101 // Add it to the codeAdditions
102 CodeAddition addition = new CodeAddition(lineNum, newCode);
103 if (!codeAdditions.containsKey(construct.file)) {
104 codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
106 codeAdditions.get(construct.file).add(addition);
109 // Returns the function name that has been renamed and replace the old line
110 private String renameInterface(Construct construct)
111 throws InterfaceWrongFormatException {
112 String funcDecl = "";
113 ArrayList<String> content = srcFilesInfo.get(construct.file).content;
115 // Depending on "(" to find the function name, so it doesn't matter if
116 // there's any template
117 int beginIdx = funcDecl.indexOf('(');
118 if (beginIdx == -1) {
119 throw new InterfaceWrongFormatException(funcDecl
120 + "\n has wrong format!");
122 IDExtractor idExtractor = new IDExtractor(funcDecl, beginIdx);
123 String funcName = idExtractor.getPrevID();
124 int idBeginIdx = idExtractor.getIDBeginIdx(), idEndIdx = idExtractor
125 .getIDEndIdx(), idLineBeginIdx = idExtractor.lineBeginIdxOfID(), idLineEndIdx = idExtractor
127 String newLine = funcDecl.substring(idLineBeginIdx, idBeginIdx)
128 + CodeVariables.SPEC_INTERFACE_WRAPPER + funcName
129 + funcDecl.substring(idEndIdx + 1, idLineEndIdx + 1);
131 int lineNumOfID = idExtractor.lineNumOfID();
132 // Be careful: lineNum - 1 -> index of content array
133 content.set(construct.beginLineNum - 1, newLine);
137 private void potentialCPDefine2Code(PotentialCPDefineConstruct construct) {
138 int lineNum = construct.beginLineNum;
139 ArrayList<String> newCode = new ArrayList<String>();
141 CodeAddition addition = new CodeAddition(lineNum, newCode);
142 if (!codeAdditions.containsKey(construct.file)) {
143 codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
145 codeAdditions.get(construct.file).add(addition);
148 private void CPDefine2Code(CPDefineConstruct construct) {
149 int lineNum = construct.beginLineNum;
150 ArrayList<String> newCode = new ArrayList<String>();
152 CodeAddition addition = new CodeAddition(lineNum, newCode);
153 if (!codeAdditions.containsKey(construct.file)) {
154 codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
156 codeAdditions.get(construct.file).add(addition);
159 private void CPDefineCheck2Code(CPDefineCheckConstruct construct) {
160 int lineNum = construct.beginLineNum;
161 ArrayList<String> newCode = new ArrayList<String>();
163 CodeAddition addition = new CodeAddition(lineNum, newCode);
164 if (!codeAdditions.containsKey(construct.file)) {
165 codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
167 codeAdditions.get(construct.file).add(addition);
170 public void generateCode() {
171 for (int i = 0; i < _semantics.constructs.size(); i++) {
172 Construct construct = _semantics.constructs.get(i);
173 if (construct instanceof GlobalConstruct) {
174 globalConstruct2Code((GlobalConstruct) construct);
175 } else if (construct instanceof InterfaceConstruct) {
177 interface2Code((InterfaceConstruct) construct);
178 } catch (InterfaceWrongFormatException e) {
181 } else if (construct instanceof PotentialCPDefineConstruct) {
182 // potentialCP2Code(inst);
183 } else if (construct instanceof CPDefineConstruct) {
184 // CPDefine2Code(inst);
185 } else if (construct instanceof CPDefineCheckConstruct) {
186 // CPDefineCheck2Code(inst);
191 public static void main(String[] argvs) {
192 String homeDir = Environment.HOME_DIRECTORY;
194 // new File(homeDir + "/benchmark/linuxrwlocks/linuxrwlocks.c"),
196 + "/benchmark/cliffc-hashtable/simplified_cliffc_hashtable.h"), };
197 // new File(homeDir + "/benchmark/ms-queue/my_queue.c"),
198 // new File(homeDir + "/benchmark/ms-queue/my_queue.h") };
199 CodeGenerator gen = new CodeGenerator(srcFiles);