generating code
[cdsspec-compiler.git] / src / edu / uci / eecs / specCompiler / codeGenerator / SemanticsChecker.java
1 package edu.uci.eecs.specCompiler.codeGenerator;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.HashSet;
6
7 import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct.DefineVar;
8 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
9 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
10 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
11 import edu.uci.eecs.specCompiler.specExtraction.Construct;
12 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
13 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
14 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
15 import edu.uci.eecs.specCompiler.specExtraction.SpecConstruct;
16
17 public class SemanticsChecker {
18         public final ArrayList<SpecConstruct> constructs;
19         public final HashMap<String, SpecConstruct> CPLabel2Construct;
20         public final HashMap<String, SpecConstruct> potentialCPLabel2Construct;
21         public final HashMap<String, SpecConstruct> interfaceName2Construct;
22         public final HashMap<String, ArrayList<InterfaceConstruct>> CPLabel2InterfaceConstruct;
23         public final HashSet<DefineVar> defineVars;
24
25         public SemanticsChecker(ArrayList<SpecConstruct> constructs) {
26                 this.constructs = constructs;
27                 this.CPLabel2Construct = new HashMap<String, SpecConstruct>();
28                 this.potentialCPLabel2Construct = new HashMap<String, SpecConstruct>();
29                 this.interfaceName2Construct = new HashMap<String, SpecConstruct>();
30                 this.CPLabel2InterfaceConstruct = new HashMap<String, ArrayList<InterfaceConstruct>>();
31                 this.defineVars = new HashSet<DefineVar>();
32         }
33
34         private void checkHBLabelConsistency(ConditionalInterface inst)
35                         throws SemanticsCheckerException {
36                 String interfaceName = inst.interfaceName,
37                                 label = inst.hbConditionLabel;
38                 if (!interfaceName2Construct.containsKey(interfaceName)) {
39                         throw new SemanticsCheckerException(
40                                         "In global construct, no interface \"" + interfaceName
41                                                         + "\"!");
42                 } else if (!label.equals("")){
43                         InterfaceConstruct iConstruct = (InterfaceConstruct) interfaceName2Construct
44                                         .get(interfaceName).construct;
45                         if (!iConstruct.hbConditions.containsKey(label)) {
46                                 throw new SemanticsCheckerException("Interface "
47                                                 + interfaceName + " doesn't contain HB_codition: "
48                                                 + label + "!");
49                         }
50                 }
51         }
52
53         private void checkLabelDuplication(Construct construct, String label)
54                         throws SemanticsCheckerException {
55                 if (potentialCPLabel2Construct.containsKey(label) ||
56                                 CPLabel2Construct.containsKey(label))
57                         throw new SemanticsCheckerException("In construct: " + construct
58                                         + "\"" + label + "\" has duplication.");
59         }
60
61         public void check() throws SemanticsCheckerException {
62                 boolean hasGlobalConstruct = false;
63                 // First grab the information from the interface
64                 for (int i = 0; i < constructs.size(); i++) {
65                         Construct inst = constructs.get(i).construct;
66                         if (inst instanceof InterfaceConstruct) {
67                                 InterfaceConstruct iConstruct = (InterfaceConstruct) inst;
68                                 interfaceName2Construct.put(iConstruct.name, constructs.get(i));
69                                 for (int j = 0; j < iConstruct.action.defineVars.size(); j++) {
70                                         DefineVar var = iConstruct.action.defineVars.get(j);
71                                         var.renameVarName("__" + iConstruct.name + "_" + var.varName + "__");
72                                 }
73                                 
74                                 for (int j = 0; j < iConstruct.commitPointSet.size(); j++) {
75                                         String label = iConstruct.commitPointSet.get(j);
76                                         if (!CPLabel2InterfaceConstruct.containsKey(label)) {
77                                                 CPLabel2InterfaceConstruct.put(label, new ArrayList<InterfaceConstruct>());
78                                         }
79                                         CPLabel2InterfaceConstruct.get(label).add(iConstruct);
80                                 }
81                         }
82                 }
83
84                 String label;
85                 for (int i = 0; i < constructs.size(); i++) {
86                         SpecConstruct inst = constructs.get(i);
87                         Construct construct = inst.construct;
88                         if (construct instanceof GlobalConstruct) {
89                                 GlobalConstruct theConstruct = (GlobalConstruct) construct;
90                                 if (!hasGlobalConstruct)
91                                         hasGlobalConstruct = true;
92                                 else {
93                                         throw new SemanticsCheckerException(
94                                                         "More than one global construct!");
95                                 }
96                                 HashMap<ConditionalInterface, HashSet<ConditionalInterface>> hbConditions = theConstruct.hbRelations;
97                                 for (ConditionalInterface left : hbConditions.keySet()) {
98                                         HashSet<ConditionalInterface> set = hbConditions.get(left);
99                                         checkHBLabelConsistency(left);
100                                         for (ConditionalInterface right : set) {
101                                                 checkHBLabelConsistency(right);
102                                         }
103                                 }
104                         } else if (construct instanceof PotentialCPDefineConstruct) {
105                                 PotentialCPDefineConstruct theConstruct = (PotentialCPDefineConstruct) construct;
106                                 label = theConstruct.label;
107                                 checkLabelDuplication(construct, label);
108                                 potentialCPLabel2Construct.put(label, inst);
109                         } else if (construct instanceof CPDefineCheckConstruct) {
110                                 CPDefineCheckConstruct theConstruct = (CPDefineCheckConstruct) construct;
111                                 label = theConstruct.label;
112                                 checkLabelDuplication(construct, label);
113                                 CPLabel2Construct.put(label, inst);
114                         } else if (construct instanceof CPDefineConstruct) {
115                                 CPDefineConstruct theConstruct = (CPDefineConstruct) construct;
116                                 label = theConstruct.label;
117                                 checkLabelDuplication(construct, label);
118                                 CPLabel2Construct.put(label, inst);
119                         }
120                 }
121         }
122         
123         public String toString() {
124                 StringBuilder sb = new StringBuilder();
125                 sb.append("Interface name 2 Construct:\n");
126                 for (String interfaceName : interfaceName2Construct.keySet()) {
127                         sb.append(interfaceName + "\t" + interfaceName2Construct.get(interfaceName) + "\n");
128                 }
129                 
130                 sb.append("Potential commit point label 2 Construct:\n");
131                 for (String label : potentialCPLabel2Construct.keySet()) {
132                         sb.append(label + "\t" + potentialCPLabel2Construct.get(label) + "\n");
133                 }
134                 
135                 sb.append("Commit point label 2 Construct:\n");
136                 for (String label : CPLabel2Construct.keySet()) {
137                         sb.append(label + "\t" + CPLabel2Construct.get(label) + "\n");
138                 }
139                 return sb.toString();
140         }
141 }