1 package edu.uci.eecs.specExtraction;
4 import java.util.ArrayList;
5 import java.util.regex.Matcher;
6 import java.util.regex.Pattern;
8 import edu.uci.eecs.specExtraction.SpecUtils.IntObj;
9 import edu.uci.eecs.specExtraction.SpecUtils.Primitive;
13 * This class is a subclass of Construct. It represents a complete global state
20 public class GlobalConstruct extends Construct {
21 public final ArrayList<VariableDeclaration> declState;
22 public final Code initState;
23 public final Code copyState;
24 public final Code finalState;
25 public final Code printState;
26 public final ArrayList<CommutativityRule> commutativityRules;
28 public final boolean autoGenCopy;
30 public GlobalConstruct(File file, int beginLineNum,
31 ArrayList<String> annotations) throws WrongAnnotationException {
32 super(file, beginLineNum);
33 declState = new ArrayList<VariableDeclaration>();
34 initState = new Code();
35 copyState = new Code();
36 finalState = new Code();
37 printState = new Code();
38 commutativityRules = new ArrayList<CommutativityRule>();
40 processAnnotations(annotations);
42 if (copyState.isEmpty()) {
43 Code code = generateAutoCopyFunction();
44 copyState.addLines(code);
53 * This function will automatically generate the copy statements for
54 * supported types if the user has not defined the "@Copy" primitive
57 * @return The auto-generated copy statements
58 * @throws WrongAnnotationException
60 private Code generateAutoCopyFunction() throws WrongAnnotationException {
61 Code code = new Code();
62 for (VariableDeclaration decl : declState) {
63 String type = decl.type;
64 String name = decl.name;
66 if (type.equals("int") || type.equals("unsigned")
67 || type.equals("unsigned int")
68 || type.equals("int unsigned") || type.equals("double")
69 || type.equals("double") || type.equals("bool")) {
71 code.addLine(SpecNaming.NewStateInst + "->" + name + " = "
72 + SpecNaming.OldStateInst + "->" + name + ";");
73 } else if (type.equals("IntList") || type.equals("IntSet")
74 || type.equals("IntMap")) {
76 // New->q = IntList(OLD->q);
77 code.addLine(SpecNaming.NewStateInst + "->" + name + " = "
78 + type + "(" + SpecNaming.OldStateInst + "->" + name
80 } else if (type.equals("IntList *") || type.equals("IntSet *")
81 || type.equals("IntMap *")) {
82 // Supported pointer types
83 // New->q = new IntList(*OLD->q);
84 String originalType = SpecUtils.trimSpace(type
86 code.addLine(SpecNaming.NewStateInst + "->" + name + " = new "
87 + originalType + "(*" + SpecNaming.OldStateInst + "->"
90 WrongAnnotationException
93 "You have types in the state declaration that we do not support auto-gen copy function.");
102 * Assert that the global state primitive is valid; if not, throws an
109 * The primitive that we have extracted earlier
110 * @throws WrongAnnotationException
112 private void assertValidPrimitive(File file, Primitive primitive)
113 throws WrongAnnotationException {
114 int lineNum = primitive.beginLineNum;
115 String name = primitive.name;
116 if (!name.equals(SpecNaming.DeclareState)
117 && !name.equals(SpecNaming.InitalState)
118 && !name.equals(SpecNaming.CopyState)
119 && !name.equals(SpecNaming.FinalState)
120 && !name.equals(SpecNaming.Commutativity)
121 && !name.equals(SpecNaming.PrintState)) {
122 WrongAnnotationException.err(file, lineNum, name
123 + " is NOT a valid CDSSpec global state primitive.");
129 * Given a "@DeclareState" primitive that has a list of strings of
130 * declarations, we initialize our local "declState" members.
133 * @throws WrongAnnotationException
135 private void processDeclState(Primitive primitive)
136 throws WrongAnnotationException {
137 for (int i = 0; i < primitive.contents.size(); i++) {
138 int lineNum = i + primitive.beginLineNum;
139 String declLine = primitive.contents.get(i);
140 VariableDeclaration tmp = new VariableDeclaration(file, lineNum,
148 * Given a "@DeclareState" primitive that has a list of strings of
149 * declarations, we initialize our local "declState" members.
152 * @throws WrongAnnotationException
154 private void processCommutativity(Primitive primitive)
155 throws WrongAnnotationException {
156 // Mathch commutativity rule
157 Pattern regexpCommute = Pattern
158 .compile("\\s*(\\w+)\\s*<->\\s*(\\w+)\\s*\\((.*)\\)\\s*$");
159 Matcher matcherCommute = regexpCommute.matcher("");
161 for (int i = 0; i < primitive.contents.size(); i++) {
162 // FIXME: Currently we only allow a one-line commutativity rule
163 int curLineNum = primitive.beginLineNum + i;
164 String line = primitive.contents.get(i);
165 matcherCommute.reset(line);
166 if (matcherCommute.find()) {
167 String method1 = matcherCommute.group(1);
168 String method2 = matcherCommute.group(2);
169 String code = matcherCommute.group(3);
170 String rule = SpecUtils.trimSpace(SpecUtils
171 .trimTrailingCommentSymbol(code));
172 commutativityRules.add(new CommutativityRule(method1, method2,
175 WrongAnnotationException
178 "The @Commutativity annotation should be: @Commutativity: Method1 <-> Method2 (condition)\n\t"
179 + "Problematic line: \"" + line + "\"");
181 // Done with processing the current commutativity
185 private void processAnnotations(ArrayList<String> annotations)
186 throws WrongAnnotationException {
187 IntObj curIdx = new IntObj(0);
188 Primitive primitive = null;
190 while ((primitive = SpecUtils.extractPrimitive(file, beginLineNum,
191 annotations, curIdx)) != null) {
192 String name = primitive.name;
193 assertValidPrimitive(file, primitive);
194 if (primitive.contents.size() == 0)
196 if (name.equals(SpecNaming.DeclareState)) {
197 processDeclState(primitive);
198 } else if (name.equals(SpecNaming.InitalState)) {
199 initState.addLines(primitive.contents);
200 } else if (name.equals(SpecNaming.CopyState)) {
201 copyState.addLines(primitive.contents);
202 } else if (name.equals(SpecNaming.FinalState)) {
203 finalState.addLines(primitive.contents);
204 } else if (name.equals(SpecNaming.PrintState)) {
205 printState.addLines(primitive.contents);
206 } else if (name.equals(SpecNaming.Commutativity)) {
207 processCommutativity(primitive);
212 public String toString() {
213 StringBuilder sb = new StringBuilder("");
214 sb.append(super.toString() + "\n");
215 sb.append("@DeclareState:\n");
216 sb.append(declState);
218 sb.append("@InitState:\n");
219 sb.append(initState);
220 if (!printState.isEmpty()) {
221 sb.append("@Print:\n");
222 sb.append(printState);
225 for (int i = 0; i < commutativityRules.size(); i++) {
226 sb.append("@Commutativity: " + commutativityRules + "\n");
228 return sb.toString();