fixed minor bugs
[cdsspec-compiler.git] / src / edu / uci / eecs / specCompiler / codeGenerator / SemanticsChecker.java
index 9eca53be2923dd8b70c284c3f03128aab4b00cd4..60732306a12f2768f44109f57d4e9d1b49b1470d 100644 (file)
 package edu.uci.eecs.specCompiler.codeGenerator;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 
-import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct.DefineVar;
+import edu.uci.eecs.specCompiler.grammerParser.ParseException;
+import edu.uci.eecs.specCompiler.grammerParser.SpecParser;
 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
+import edu.uci.eecs.specCompiler.specExtraction.ClassBeginConstruct;
+import edu.uci.eecs.specCompiler.specExtraction.ClassEndConstruct;
 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
 import edu.uci.eecs.specCompiler.specExtraction.Construct;
 import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct;
 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
 import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
+import edu.uci.eecs.specCompiler.specExtraction.ParserUtils;
 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.SpecConstruct;
+import edu.uci.eecs.specCompiler.specExtraction.SourceFileInfo;
+import edu.uci.eecs.specCompiler.specExtraction.SpecExtractor;
 
 public class SemanticsChecker {
-       public final ArrayList<SpecConstruct> constructs;
-       public final HashMap<String, SpecConstruct> CPLabel2Construct;
-       public final HashMap<String, SpecConstruct> potentialCPLabel2Construct;
-       public final HashMap<String, SpecConstruct> interfaceName2Construct;
-       public final HashMap<String, SpecConstruct> interfaceName2DefineConstruct;
+       public final HashMap<File, SourceFileInfo> srcFilesInfo;
+       public final ArrayList<Construct> constructs;
+       public final HashMap<String, Construct> CPLabel2Construct;
+       public final HashMap<String, PotentialCPDefineConstruct> potentialCPLabel2Construct;
+       public final HashMap<String, InterfaceConstruct> interfaceName2Construct;
+       public final HashMap<String, InterfaceDefineConstruct> interfaceName2DefineConstruct;
        public final HashMap<String, ArrayList<InterfaceConstruct>> CPLabel2InterfaceConstruct;
-       public final HashSet<DefineVar> defineVars;
-       
+
        public final HashMap<String, Integer> interface2Num;
        public final HashMap<String, Integer> hbLabel2Num;
        public final HashMap<String, Integer> commitPointLabel2Num;
 
        private HashMap<String, String> options;
        private HashMap<ConditionalInterface, HashSet<ConditionalInterface>> hbConditions;
-       private SpecConstruct entryPointConstruct;
+       private ArrayList<EntryPointConstruct> entryPointConstructs;
+       private ClassBeginConstruct classBeginConstruct;
+       private ClassEndConstruct classEndConstruct;
        
+       private String templateStr;
+       private String templateFullStr;
+       private String className;
+
        private int _interfaceNum;
        private int _hbLabelNum;
-       private int _commitPointNum;    
-
-       public SemanticsChecker(ArrayList<SpecConstruct> constructs) {
-               this.constructs = constructs;
-               this.CPLabel2Construct = new HashMap<String, SpecConstruct>();
-               this.potentialCPLabel2Construct = new HashMap<String, SpecConstruct>();
-               this.interfaceName2Construct = new HashMap<String, SpecConstruct>();
-               this.interfaceName2DefineConstruct = new HashMap<String, SpecConstruct>();
+       private int _commitPointNum;
+
+       public SemanticsChecker(SpecExtractor extractor) {
+               this.srcFilesInfo = extractor.srcFilesInfo;
+               this.constructs = extractor.getConstructs();
+               this.CPLabel2Construct = new HashMap<String, Construct>();
+               this.potentialCPLabel2Construct = new HashMap<String, PotentialCPDefineConstruct>();
+               this.interfaceName2Construct = new HashMap<String, InterfaceConstruct>();
+               this.interfaceName2DefineConstruct = new HashMap<String, InterfaceDefineConstruct>();
                this.CPLabel2InterfaceConstruct = new HashMap<String, ArrayList<InterfaceConstruct>>();
-               this.defineVars = new HashSet<DefineVar>();
-               this.entryPointConstruct = null;
-               
+               this.entryPointConstructs = new ArrayList<EntryPointConstruct>();
+               this.classBeginConstruct = null;
+               this.classEndConstruct = null;
+
                this.interface2Num = new HashMap<String, Integer>();
                this.hbLabel2Num = new HashMap<String, Integer>();
                // Immediately init the true HB-condition to be 0
                hbLabel2Num.put("", 0);
-               
+
                this.commitPointLabel2Num = new HashMap<String, Integer>();
-               
+
                _interfaceNum = 0;
                _hbLabelNum = 0;
                _commitPointNum = 0;
+               
+               templateStr = null;
+               templateFullStr = null;
+               className = null;
+       }
+       
+       public ClassBeginConstruct getClassBeginConstruct() {
+               return this.classBeginConstruct;
+       }
+       
+       public ClassEndConstruct getClassEndConstruct() {
+               return this.classEndConstruct;
+       }
+       
+       public String getTemplateFullStr() {
+               return this.templateFullStr;
+       }
+       
+       public String getTemplateStr() {
+               return this.templateStr;
+       }
+       
+       public String getClassName() {
+               return this.className;
        }
 
        public HashMap<ConditionalInterface, HashSet<ConditionalInterface>> getHBConditions() {
                return this.hbConditions;
        }
+       
+       /**
+        * Check if the conditional interface is in the HB checking list
+        * @param condInterface
+        * @return
+        */
+       public boolean containsConditionalInterface(ConditionalInterface condInterface) {
+               if (hbConditions.containsKey(condInterface))
+                       return true;
+               for (ConditionalInterface key : hbConditions.keySet()) {
+                       if (hbConditions.get(key).contains(condInterface))
+                               return true;
+               }
+               return false;
+       }
 
        public String getOption(String key) {
                return options.get(key);
@@ -76,22 +129,16 @@ public class SemanticsChecker {
                                                        + "\"!");
                } else if (!label.equals("")) {
                        InterfaceConstruct iConstruct = (InterfaceConstruct) interfaceName2Construct
-                                       .get(interfaceName).construct;
+                                       .get(interfaceName);
                        if (!iConstruct.hbConditions.containsKey(label)) {
                                throw new SemanticsCheckerException("Interface "
                                                + interfaceName + " doesn't contain HB_codition: "
                                                + label + "!");
                        }
-                       
-                       // No HB condition label can duplicate!
-                       if (hbLabel2Num.containsKey(label)) {
-                               throw new SemanticsCheckerException("Happens-before label: "
-                                               + label + " duplicates!");
-                       }
-                       
+
                        // Number the HB-condition label
                        hbLabel2Num.put(label, _hbLabelNum++);
-               }       
+               }
        }
 
        private void checkLabelDuplication(Construct construct, String label)
@@ -107,17 +154,25 @@ public class SemanticsChecker {
        }
 
        private void postCheck() throws SemanticsCheckerException {
-               // This is a C program, must provide the entry point
-               if (getOption("LANG").equals("C") && entryPointConstruct == null) {
+               // C++ data structure with Class must provide the beginning and ending
+               // of its declaration
+               if (getOption("Class") != null) {
+                       if (classBeginConstruct == null || classEndConstruct == null) {
+                               throw new SemanticsCheckerException(
+                                               "Class must provide the boundary explicitly!");
+                       }
+               }
+               // It must provide the entry point
+               if (entryPointConstructs.size() == 0) {
                        throw new SemanticsCheckerException(
-                                       "C program must provide the entry point!");
+                                       "The program must have at least one entry point!");
                }
 
                // Check if interface define construct labels are correct
                for (String name : interfaceName2DefineConstruct.keySet()) {
                        if (!interfaceName2Construct.containsKey(name)) {
-                               throw new SemanticsCheckerException(
-                                               "Label \"" + name + "\" does not have interface declaration!");
+                               throw new SemanticsCheckerException("Label \"" + name
+                                               + "\" does not have interface declaration!");
                        }
                }
        }
@@ -126,7 +181,7 @@ public class SemanticsChecker {
                boolean hasGlobalConstruct = false;
                // First grab the information from the interface
                for (int i = 0; i < constructs.size(); i++) {
-                       Construct inst = constructs.get(i).construct;
+                       Construct inst = constructs.get(i);
                        if (inst instanceof InterfaceConstruct) {
                                InterfaceConstruct iConstruct = (InterfaceConstruct) inst;
                                if (interfaceName2Construct.containsKey(iConstruct.name)) {
@@ -135,13 +190,9 @@ public class SemanticsChecker {
                                }
                                // Number the interface label
                                interface2Num.put(iConstruct.name, _interfaceNum++);
-                               
-                               interfaceName2Construct.put(iConstruct.name, constructs.get(i));
-                               for (int j = 0; j < iConstruct.action.defineVars.size(); j++) {
-                                       DefineVar var = iConstruct.action.defineVars.get(j);
-                                       var.renameVarName("__" + iConstruct.name + "_"
-                                                       + var.varName + "__");
-                               }
+
+                               interfaceName2Construct.put(iConstruct.name,
+                                               (InterfaceConstruct) constructs.get(i));
 
                                for (int j = 0; j < iConstruct.commitPointSet.size(); j++) {
                                        String label = iConstruct.commitPointSet.get(j);
@@ -156,8 +207,7 @@ public class SemanticsChecker {
 
                String label;
                for (int i = 0; i < constructs.size(); i++) {
-                       SpecConstruct inst = constructs.get(i);
-                       Construct construct = inst.construct;
+                       Construct construct = constructs.get(i);
                        if (construct instanceof GlobalConstruct) {
                                GlobalConstruct theConstruct = (GlobalConstruct) construct;
                                if (!hasGlobalConstruct)
@@ -174,7 +224,7 @@ public class SemanticsChecker {
                                for (ConditionalInterface left : hbConditions.keySet()) {
                                        HashSet<ConditionalInterface> set = hbConditions.get(left);
                                        checkHBLabelConsistency(left);
-                                       
+
                                        for (ConditionalInterface right : set) {
                                                checkHBLabelConsistency(right);
                                        }
@@ -185,30 +235,27 @@ public class SemanticsChecker {
                                checkLabelDuplication(construct, label);
                                // Number the commit_point label
                                commitPointLabel2Num.put(label, _commitPointNum++);
-                               
-                               potentialCPLabel2Construct.put(label, inst);
+
+                               potentialCPLabel2Construct.put(label,
+                                               (PotentialCPDefineConstruct) construct);
                        } else if (construct instanceof CPDefineCheckConstruct) {
                                CPDefineCheckConstruct theConstruct = (CPDefineCheckConstruct) construct;
                                label = theConstruct.label;
                                checkLabelDuplication(construct, label);
                                // Number the commit_point label
                                commitPointLabel2Num.put(label, _commitPointNum++);
-                               
-                               CPLabel2Construct.put(label, inst);
+
+                               CPLabel2Construct.put(label, construct);
                        } else if (construct instanceof CPDefineConstruct) {
                                CPDefineConstruct theConstruct = (CPDefineConstruct) construct;
                                label = theConstruct.label;
                                checkLabelDuplication(construct, label);
                                // Number the commit_point label
                                commitPointLabel2Num.put(label, _commitPointNum++);
-                               
-                               CPLabel2Construct.put(label, inst);
+
+                               CPLabel2Construct.put(label, construct);
                        } else if (construct instanceof EntryPointConstruct) {
-                               if (entryPointConstruct != null) {
-                                       throw new SemanticsCheckerException(
-                                                       "More than one entry point!");
-                               }
-                               entryPointConstruct = inst;
+                               entryPointConstructs.add((EntryPointConstruct) construct);
                        } else if (construct instanceof InterfaceDefineConstruct) {
                                InterfaceDefineConstruct theConstruct = (InterfaceDefineConstruct) construct;
                                String name = theConstruct.name;
@@ -216,25 +263,35 @@ public class SemanticsChecker {
                                        throw new SemanticsCheckerException(
                                                        "Interface define label duplicates!");
                                }
-                               interfaceName2DefineConstruct.put(name, inst);
+                               interfaceName2DefineConstruct.put(name, theConstruct);
+                       } else if (construct instanceof ClassBeginConstruct) {
+                               classBeginConstruct = (ClassBeginConstruct) construct;
+                               ArrayList<String> content = srcFilesInfo.get(classBeginConstruct.file).content;
+                               String firstLine = content.get(classBeginConstruct.beginLineNum), secondLine;
+                               if (firstLine.startsWith("template")) {
+                                       secondLine = content.get(classBeginConstruct.beginLineNum + 1);
+                                       templateFullStr = firstLine;
+                                       templateStr = ParserUtils.getTemplateStr(firstLine);
+                                       className = ParserUtils.getClassName(secondLine);
+                               } else {
+                                       className = ParserUtils.getClassName(firstLine);
+                               }
+                               
+                       } else if (construct instanceof ClassEndConstruct) {
+                               classEndConstruct = (ClassEndConstruct) construct;
                        }
                }
        }
 
        public String toString() {
                StringBuilder sb = new StringBuilder();
-               if (entryPointConstruct == null) {
-                       sb.append("Entry point is not specified!");
-               } else {
-                       sb.append("@Entry_point:\n" + entryPointConstruct);
-               }
-               
+
                sb.append("Interface name 2 Construct:\n");
                for (String interfaceName : interfaceName2Construct.keySet()) {
                        sb.append(interfaceName + "\t"
                                        + interfaceName2Construct.get(interfaceName) + "\n");
                }
-               
+
                sb.append("Interface name 2 define construct:\n");
                for (String interfaceName : interfaceName2DefineConstruct.keySet()) {
                        sb.append(interfaceName + "\t"