IR
authordroy <droy>
Mon, 7 Jul 2003 16:14:57 +0000 (16:14 +0000)
committerdroy <droy>
Mon, 7 Jul 2003 16:14:57 +0000 (16:14 +0000)
61 files changed:
Repair/RepairCompiler/MCC/IR/ArrayDescriptor.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/BooleanLiteralExpr.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/CastExpr.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/CodeWriter.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/ComparisonPredicate.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/Constraint.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/DependencyBuilder.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/Descriptor.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/DotExpr.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/ElementOfExpr.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/Expr.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/FieldDescriptor.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/ForQuantifier.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/GraphNode.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/IRErrorReporter.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/IRException.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/ImageSetExpr.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/Inclusion.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/InclusionPredicate.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/IntegerLiteralExpr.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/LabelDescriptor.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/LiteralExpr.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/LogicStatement.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/MissingSetDescriptor.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/MissingTypeDescriptor.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/NaiveGenerator.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/OpExpr.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/Opcode.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/ParseNode.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/ParseNodeDOTVisitor.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/ParseNodeVector.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/Predicate.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/PrettyPrinter.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/Quantifier.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/RelationDescriptor.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/RelationExpr.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/RelationInclusion.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/RelationQuantifier.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/ReservedFieldDescriptor.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/ReservedSetDescriptor.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/ReservedTypeDescriptor.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/Rule.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/ScheduleEvent.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/SemanticAnalyzer.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/SemanticChecker.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/SetDescriptor.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/SetExpr.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/SetInclusion.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/SetQuantifier.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/SimpleIRErrorReporter.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/SizeofExpr.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/StructureTypeDescriptor.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/SymbolTable.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/SymbolTableStack.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/TokenLiteralExpr.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/TokenSetDescriptor.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/TupleOfExpr.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/TypeDescriptor.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/VarDescriptor.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/VarExpr.java [new file with mode: 0755]
Repair/RepairCompiler/MCC/IR/Walkable.java [new file with mode: 0755]

diff --git a/Repair/RepairCompiler/MCC/IR/ArrayDescriptor.java b/Repair/RepairCompiler/MCC/IR/ArrayDescriptor.java
new file mode 100755 (executable)
index 0000000..480ea4b
--- /dev/null
@@ -0,0 +1,41 @@
+package MCC.IR;
+
+/**
+ * ArrayDescriptor
+ *
+ * wrapper descriptor for an internal field descriptor that
+ * allows arrays
+ */
+
+public class ArrayDescriptor extends FieldDescriptor {
+
+    FieldDescriptor fd;
+    Expr index;
+
+    public ArrayDescriptor(FieldDescriptor fd, Expr index) {
+        super(fd.getSymbol());
+        this.index = index;
+        this.fd = fd;
+    }
+
+    public FieldDescriptor getField() {
+        return fd;
+    }
+
+    public TypeDescriptor getType() {
+        return fd.getType();
+    }
+
+    public void setType(TypeDescriptor td) {
+        fd.setType(td);
+    }
+
+    public Expr getIndexBound() {
+        return index;
+    }
+
+    public Expr getBaseSizeExpr() {
+        throw new IRException();
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/BooleanLiteralExpr.java b/Repair/RepairCompiler/MCC/IR/BooleanLiteralExpr.java
new file mode 100755 (executable)
index 0000000..d0729e6
--- /dev/null
@@ -0,0 +1,31 @@
+package MCC.IR;
+
+import MCC.State;
+
+public class BooleanLiteralExpr extends LiteralExpr {
+    
+    boolean value;
+    
+    public BooleanLiteralExpr(boolean value) {
+        this.value = value;
+        td = ReservedTypeDescriptor.INT;
+    }
+
+    public boolean getValue() {
+        return value;
+    }
+
+    public void generate(CodeWriter writer, VarDescriptor dest) {
+        writer.outputline("int " + dest.getSafeSymbol() + " = " + (value ? "1" : "0") + ";");
+    }
+
+    public void prettyPrint(PrettyPrinter pp) {
+        pp.output(value ? "true" : "false");
+    }
+
+    public TypeDescriptor typecheck(SemanticAnalyzer sa) {
+        td = ReservedTypeDescriptor.INT;
+        return td;
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/CastExpr.java b/Repair/RepairCompiler/MCC/IR/CastExpr.java
new file mode 100755 (executable)
index 0000000..83a1ddb
--- /dev/null
@@ -0,0 +1,59 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class CastExpr extends Expr {
+    
+    TypeDescriptor type;
+    Expr expr;
+
+    public CastExpr(TypeDescriptor type, Expr expr) {
+        this.type = type;
+        this.expr = expr;
+    }
+
+    public Set getRequiredDescriptors() {
+        return expr.getRequiredDescriptors();
+    }
+
+    public void generate(CodeWriter writer, VarDescriptor dest) {
+        VarDescriptor vd = VarDescriptor.makeNew("expr");
+        expr.generate(writer, vd);
+        writer.outputline("int " + dest.getSafeSymbol() + " = (int) " + vd.getSafeSymbol() + ";");
+    }
+
+    public void prettyPrint(PrettyPrinter pp) {
+        pp.output("cast(" + type.getSafeSymbol() + ", ");
+        expr.prettyPrint(pp);
+        pp.output(")");
+    }
+
+    public TypeDescriptor getType() {
+        return type;
+    }
+
+    public TypeDescriptor typecheck(SemanticAnalyzer sa) {
+        TypeDescriptor td = expr.typecheck(sa);
+
+        if (td == null) {
+            return null;
+        }
+
+        if (!type.isSubtypeOf(td)) {
+            sa.getErrorReporter().report(null, "Expression type '" + td.getSymbol() + "' is not a parent of the cast type '" + type.getSymbol() + "'");
+            return null;
+        }
+
+        this.td = type;
+        return type;
+    }
+
+}
+
+
+
+
+
+
+
+
diff --git a/Repair/RepairCompiler/MCC/IR/CodeWriter.java b/Repair/RepairCompiler/MCC/IR/CodeWriter.java
new file mode 100755 (executable)
index 0000000..d36ee72
--- /dev/null
@@ -0,0 +1,11 @@
+package MCC.IR;
+
+public interface CodeWriter extends PrettyPrinter{
+
+    public void outputline(String s);
+    public void indent();
+    public void unindent();
+
+    public SymbolTable getSymbolTable();
+    
+}
diff --git a/Repair/RepairCompiler/MCC/IR/ComparisonPredicate.java b/Repair/RepairCompiler/MCC/IR/ComparisonPredicate.java
new file mode 100755 (executable)
index 0000000..1e28b63
--- /dev/null
@@ -0,0 +1,51 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class ComparisonPredicate extends Predicate {
+
+    public static final Comparison GT = new Comparison("GT");
+    public static final Comparison GE = new Comparison("GE");
+    public static final Comparison LT = new Comparison("LT");
+    public static final Comparison LE = new Comparison("LE");
+    public static final Comparison EQ = new Comparison("EQ");
+    private static final Comparison ALL[] = { GT, GE, LT, LE, EQ };               
+    
+    public static class Comparison {
+        private final String name;
+        private Comparison(String name) { this.name = name; }
+        public String toString() { return name; }
+        public static Comparison fromString(String name) {
+            if (name == null) {
+                throw new NullPointerException();
+            }
+
+            for (int i = 0; i < ALL.length; i++) {
+                if (name.equalsIgnoreCase(ALL[i].toString())) {
+                    return ALL[i];
+                }
+            }
+
+            throw new IllegalArgumentException("Input not a valid comparison.");
+        }                
+    }
+    
+    Comparison comparison;
+    Expr left, right;
+
+    public ComparisonPredicate(String comparison, Expr left, Expr right) {
+        this.comparison = Comparison.fromString(comparison);
+        this.left = left;
+        this.right = right;
+    }
+
+    public Set getRequiredDescriptors() {
+        assert left != null;
+        assert right != null;
+        Set v = left.getRequiredDescriptors();
+        v.addAll(right.getRequiredDescriptors());
+        return v;
+    }
+            
+}
+    
diff --git a/Repair/RepairCompiler/MCC/IR/Constraint.java b/Repair/RepairCompiler/MCC/IR/Constraint.java
new file mode 100755 (executable)
index 0000000..ec216b6
--- /dev/null
@@ -0,0 +1,75 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class Constraint {
+    
+    private static int count = 1;
+
+    String label = null;
+    boolean crash = false;
+    SymbolTable st = new SymbolTable();
+    Vector quantifiers = new Vector(); 
+    LogicStatement logicstatement = null;
+
+    public Constraint() {
+        label = new String("c" + count++);
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public SymbolTable getSymbolTable() {
+        return st;
+    }
+
+    public void addQuantifier(Quantifier q) {
+        quantifiers.addElement(q);
+    }
+
+    public void setLogicStatement(LogicStatement ls) {
+        logicstatement = ls;
+    }
+
+    public LogicStatement getLogicStatement() {
+        return logicstatement;
+    }
+    
+    public void setCrash(boolean crash) {
+        this.crash = crash;
+    }
+
+    public Iterator quantifiers() {
+        return quantifiers.iterator();
+    }
+
+    public Set getRequiredDescriptorsFromQuantifiers() {
+
+        HashSet topdescriptors = new HashSet();
+
+        for (int i = 0; i < quantifiers.size(); i++) {            
+            Quantifier q = (Quantifier) quantifiers.elementAt(i);
+            topdescriptors.addAll(q.getRequiredDescriptors());                
+        }
+
+        return SetDescriptor.expand(topdescriptors);
+    }
+
+    public Set getRequiredDescriptorsFromLogicStatement() {
+        
+        HashSet topdescriptors = new HashSet();
+
+        topdescriptors.addAll(logicstatement.getRequiredDescriptors());
+
+        return SetDescriptor.expand(topdescriptors);
+    }
+   
+    public Set getRequiredDescriptors() {
+        Set set = getRequiredDescriptorsFromQuantifiers();
+        set.addAll(getRequiredDescriptorsFromLogicStatement());
+        return set;
+    }
+   
+}
+
diff --git a/Repair/RepairCompiler/MCC/IR/DependencyBuilder.java b/Repair/RepairCompiler/MCC/IR/DependencyBuilder.java
new file mode 100755 (executable)
index 0000000..975ea60
--- /dev/null
@@ -0,0 +1,182 @@
+package MCC.IR;
+
+import MCC.State;
+import java.util.*;
+
+public class DependencyBuilder {
+
+    Hashtable constraintnodes = new Hashtable(); 
+    Hashtable rulenodes = new Hashtable();
+    State state;
+
+    public DependencyBuilder(State state) {
+        this.state = state;
+    }
+
+    public void calculate() {
+                     
+        /* reinitialize (clear) nodes */
+        constraintnodes = new Hashtable();
+        rulenodes = new Hashtable();
+
+        /* load up the rules and constraints */
+        Vector rules = state.vRules;        
+        Vector constraints = state.vConstraints;
+
+        /* build up graph rulenodes (not edges yet) */
+        for (int i = 0; i < rules.size(); i++) {
+            Rule rule = (Rule) rules.elementAt(i);
+            assert rule != null;
+            assert rule.getLabel() != null;
+
+            Inclusion inclusion = rule.getInclusion();
+            Iterator targets = inclusion.getTargetDescriptors().iterator();
+            String additionallabel = new String();
+
+            if (targets.hasNext()) {
+                Descriptor d = (Descriptor)targets.next();
+                additionallabel = "\\n" + d.getSymbol();
+            } 
+            
+            GraphNode gn = new GraphNode(rule.getLabel(), rule.getLabel() + additionallabel, rule);
+            rulenodes.put(rule.getLabel(), gn);
+        } 
+
+        /* build up graph constraintnodes (not edges yet) */
+        for (int i = 0; i < constraints.size(); i++) {
+            Constraint constraint = (Constraint) constraints.elementAt(i);
+            assert constraint != null;
+            assert constraint.getLabel() != null;
+            GraphNode gn = new GraphNode(constraint.getLabel(), constraint);
+            gn.setDotNodeParameters("shape=box");
+            constraintnodes.put(constraint.getLabel(), gn);
+        } 
+
+        /* calculate rule->rule dependencies */        
+        for (int i = 0; i < rules.size(); i++) {
+            Rule rule = (Rule) rules.elementAt(i);
+            GraphNode rulenode = (GraphNode) rulenodes.get(rule.getLabel());
+            Set requiredsymbols = rule.getRequiredDescriptors();
+
+            for (int j = 0; j < rules.size(); j++) {
+
+                if (j == i) {
+                    continue; 
+                }
+                
+                Rule otherrule = (Rule) rules.elementAt(j);
+                Inclusion inclusion = otherrule.getInclusion();
+                Iterator targets = inclusion.getTargetDescriptors().iterator();
+                GraphNode otherrulenode = (GraphNode) rulenodes.get(otherrule.getLabel());
+
+                while (targets.hasNext()) {
+                    Descriptor d = (Descriptor) targets.next();
+
+                    if (requiredsymbols.contains(d)) { /* rule->rule dependency */
+                        otherrulenode.addEdge(new GraphNode.Edge(d.getSymbol(), rulenode));
+                    }
+                }
+            }           
+        }
+
+        /* build constraint->rule dependencies */
+        for (int i = 0; i < constraints.size(); i++) {           
+            Constraint constraint = (Constraint) constraints.elementAt(i);
+            GraphNode constraintnode = (GraphNode) constraintnodes.get(constraint.getLabel());
+            Set requiredsymbols = constraint.getRequiredDescriptorsFromLogicStatement();
+            Set requiredquantifiers = constraint.getRequiredDescriptorsFromQuantifiers();
+            for (int j = 0; j < rules.size(); j++) {                
+                Rule otherrule = (Rule) rules.elementAt(j);
+                Inclusion inclusion = otherrule.getInclusion();
+                Iterator targets = inclusion.getTargetDescriptors().iterator();
+                GraphNode otherrulenode = (GraphNode) rulenodes.get(otherrule.getLabel());
+
+                while (targets.hasNext()) {
+                    Descriptor d = (Descriptor) targets.next();
+
+                    if (requiredsymbols.contains(d)) { /* logic->rule dependency */
+                        GraphNode.Edge edge = new GraphNode.Edge(d.getSymbol(), constraintnode);
+                        //edge.setDotNodeParameters("style=bold");
+                        otherrulenode.addEdge(edge);
+                    }
+
+                    if (requiredquantifiers.contains(d)) { /* quantifier-> dependency */
+                        GraphNode.Edge edge = new GraphNode.Edge(d.getSymbol(), constraintnode);
+                        edge.setDotNodeParameters("style=dotted");
+                        otherrulenode.addEdge(edge);
+                    }
+                }               
+            }           
+        }
+
+        /* store results in state */
+        state.rulenodes = rulenodes;
+        state.constraintnodes = constraintnodes;
+    }
+
+    static class IntegerLattice {
+
+        boolean top;
+        boolean isNum;
+        int num;
+
+        public static final IntegerLattice TOP = new IntegerLattice(true);
+        public static final IntegerLattice BOT = new IntegerLattice(false);
+
+        private IntegerLattice(boolean top) {
+            this.top = top;
+            isNum = false;
+        }
+
+        public IntegerLattice(int num) {
+            isNum = true;
+            this.num = num;
+        }
+
+    }
+
+    public IntegerLattice setSize(SetDescriptor sd) {
+        String setname = sd.getSymbol();
+
+        if (setname.equals("Block")) {
+            return IntegerLattice.TOP;
+        } else if (setname.equals("UsedBlock")) {
+            return IntegerLattice.TOP;
+        } else if (setname.equals("FreeBlock")) {
+            return IntegerLattice.TOP;
+        } else if (setname.equals("Inode")) {
+            return IntegerLattice.TOP;
+        } else if (setname.equals("UsedInode")) {
+            return IntegerLattice.TOP;
+        } else if (setname.equals("FileInode")) {
+            return IntegerLattice.TOP;
+        } else if (setname.equals("DirectoryInode")) {
+            return new IntegerLattice(1);
+        } else if (setname.equals("RootDirectoryInode")) {
+            return new IntegerLattice(1);
+        } else if (setname.equals("SuperBlock")) {
+            return new IntegerLattice(1);
+        } else if (setname.equals("GroupBlock")) {
+            return new IntegerLattice(1);
+        } else if (setname.equals("FileDirectoryBlock")) {
+            return IntegerLattice.TOP;
+        } else if (setname.equals("InodeTableBlock")) {
+            return new IntegerLattice(1);
+        } else if (setname.equals("InodeBitmapBlock")) {
+            return new IntegerLattice(1);
+        } else if (setname.equals("BlockBitmapBlock")) {
+            return new IntegerLattice(1);
+        } else if (setname.equals("DirectoryBlock")) {
+            return new IntegerLattice(0);
+        } else if (setname.equals("FileBlock")) {
+            return IntegerLattice.TOP;
+        } else if (setname.equals("DirectoryEntry")) {
+            return IntegerLattice.TOP;
+        } else {
+            throw new IRException();
+        }
+            
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/Descriptor.java b/Repair/RepairCompiler/MCC/IR/Descriptor.java
new file mode 100755 (executable)
index 0000000..99eb8d9
--- /dev/null
@@ -0,0 +1,36 @@
+package MCC.IR;
+
+/**
+ * Descriptor 
+ *
+ * represents a symbol in the language (var name, function name, etc).
+ */
+
+public abstract class Descriptor {
+
+    protected String name;
+    protected String safename;
+    
+    public Descriptor(String name) {
+       this.name = name;
+        this.safename = "__" + name + "__";
+    }
+
+    protected Descriptor(String name, String safename) {
+       this.name = name;
+        this.safename = safename;
+    }
+    
+    public String toString() {
+       return name;
+    }
+    
+    public String getSymbol() {
+       return name;
+    }
+
+    public String getSafeSymbol() {
+        return safename;
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/DotExpr.java b/Repair/RepairCompiler/MCC/IR/DotExpr.java
new file mode 100755 (executable)
index 0000000..fe293d1
--- /dev/null
@@ -0,0 +1,228 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class DotExpr extends Expr {
+    
+    Expr left;
+    String field;
+    Expr index;
+
+    public DotExpr(Expr left, String field, Expr index) {
+        this.left = left;
+        this.field = field;
+        this.index = index;
+    }
+
+    public Set getRequiredDescriptors() {
+        Set v = left.getRequiredDescriptors();
+        
+        if (index != null) {
+            v.addAll(index.getRequiredDescriptors());
+        }
+
+        return v;
+    }
+
+    public void generate(CodeWriter writer, VarDescriptor dest) {
+        VarDescriptor leftd = VarDescriptor.makeNew("left");
+
+        writer.output("// " +  leftd.getSafeSymbol() + " <-- ");
+        left.prettyPrint(writer);
+        writer.outputline("");
+
+        left.generate(writer, leftd);
+
+        writer.output("// " +  leftd.getSafeSymbol() + " = ");
+        left.prettyPrint(writer);
+        writer.outputline("");
+
+      
+        StructureTypeDescriptor struct = (StructureTypeDescriptor) left.getType();        
+        FieldDescriptor fd = struct.getField(field);
+        LabelDescriptor ld = struct.getLabel(field);        
+        Expr intindex = index;
+        Expr offsetbits;
+
+        if (ld != null) { /* label */
+            assert fd == null;
+            fd = ld.getField();
+            assert fd != null;
+            assert intindex == null;
+            intindex = ld.getIndex();
+        } 
+
+        // #ATTN#: getOffsetExpr needs to be called with the fielddescriptor obect that is in teh vector list
+        // this means that if the field is an arraydescriptor you have to call getOffsetExpr with the array 
+        // descriptor not the underlying field descriptor
+
+        /* we calculate the offset in bits */
+        offsetbits = struct.getOffsetExpr(fd);                    
+
+        if (fd instanceof ArrayDescriptor) {
+            fd = ((ArrayDescriptor) fd).getField();
+        } 
+        
+        if (intindex != null) {
+            if (intindex instanceof IntegerLiteralExpr && ((IntegerLiteralExpr) intindex).getValue() == 0) {
+                /* short circuit for constant 0 */                
+            } else {
+                Expr basesize = fd.getBaseSizeExpr();
+                offsetbits = new OpExpr(Opcode.ADD, offsetbits, new OpExpr(Opcode.MULT, basesize, intindex));
+            }
+        }
+        
+        final SymbolTable st = writer.getSymbolTable();
+        TypeDescriptor td = offsetbits.typecheck(new SemanticAnalyzer() {
+                public IRErrorReporter getErrorReporter() { throw new IRException("badness"); }
+                public SymbolTable getSymbolTable() { return st; }
+            });
+
+        if (td == null) {
+            throw new IRException();
+        } else if (td != ReservedTypeDescriptor.INT) {
+            throw new IRException();
+        }
+               
+        // #TBD#: ptr's to bits and byte's and stuff are a little iffy... 
+        // right now, a bit* is the same as a int* = short* = byte* (that is there 
+        // is no post-derefernce mask)
+
+        if (offsetbits instanceof IntegerLiteralExpr) {
+            int offsetinbits = ((IntegerLiteralExpr) offsetbits).getValue();
+            int offset = offsetinbits >> 3; /* offset in bytes */
+
+            if (fd.getType() instanceof ReservedTypeDescriptor && !fd.getPtr()) {
+                int shift = offsetinbits - (offset << 3);            
+                int mask = bitmask(((IntegerLiteralExpr)fd.getType().getSizeExpr()).getValue());
+                               
+                /* type var = ((*(int *) (base + offset)) >> shift) & mask */
+                writer.outputline(getType().getGenerateType() + " " + dest.getSafeSymbol() + 
+                                  " = ((*(int *)" + 
+                                  "(" + leftd.getSafeSymbol() + " + " + offset + ")) " + 
+                                  " >> " + shift + ") & 0x" + Integer.toHexString(mask) + ";");  
+            } else { /* a structure address or a ptr! */
+                String ptr = fd.getPtr() ? "*(int *)" : "";
+                /* type var = [*(int *)] (base + offset) */
+                writer.outputline(getType().getGenerateType() + " " + dest.getSafeSymbol() + 
+                                  " = " + ptr + "(" + leftd.getSafeSymbol() + " + " + offset + ");");  
+            }
+        } else { /* offset in bits is an expression that must be generated */                        
+            VarDescriptor ob = VarDescriptor.makeNew("offsetinbits");
+            writer.output("// " + ob.getSafeSymbol() + " <-- ");
+            offsetbits.prettyPrint(writer);
+            writer.outputline("");
+            offsetbits.generate(writer, ob);
+            writer.output("// " + ob.getSafeSymbol() + " = ");
+            offsetbits.prettyPrint(writer);
+            writer.outputline("");
+
+            /* derive offset in bytes */
+            VarDescriptor offset = VarDescriptor.makeNew("offset");
+            writer.outputline("int " + offset.getSafeSymbol() + " = " + ob.getSafeSymbol() + " >> 3;");
+            
+            if (fd.getType() instanceof ReservedTypeDescriptor && !fd.getPtr()) {
+                VarDescriptor shift = VarDescriptor.makeNew("shift");
+                writer.outputline("int " + shift.getSafeSymbol() + " = " + ob.getSafeSymbol() + 
+                                  " - (" + offset.getSafeSymbol() + " << 3);");
+                int mask = bitmask(((IntegerLiteralExpr)fd.getType().getSizeExpr()).getValue());
+                
+                /* type var = ((*(int *) (base + offset)) >> shift) & mask */
+                writer.outputline(getType().getGenerateType() + " " + dest.getSafeSymbol() + 
+                                  " = ((*(int *)" + 
+                                  "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ")) " + 
+                                  " >> " + shift.getSafeSymbol() + ") & 0x" + Integer.toHexString(mask) + ";");  
+            } else { /* a structure address or a ptr */
+                String ptr = fd.getPtr() ? "*(int *)" : "";
+                /* type var = [*(int *)] (base + offset) */
+                writer.outputline(getType().getGenerateType() + " " + dest.getSafeSymbol() + 
+                                  " = " + ptr + "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ");");  
+            }            
+        }
+    }
+
+    private int bitmask(int bits) {
+        int mask = 0;
+        
+        for (int i = 0; i < bits; i++) {
+            mask <<= 1;
+            mask += 1;
+        }
+
+        return mask;            
+    }
+
+    public void prettyPrint(PrettyPrinter pp) {
+        left.prettyPrint(pp);
+        pp.output("." + field);
+        if (index != null) {
+            pp.output("[");
+            index.prettyPrint(pp);
+            pp.output("]");
+        }
+    }
+
+    public TypeDescriptor typecheck(SemanticAnalyzer sa) {
+        TypeDescriptor lefttype = left.typecheck(sa);
+        TypeDescriptor indextype = index == null ? null : index.typecheck(sa);
+
+        if ((lefttype == null) || (index != null && indextype == null)) {
+            return null;
+        }
+
+        if (indextype != null) {
+            if (indextype != ReservedTypeDescriptor.INT) {
+                sa.getErrorReporter().report(null, "Index must be of type 'int' not '" + indextype.getSymbol() + "'");
+                return null;
+            }
+        }
+
+        if (lefttype instanceof StructureTypeDescriptor) {            
+            StructureTypeDescriptor struct = (StructureTypeDescriptor) lefttype;
+            FieldDescriptor fd = struct.getField(field);
+            LabelDescriptor ld = struct.getLabel(field);
+
+            if (fd != null) { /* field */
+                assert ld == null;
+
+                if (indextype == null && fd instanceof ArrayDescriptor) {
+                    sa.getErrorReporter().report(null, "Must specify an index what accessing array field '" + struct.getSymbol() + "." + fd.getSymbol() + "'");
+                    return null;                
+                } else if (indextype != null && !(fd instanceof ArrayDescriptor)) {
+                    sa.getErrorReporter().report(null, "Cannot specify an index when accessing non-array field '" + struct.getSymbol() + "." + fd.getSymbol() + "'");
+                    return null;
+                }
+                
+                this.td = fd.getType();
+            } else if (ld != null) { /* label */
+                assert fd == null;
+
+                if (index != null) { 
+                    sa.getErrorReporter().report(null, "A label cannot be accessed as an array");
+                    return null;
+                }
+                
+                this.td = ld.getType();
+            } else {
+                sa.getErrorReporter().report(null, "No such field or label '" + field + "' in structure '" + struct.getSymbol() + "'");
+                return null;
+            }
+
+            /* we promote bit, byte and short to integer types */
+            if (this.td == ReservedTypeDescriptor.BIT ||
+                this.td == ReservedTypeDescriptor.BYTE ||
+                this.td == ReservedTypeDescriptor.SHORT) {
+                this.td = ReservedTypeDescriptor.INT;
+            }
+
+            return this.td;
+        } else {
+            sa.getErrorReporter().report(null, "Left hand side of . expression must be a structure type, not '" + lefttype.getSymbol() + "'");
+            return null;
+        }
+        
+        
+    }
+
+}
+        
diff --git a/Repair/RepairCompiler/MCC/IR/ElementOfExpr.java b/Repair/RepairCompiler/MCC/IR/ElementOfExpr.java
new file mode 100755 (executable)
index 0000000..51941f9
--- /dev/null
@@ -0,0 +1,56 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class ElementOfExpr extends Expr {
+
+    Expr element;
+    SetDescriptor set;
+
+    public ElementOfExpr(Expr element, SetDescriptor set) {
+        if (element == null || set == null) {
+            throw new NullPointerException();
+        }
+
+        this.element = element;
+        this.set = set;
+    }
+
+    public Set getRequiredDescriptors() {
+        Set v = element.getRequiredDescriptors();
+        v.add(set);
+        return v;
+    }
+
+    public void generate(CodeWriter writer, VarDescriptor dest) {
+        VarDescriptor ed = VarDescriptor.makeNew("element");
+        element.generate(writer, ed);
+        writer.outputline("int " + dest.getSafeSymbol() + " = " + 
+                          set.getSafeSymbol() + "_hash->contains(" + ed.getSafeSymbol() + ");");
+    }
+    
+    public void prettyPrint(PrettyPrinter pp) {
+        element.prettyPrint(pp);
+        pp.output(" in? " + set.getSafeSymbol());
+    }
+
+    public TypeDescriptor typecheck(SemanticAnalyzer sa) {
+        TypeDescriptor td = element.typecheck(sa);
+        
+        if (td == null) {
+            return null;
+        }
+
+        TypeDescriptor settype = set.getType();
+
+        if (!td.equals(settype)) {
+            sa.getErrorReporter().report(null, "Type mismatch: attempting to test for types '" + td.getSymbol() + "' in set of type '" + settype.getSymbol() + "'");
+            return null;
+        }
+        
+        this.td = ReservedTypeDescriptor.INT;
+        return this.td;
+    }
+
+}
+
diff --git a/Repair/RepairCompiler/MCC/IR/Expr.java b/Repair/RepairCompiler/MCC/IR/Expr.java
new file mode 100755 (executable)
index 0000000..b5481c3
--- /dev/null
@@ -0,0 +1,24 @@
+package MCC.IR;
+
+import java.util.*;
+
+public abstract class Expr {
+    
+    TypeDescriptor td = null;
+
+    public Expr() {}
+
+    public abstract Set getRequiredDescriptors();
+
+    public abstract void generate(CodeWriter writer, VarDescriptor dest);
+
+    public TypeDescriptor getType() {
+        assert td != null : toString();
+        return td;
+    }
+
+    public abstract TypeDescriptor typecheck(SemanticAnalyzer sa);
+
+    public abstract void prettyPrint(PrettyPrinter pp);
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/FieldDescriptor.java b/Repair/RepairCompiler/MCC/IR/FieldDescriptor.java
new file mode 100755 (executable)
index 0000000..352a41b
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * FieldDescriptor
+ *
+ * represents a field of a type
+ */
+
+package MCC.IR;
+
+public class FieldDescriptor extends Descriptor {
+
+    TypeDescriptor type;
+    boolean ptr;
+
+    public FieldDescriptor(String name) {
+        super(name);
+    }
+
+    public TypeDescriptor getType() {
+        assert type != null;
+        return type;
+    }
+
+    public void setType(TypeDescriptor td) {
+        assert td != null;
+        type = td;
+    }
+
+    public void setPtr(boolean ptr) {
+        this.ptr = ptr;
+    }
+
+    public boolean getPtr() {
+        return ptr;
+    }
+
+    public Expr getBaseSizeExpr() {
+        if (ptr) { /* ptrs are 32bits */
+            return new IntegerLiteralExpr(32);
+        } else {
+            return type.getSizeExpr();
+        }
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/ForQuantifier.java b/Repair/RepairCompiler/MCC/IR/ForQuantifier.java
new file mode 100755 (executable)
index 0000000..2b354f7
--- /dev/null
@@ -0,0 +1,73 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class ForQuantifier extends Quantifier {
+
+    VarDescriptor var = null;
+    Expr lower = null;
+    Expr upper = null;
+
+    public ForQuantifier() {}
+
+    public void setVar(VarDescriptor vd) {
+        this.var = vd;
+    }
+
+    public void setBounds(Expr lower, Expr upper) {
+        this.lower = lower;
+        this.upper = upper;
+    }
+
+    public Set getRequiredDescriptors() {
+        return new HashSet();
+    }
+
+    public String toString() {
+        return "for quantifier " + var.getSymbol() + " = " + lower + " to " + upper;
+    }
+
+    public void generate_open(CodeWriter writer) {
+        VarDescriptor ld = VarDescriptor.makeNew();
+        VarDescriptor ud = VarDescriptor.makeNew();
+        lower.generate(writer, ld);
+        upper.generate(writer, ud);
+        
+        writer.outputline("for (int " + var.getSafeSymbol() + " = " + ld.getSafeSymbol() + "; " + var.getSafeSymbol() + " <= " + ud.getSafeSymbol() + "; " + var.getSafeSymbol() + "++) {");
+        writer.indent();
+    }
+
+    public boolean typecheck(SemanticAnalyzer sa) {
+        TypeDescriptor lt = lower.typecheck(sa);
+        TypeDescriptor ut = upper.typecheck(sa);
+        
+        if (lt == null || ut == null) {
+            return false;
+        }
+
+        boolean ok = true;
+
+        if (lt != ReservedTypeDescriptor.INT) {
+            sa.getErrorReporter().report(null, "Lower bound of for quantifier must be of type 'int'");
+            ok = false;
+        }
+
+        if (ut != ReservedTypeDescriptor.INT) {
+            sa.getErrorReporter().report(null, "Upper bound of for quantifier must be of type 'int'");
+            ok = false;
+        }
+
+        return ok;       
+    } 
+
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/Repair/RepairCompiler/MCC/IR/GraphNode.java b/Repair/RepairCompiler/MCC/IR/GraphNode.java
new file mode 100755 (executable)
index 0000000..8059be3
--- /dev/null
@@ -0,0 +1,263 @@
+package MCC.IR;
+
+import java.util.*;
+import java.io.*;
+
+public class GraphNode {
+
+    public static boolean useEdgeLabels;
+
+    /* NodeStatus enumeration pattern ***********/
+    
+    public static final NodeStatus UNVISITED = new NodeStatus("UNVISITED");
+    public static final NodeStatus PROCESSING = new NodeStatus("PROCESSING");
+    public static final NodeStatus FINISHED = new NodeStatus("FINISHED");
+
+    public static class NodeStatus {
+        private static String name;
+        private NodeStatus(String name) { this.name = name; }
+        public String toString() { return name; }
+    }
+
+    /* Edge *****************/
+
+    public static class Edge {
+        
+        private String label;
+        private GraphNode target;
+        private String dotnodeparams = new String();
+
+        public Edge(String label, GraphNode target) {
+            this.label = label;
+            this.target = target;
+        }
+
+        public String getLabel() {
+            return label;
+        }
+
+        public GraphNode getTarget() {
+            return target;
+        }
+
+        public void setDotNodeParameters(String param) {
+            if (param == null) {
+                throw new NullPointerException();
+            }
+            if (param.length() > 0) {
+                dotnodeparams = "," + param;
+            } else {
+                dotnodeparams = new String();
+            }
+        }
+
+    }
+
+    int discoverytime = -1;
+    int finishingtime = -1; /* used for searches */
+    Vector edges = new Vector();  
+    String nodelabel;
+    String textlabel;
+    NodeStatus status = UNVISITED;    
+    String dotnodeparams = new String();
+    Object owner = null;
+
+    public GraphNode(String label) {
+        this.nodelabel = label;
+        this.textlabel = label;
+    }
+
+    public GraphNode(String label, Object owner) {
+        this.nodelabel = label;
+        this.textlabel = label;
+        this.owner = owner;
+    }
+
+    public GraphNode(String label, String textlabel, Object owner) {
+        this.nodelabel = label;
+        this.textlabel = textlabel;
+        this.owner = owner;
+    }
+
+    public Object getOwner() {
+        return owner;
+    }
+
+    public void setDotNodeParameters(String param) {
+        if (param == null) {
+            throw new NullPointerException();
+        }
+        if (param.length() > 0) {
+            dotnodeparams = "," + param;
+        } else {
+            dotnodeparams = new String();
+        }
+    }
+    
+    public void setStatus(NodeStatus status) {
+        if (status == null) {
+            throw new NullPointerException();
+        }
+        this.status = status;
+    }
+
+    public String getLabel() {
+        return nodelabel;
+    }
+
+    public String getTextLabel() {
+        return textlabel;
+    }
+    
+    public NodeStatus getStatus() {
+        return this.status;
+    }
+
+    public Iterator edges() {
+        return edges.iterator();
+    }
+
+    public void addEdge(Edge newedge) {
+        edges.addElement(newedge);
+    }
+
+    public void reset() {
+        discoverytime = -1;
+        finishingtime = -1;
+        status = UNVISITED;
+    }
+
+    public void discover(int time) {
+        discoverytime = time++;
+        status = PROCESSING;
+    }
+
+    public void finish(int time) {
+        assert status == PROCESSING;
+        finishingtime = time++;
+        status = FINISHED;
+    }
+
+    public int getFinishingTime() {
+        return finishingtime;
+    }
+
+    public static class DOTVisitor {
+        
+        java.io.PrintWriter output;
+        int tokennumber;
+        int color;
+      
+        private DOTVisitor(java.io.OutputStream output) {
+            tokennumber = 0;
+            color = 0;
+            this.output = new java.io.PrintWriter(output, true);
+        }
+        
+        private String getNewID(String name) {
+            tokennumber = tokennumber + 1;
+            return new String (name+tokennumber);
+        }
+
+        Collection nodes;
+        
+        public static void visit(java.io.OutputStream output, Collection nodes) {
+            DOTVisitor visitor = new DOTVisitor(output);
+            visitor.nodes = nodes;
+            visitor.make();
+
+        }
+        
+        private void make() {
+            output.println("digraph dotvisitor {");
+            output.println("\trotate=90;");
+            output.println("\tpage=\"8.5,11\";");
+            output.println("\tnslimit=1000.0;");
+            output.println("\tnslimit1=1000.0;");
+            output.println("\tmclimit=1000.0;");
+            output.println("\tremincross=true;");
+            output.println("\tnode [fontsize=10,height=\"0.1\", width=\"0.1\"];");
+            output.println("\tedge [fontsize=6];");
+
+            traverse();
+
+            output.println("}\n");
+        }
+                
+        private void traverse() {            
+            Iterator i = nodes.iterator();
+            while (i.hasNext()) {
+                GraphNode gn = (GraphNode) i.next();
+                Iterator edges = gn.edges();
+                String label = gn.getTextLabel(); // + " [" + gn.discoverytime + "," + gn.finishingtime + "];";
+                output.println("\t" + gn.getLabel() + " [label=\"" + label + "\"" + gn.dotnodeparams + "];");
+
+                while (edges.hasNext()) {
+                    Edge edge = (Edge) edges.next();
+                    GraphNode node = edge.getTarget();
+                    String edgelabel = useEdgeLabels ? "label=\"" + edge.getLabel() + "\"" : "label=\"\"";
+                    output.println("\t" + gn.getLabel() + " -> " + node.getLabel() + " [" + edgelabel + edge.dotnodeparams + "];");
+                }
+            }
+        }
+    }
+    
+    /**
+     * DFS encapsulates the depth first search algorithm 
+     */
+    public static class DFS {
+
+        int time = 0;
+        Collection nodes;
+
+        private DFS(Collection nodes) { 
+            this.nodes = nodes;
+        }
+
+        public static void depthFirstSearch(Collection nodes) {
+            if (nodes == null) {
+                throw new NullPointerException();
+            }
+            
+            DFS dfs = new DFS(nodes);
+            dfs.go();
+        }
+
+        private void go() {           
+            Iterator i;
+            time = 0;
+            
+            i = nodes.iterator();
+            while (i.hasNext()) {
+                GraphNode gn = (GraphNode) i.next();
+                gn.reset();            
+            }            
+
+            i = nodes.iterator();
+            while (i.hasNext()) {
+                GraphNode gn = (GraphNode) i.next();
+                assert gn.getStatus() != PROCESSING;                    
+                if (gn.getStatus() == UNVISITED) {
+                    dfs(gn);
+                } 
+            }
+        }
+
+        private void dfs(GraphNode gn) {
+            gn.discover(time++);            
+            Iterator edges = gn.edges();
+
+            while (edges.hasNext()) {
+                Edge edge = (Edge) edges.next();
+                GraphNode node = edge.getTarget();
+                if (node.getStatus() == UNVISITED) {
+                    dfs(node);
+                }
+            }
+
+            gn.finish(time++);
+        }                        
+
+    } /* end DFS */
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/IRErrorReporter.java b/Repair/RepairCompiler/MCC/IR/IRErrorReporter.java
new file mode 100755 (executable)
index 0000000..3b013f0
--- /dev/null
@@ -0,0 +1,7 @@
+package MCC.IR;
+
+public interface IRErrorReporter {
+    public void report(ParseNode v, String s);
+    public void warn(ParseNode v, String s);
+    public void setFilename(String filename);
+}
diff --git a/Repair/RepairCompiler/MCC/IR/IRException.java b/Repair/RepairCompiler/MCC/IR/IRException.java
new file mode 100755 (executable)
index 0000000..d9542c9
--- /dev/null
@@ -0,0 +1,23 @@
+package MCC.IR;
+
+/**
+ * If an exception condition occurs while building an IR, an IRException
+ * object is thrown.
+ */
+
+public class IRException extends java.lang.RuntimeException
+{
+    /**
+     * @param reason    reason for exception 
+     */
+    public IRException(String reason)
+    {
+       super(reason);
+    }
+
+    public IRException()
+    {
+       super("IR ERROR");
+    }
+}
+
diff --git a/Repair/RepairCompiler/MCC/IR/ImageSetExpr.java b/Repair/RepairCompiler/MCC/IR/ImageSetExpr.java
new file mode 100755 (executable)
index 0000000..ac255ca
--- /dev/null
@@ -0,0 +1,43 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class ImageSetExpr extends SetExpr {
+    
+    public static final boolean INVERSE = true;
+
+    VarDescriptor vd;
+    RelationDescriptor rd;
+    boolean inverse;
+
+    public ImageSetExpr(VarDescriptor vd, RelationDescriptor rd) {
+        this.vd = vd;
+        this.rd = rd;
+        this.inverse = false;
+    }
+
+    public ImageSetExpr(boolean inverse, VarDescriptor vd, RelationDescriptor rd) {
+        this.vd = vd;
+        this.rd = rd;
+        this.inverse = inverse;
+    }
+
+    public Set getRequiredDescriptors() {
+        HashSet v = new HashSet();
+        v.add(rd);
+        return v;
+    }
+
+    public void generate(CodeWriter writer, VarDescriptor vd) {
+        throw new IRException("not supported");
+    }
+
+    public void prettyPrint(PrettyPrinter pp) {
+        throw new IRException("not supported");
+    }
+
+    public TypeDescriptor typecheck(SemanticAnalyzer sa) {
+        throw new IRException("not supported");
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/Inclusion.java b/Repair/RepairCompiler/MCC/IR/Inclusion.java
new file mode 100755 (executable)
index 0000000..0fe01da
--- /dev/null
@@ -0,0 +1,18 @@
+package MCC.IR;
+
+import java.util.*;
+
+public abstract class Inclusion {
+
+    protected Inclusion() {}
+
+    public abstract Set getTargetDescriptors();
+
+    public abstract Set getRequiredDescriptors();
+
+    public abstract void generate(CodeWriter writer);
+    
+    public abstract boolean typecheck(SemanticAnalyzer sa);
+         
+}
+
diff --git a/Repair/RepairCompiler/MCC/IR/InclusionPredicate.java b/Repair/RepairCompiler/MCC/IR/InclusionPredicate.java
new file mode 100755 (executable)
index 0000000..0944327
--- /dev/null
@@ -0,0 +1,28 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class InclusionPredicate extends Predicate {
+
+    VarDescriptor var;
+    SetExpr setexpr;
+
+    public InclusionPredicate(VarDescriptor var, SetExpr setexpr) {
+        if (var == null) {
+            throw new NullPointerException();
+        }
+
+        if (setexpr == null) {
+            throw new NullPointerException();
+        }
+
+        this.var = var;
+        this.setexpr = setexpr;
+    }
+
+    public Set getRequiredDescriptors() {
+        return setexpr.getRequiredDescriptors();
+    }
+            
+}
+    
diff --git a/Repair/RepairCompiler/MCC/IR/IntegerLiteralExpr.java b/Repair/RepairCompiler/MCC/IR/IntegerLiteralExpr.java
new file mode 100755 (executable)
index 0000000..46a8111
--- /dev/null
@@ -0,0 +1,29 @@
+package MCC.IR;
+
+public class IntegerLiteralExpr extends LiteralExpr {
+
+    int value;
+
+    public IntegerLiteralExpr(int value) {
+        this.value = value; 
+        td = ReservedTypeDescriptor.INT;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public void generate(CodeWriter writer, VarDescriptor dest) {
+        writer.outputline("int " + dest.getSafeSymbol() + " = " + value + ";");
+    }
+
+    public void prettyPrint(PrettyPrinter pp) {
+        pp.output("" + value);
+    }
+
+    public TypeDescriptor typecheck(SemanticAnalyzer sa) {
+        td = ReservedTypeDescriptor.INT;
+        return td;
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/LabelDescriptor.java b/Repair/RepairCompiler/MCC/IR/LabelDescriptor.java
new file mode 100755 (executable)
index 0000000..30f17a2
--- /dev/null
@@ -0,0 +1,39 @@
+package MCC.IR;
+
+/**
+ * LabelDescriptor
+ *
+ * a label descriptor represents a label in a structure which is just
+ * a shorthand notation for another field
+ */
+
+public class LabelDescriptor extends FieldDescriptor {
+
+    FieldDescriptor fd;
+    Expr index;
+
+    public LabelDescriptor(String name) {
+        super(name);
+        index = null;
+    }
+
+    public FieldDescriptor getField() {
+        return fd;
+    }
+
+    public void setField(FieldDescriptor fd) {
+        this.fd = fd;
+    }
+
+    public Expr getIndex() {
+        return index;
+    }
+
+    public void setIndex(Expr index) {
+        this.index = index;
+    }
+
+    public Expr getBaseSizeExpr() {
+        throw new IRException();
+    }
+}
diff --git a/Repair/RepairCompiler/MCC/IR/LiteralExpr.java b/Repair/RepairCompiler/MCC/IR/LiteralExpr.java
new file mode 100755 (executable)
index 0000000..df14ed1
--- /dev/null
@@ -0,0 +1,11 @@
+package MCC.IR;
+
+import java.util.*;
+
+public abstract class LiteralExpr extends Expr {
+
+    public Set getRequiredDescriptors() {
+        return new HashSet();
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/LogicStatement.java b/Repair/RepairCompiler/MCC/IR/LogicStatement.java
new file mode 100755 (executable)
index 0000000..ea44606
--- /dev/null
@@ -0,0 +1,55 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class LogicStatement {
+
+    public static final Operation AND = new Operation("AND");
+    public static final Operation OR = new Operation("OR");
+    public static final Operation NOT = new Operation("NOT");
+    
+    public static class Operation {
+        private final String name;
+        private Operation(String opname) { name = opname; }
+        public String toString() { return name; }
+    }
+
+    Operation op;
+    LogicStatement left;
+    LogicStatement right;
+
+    public LogicStatement(Operation op, LogicStatement left, LogicStatement right) {
+        if (op == NOT) {
+            throw new IllegalArgumentException("Must be a AND or OR expression.");
+        }
+
+        this.op = op;
+        this.left = left;
+        this.right = right;
+    }
+
+    public LogicStatement(Operation op, LogicStatement left) {
+        if (op != NOT) {
+            throw new IllegalArgumentException("Must be a NOT expression.");
+        }
+
+        this.op = op;
+        this.left = left;
+        this.right = null;
+    }
+
+    protected LogicStatement() {
+        this.op = null;
+        this.left = null;
+        this.right = null;
+    }
+
+    public Set getRequiredDescriptors() {
+        Set v = left.getRequiredDescriptors();
+        if (right != null) {
+            v.addAll(right.getRequiredDescriptors());
+        }
+        return v;
+    }
+   
+}
diff --git a/Repair/RepairCompiler/MCC/IR/MissingSetDescriptor.java b/Repair/RepairCompiler/MCC/IR/MissingSetDescriptor.java
new file mode 100755 (executable)
index 0000000..eaa5144
--- /dev/null
@@ -0,0 +1,40 @@
+package MCC.IR;
+
+/**
+ * MissingSetDescriptor
+ *
+ * represents a set in the model space
+ */
+
+import java.util.*;
+
+public class MissingSetDescriptor extends SetDescriptor {
+
+    public MissingSetDescriptor(String name) {
+        super(name);
+    }
+
+    public boolean isPartition() {
+        throw new IRException();
+    }
+    
+    public void isPartition(boolean newvalue) {
+        throw new IRException();
+    }
+
+    public void setType(TypeDescriptor td) {
+        throw new IRException();
+    }
+
+    public TypeDescriptor getType() {
+        throw new IRException();
+    }
+
+    public void addSubset(SetDescriptor sd) {
+        throw new IRException();
+    }
+
+    public Vector getSubsets() {
+        throw new IRException();
+    }
+}
diff --git a/Repair/RepairCompiler/MCC/IR/MissingTypeDescriptor.java b/Repair/RepairCompiler/MCC/IR/MissingTypeDescriptor.java
new file mode 100755 (executable)
index 0000000..0df3caa
--- /dev/null
@@ -0,0 +1,19 @@
+package MCC.IR;
+
+/**
+ * MissingTypeDescriptor
+ *
+ * a placeholder for type descriptors that haven't been found yet
+ */
+
+public class MissingTypeDescriptor extends TypeDescriptor {
+
+    public MissingTypeDescriptor(String name) {
+        super(name);
+    }
+
+    public Expr getSizeExpr() {
+        throw new IRException("invalid");
+    }
+    
+}
diff --git a/Repair/RepairCompiler/MCC/IR/NaiveGenerator.java b/Repair/RepairCompiler/MCC/IR/NaiveGenerator.java
new file mode 100755 (executable)
index 0000000..d4af8e5
--- /dev/null
@@ -0,0 +1,210 @@
+package MCC.IR;
+
+import java.io.*;
+import java.util.*;
+import MCC.State;
+
+public class NaiveGenerator {
+
+    State state;
+    java.io.PrintWriter output = null;
+            
+    public NaiveGenerator(State state) {
+        this.state = state;
+    }
+
+    public void generate(java.io.OutputStream output) {
+        this.output = new java.io.PrintWriter(output, true); 
+
+        generate_hashtables();
+        generate_rules();
+        generate_implicit_checks();
+        generate_checks();
+
+    }
+
+    private void generate_hashtables() {
+
+        CodeWriter cr = new CodeWriter() {
+                
+                int indent = 0;
+                public void indent() { indent++; }
+                public void unindent() { indent--; assert indent >= 0; }
+                private void doindent() {
+                    for (int i = 0; i < indent; i++) { 
+                        output.print("  ");
+                    }
+                }
+                public void outputline(String s) {
+                    doindent();
+                    output.println(s);
+                }                                                             
+                public void output(String s) { throw new IRException(); }
+                public SymbolTable getSymbolTable() { throw new IRException(); }
+            };
+        
+        cr.outputline("// creating hashtables ");
+        
+        /* build all the hashtables */
+        Hashtable hashtables = new Hashtable();
+
+        /* build sets */
+        Iterator sets = state.stSets.descriptors();
+        
+        /* first pass create all the hash tables */
+        while (sets.hasNext()) {
+            SetDescriptor set = (SetDescriptor) sets.next();
+            cr.outputline("SimpleHash* " + set.getSafeSymbol() + "_hash = new SimpleHash();");
+        } 
+
+        /* second pass build relationships between hashtables */
+        sets = state.stSets.descriptors();
+        
+        while (sets.hasNext()) {
+            SetDescriptor set = (SetDescriptor) sets.next();
+            Iterator subsets = set.subsets();
+            
+            while (subsets.hasNext()) {
+                SetDescriptor subset = (SetDescriptor) subsets.next();                
+                cr.outputline(subset.getSafeSymbol() + "_hash->addParent(" + set.getSafeSymbol() + "_hash);");
+            }
+        } 
+
+        /* build relations */
+        Iterator relations = state.stRelations.descriptors();
+        
+        /* first pass create all the hash tables */
+        while (relations.hasNext()) {
+            RelationDescriptor relation = (RelationDescriptor) relations.next();
+            cr.outputline("SimpleHash* " + relation.getSafeSymbol() + "_hash = new SimpleHash();");
+        } 
+
+        cr.outputline("");
+        cr.outputline("");
+
+    }
+
+    private void generate_rules() {
+
+        /* first we must sort the rules */
+        GraphNode.DFS.depthFirstSearch(state.rulenodes.values());
+
+        TreeSet topologicalsort = new TreeSet(new Comparator() {
+                public boolean equals(Object obj) { return false; }
+                public int compare(Object o1, Object o2) {
+                    GraphNode g1 = (GraphNode) o1;
+                    GraphNode g2 = (GraphNode) o2;
+                    return g2.getFinishingTime() - g1.getFinishingTime();
+                }
+            });
+        
+        topologicalsort.addAll(state.rulenodes.values());        
+
+        /* build all the rules */
+        Iterator rules = topologicalsort.iterator();
+                
+        while (rules.hasNext()) {
+
+            GraphNode rulenode = (GraphNode) rules.next();
+            Rule rule = (Rule) rulenode.getOwner();            
+
+            {
+
+                final SymbolTable st = rule.getSymbolTable();
+                
+                CodeWriter cr = new CodeWriter() {
+                        boolean linestarted = false;
+                        int indent = 0;
+                        public void indent() { indent++; }
+                        public void unindent() { indent--; assert indent >= 0; }
+                        private void doindent() {
+                            for (int i = 0; i < indent; i++) { 
+                                output.print("  ");
+                            }
+                            linestarted = true;
+                        }
+                        public void outputline(String s) {
+                            if (!linestarted) {
+                                doindent();
+                            }
+                            output.println(s);
+                            linestarted = false;
+                        }                 
+                        public void output(String s) {
+                            if (!linestarted) {
+                                doindent();
+                            }
+                            output.print(s);
+                            output.flush(); 
+                        }
+                        public SymbolTable getSymbolTable() { return st; }
+                    };
+                
+                cr.outputline("// build " + rule.getLabel());
+                cr.outputline("{");
+                cr.indent();
+
+                ListIterator quantifiers = rule.quantifiers();
+
+                while (quantifiers.hasNext()) {
+                    Quantifier quantifier = (Quantifier) quantifiers.next();                   
+                    quantifier.generate_open(cr);
+                }            
+                        
+                /* pretty print! */
+                cr.output("//");
+                rule.getGuardExpr().prettyPrint(cr);
+                cr.outputline("");
+
+                /* now we have to generate the guard test */
+        
+                VarDescriptor guardval = VarDescriptor.makeNew();
+                rule.getGuardExpr().generate(cr, guardval);
+                
+                cr.outputline("if (" + guardval.getSafeSymbol() + ") {");
+
+                cr.indent();
+
+                /* now we have to generate the inclusion code */
+                rule.getInclusion().generate(cr);
+
+                cr.unindent();
+
+                cr.outputline("}");
+
+                while (quantifiers.hasPrevious()) {
+                    Quantifier quantifier = (Quantifier) quantifiers.previous();
+                    cr.unindent();                    
+                    cr.outputline("}");
+                }
+
+                cr.unindent();
+                cr.outputline("}");
+                cr.outputline("");
+                cr.outputline("");
+            }
+        }
+
+    }
+
+    private void generate_implicit_checks() {
+
+        /* do post checks */
+        //output.println("check to make sure all relations are well typed");
+        //output.println("check multiplicity");
+
+    }
+
+    private void generate_checks() {
+
+        /* do constraint checks */
+        Vector constraints = state.vConstraints;
+
+        for (int i = 0; i < constraints.size(); i++) {
+            //output.println("check constraint " + (i + 1));
+        }
+
+        //output.println("report problems");
+    }    
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/OpExpr.java b/Repair/RepairCompiler/MCC/IR/OpExpr.java
new file mode 100755 (executable)
index 0000000..6ca7d65
--- /dev/null
@@ -0,0 +1,98 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class OpExpr extends Expr {
+
+    Expr left;
+    Expr right;
+    Opcode opcode;
+
+    public OpExpr(Opcode opcode, Expr left, Expr right) {
+        this.opcode = opcode;
+        this.left = left;
+        this.right = right;
+
+        assert (right == null && opcode == Opcode.NOT) || (right != null);
+    }
+
+    public Set getRequiredDescriptors() {
+        Set v = left.getRequiredDescriptors();
+     
+        if (right != null) {
+            v.addAll(right.getRequiredDescriptors());
+        }
+
+        return v;
+    }   
+
+    public void generate(CodeWriter writer, VarDescriptor dest) {
+        VarDescriptor ld = VarDescriptor.makeNew("leftop");
+        left.generate(writer, ld);        
+        VarDescriptor rd = null;
+
+        if (right != null) {
+            rd = VarDescriptor.makeNew("rightop");
+            right.generate(writer, rd);
+        }
+
+        String code;
+        if (opcode != Opcode.NOT) { /* two operands */
+            assert rd != null;
+            writer.outputline("int " + dest.getSafeSymbol() + " = " + 
+                              ld.getSafeSymbol() + " " + opcode.toString() + " " + rd.getSafeSymbol() + ";");
+        } else {
+            writer.outputline("int " + dest.getSafeSymbol() + " = !" + ld.getSafeSymbol() + ";");
+        }
+    }
+
+    public void prettyPrint(PrettyPrinter pp) {
+        if (opcode == Opcode.NOT) {
+            pp.output("!");
+            left.prettyPrint(pp);
+        } else {            
+            left.prettyPrint(pp);
+            pp.output(" " + opcode.toString() + " ");
+            assert right != null;
+            right.prettyPrint(pp);
+        }
+    }
+
+    public TypeDescriptor typecheck(SemanticAnalyzer sa) {
+        TypeDescriptor lt = left.typecheck(sa);
+        TypeDescriptor rt = right == null ? null : right.typecheck(sa);
+
+        if (lt == null) {
+            return null;
+        } else if (right != null && rt == null) {
+            return null;
+        }
+
+        boolean ok = true;
+
+        if (lt != ReservedTypeDescriptor.INT) {
+            sa.getErrorReporter().report(null, "Left hand side of expression is of type '" + lt.getSymbol() + "' but must be type 'int'");
+            ok = false;
+        }
+
+        if (right != null) {
+            if (rt != ReservedTypeDescriptor.INT) {
+                sa.getErrorReporter().report(null, "Right hand side of expression is of type '" + rt.getSymbol() + "' but must be type 'int'");
+                ok = false;
+            }
+        }
+
+        if (!ok) {
+            return null;
+        }
+
+        this.td = ReservedTypeDescriptor.INT;
+        return this.td;
+    }
+
+}
+
+
+
+
+
diff --git a/Repair/RepairCompiler/MCC/IR/Opcode.java b/Repair/RepairCompiler/MCC/IR/Opcode.java
new file mode 100755 (executable)
index 0000000..79a1666
--- /dev/null
@@ -0,0 +1,27 @@
+package MCC.IR;
+
+public class Opcode {
+
+    private final String name;
+    private Opcode(String name) { this.name = name; }
+    
+    public String toString() { return name; }       
+
+    public static final Opcode ADD = new Opcode("+");
+    public static final Opcode SUB = new Opcode("-");
+    public static final Opcode MULT = new Opcode("*");
+    public static final Opcode DIV = new Opcode("/");
+
+    public static final Opcode GT = new Opcode(">");
+    public static final Opcode GE = new Opcode(">=");
+    public static final Opcode LT = new Opcode("<");
+    public static final Opcode LE = new Opcode("<=");
+
+    public static final Opcode EQ = new Opcode("==");
+    public static final Opcode NE = new Opcode("!=");
+
+    public static final Opcode AND = new Opcode("&&");
+    public static final Opcode OR = new Opcode("||");
+    public static final Opcode NOT = new Opcode("!");
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/ParseNode.java b/Repair/RepairCompiler/MCC/IR/ParseNode.java
new file mode 100755 (executable)
index 0000000..4b65354
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ Class: ParseNode
+ Author: Dan Roy
+ Purpose: ParseNode is used to represent a parse production
+
+*/
+
+package MCC.IR;
+
+import java.util.*;
+
+public class ParseNode implements Walkable {
+
+    private String label;
+    private ParseNode parent;
+    private ParseNodeVector children;
+    private int line;
+
+    //private SymbolTable st;
+
+    public ParseNode(String label) {
+       this.label = label;
+       this.line = -1;
+       this.parent = null;
+       children = new ParseNodeVector();
+    }
+
+    public ParseNode ( String label, int line ) {
+       this.label = label;
+       this.line = line;
+       this.parent = null;
+       children = new ParseNodeVector();
+    }
+
+    public void setLabel( String label ) {
+       this.label = label;
+    }
+
+    public String getLabel() {
+       return label;
+    }
+
+    /*
+    public void setSymbolTable(SymbolTable st) {
+       if (st == null) {
+           throw new IRException("symboltable is null!");
+       }
+       this.st = st;
+    }
+
+    public SymbolTable getSymbolTable() {
+       if (st == null) {
+           if (parent != null) {
+               return parent.getSymbolTable();
+           } else {
+               return null;
+           }
+       } else {
+           return st;
+       }
+    }
+    */
+
+    public int getLine() {
+       if (line >= 0) {
+           return line;
+       } else {
+           if (parent != null) {
+               return parent.getLine();
+           } else {
+               return 0;
+           }
+       }
+    }
+
+    public void setParent( ParseNode parent ) {
+       this.parent = parent;
+    }
+
+    public ParseNode getParent() {
+       return parent;
+    }
+
+    public ParseNode insertChild(ParseNode child) {
+       if (child == null) {
+           throw new NullPointerException("Can't add null node to parse tree");
+       }
+
+       children.insertElementAt(child, 0);
+       child.setParent(this);
+       return child;
+    }
+
+    public ParseNode insertChild(String newlabel) {
+       ParseNode child = new ParseNode(newlabel, -1);
+       return insertChild(child);
+    }
+
+    public ParseNode addChild( ParseNode child ) {
+
+       if (child == null) 
+           throw new NullPointerException("Can't add null node to parse tree");
+
+       children.addElement (child);
+       child.setParent(this);
+       return child;
+    }
+
+    public ParseNode addChild( String newlabel ) {
+       
+       ParseNode child = new ParseNode(newlabel, -1);
+       children.addElement(child);
+       child.setParent(this);
+       return child;
+    }
+
+    public ParseNode addChild (String newlabel, int line) {
+       ParseNode child = new ParseNode(newlabel, line);
+       children.addElement(child);
+       child.setParent(this);
+       return child;
+    }
+
+    public ParseNodeVector getChildren() {
+       return children;
+    }
+
+    public ParseNode getChild (String label) {
+       int i;
+       ParseNode p;
+
+       for (i = 0; i < children.size(); i++) {
+           p = children.elementAt(i);
+           if (p.getLabel().equals(label)) {
+               return p;
+           }
+       }
+
+       return null;
+    }
+
+    public ParseNode getRoot() {
+        return (parent == null) ? this : parent.getRoot();
+    }
+
+    public String getTerminal () {
+       ParseNode pn = children.elementAt(0);
+       if (pn == null) {
+           return null;
+       } else {
+           return pn.getLabel();
+       }
+    }
+
+
+    public ParseNodeVector getChildren(String label) {
+       int i;
+       ParseNodeVector v = new ParseNodeVector();
+
+       for (i = 0; i < children.size(); i++) {
+           ParseNode pn = children.elementAt(i);
+           if (pn.getLabel().equals(label))
+               v.addElement(pn);
+       }
+
+       return v;
+    }
+
+    public String getNodeName() {
+       return label + " - " + getLine();
+    }
+
+    public int getNeighborCount() {
+       return children.size();
+    }
+
+    public Object getNeighbor(int index) {
+       return children.elementAt(index);
+    }
+
+    public String doIndent(int indent) {
+
+       String output = new String();
+        for(int i=0;i<indent;i++) output += " ";
+       return output;
+    }
+
+    public String PPrint(int indent, boolean recursive) {
+
+        String output = new String();
+
+       if (children.size()==0) {
+           output += doIndent(indent) + "<" + label + "/>\n";
+       } else {
+           output += doIndent(indent) + "<" + label + ">\n";
+           indent += 2;
+           
+           if (recursive) {
+               for (int i = 0; i < children.size(); i++) {
+                   Walkable w = (Walkable)children.elementAt(i);
+                   output += w.PPrint(indent, true);
+               }
+           } else {
+               for (int i = 0; i < children.size(); i++) {
+                   Walkable w = (Walkable)children.elementAt(i);
+                   output += doIndent(indent) + "<" + w.getNodeName() + "/>\n";
+               }          
+           }
+           
+           indent -= 2;
+           output += doIndent(indent) + "</" + label + ">\n";
+       }
+
+       return output;  
+    }
+
+}
+
diff --git a/Repair/RepairCompiler/MCC/IR/ParseNodeDOTVisitor.java b/Repair/RepairCompiler/MCC/IR/ParseNodeDOTVisitor.java
new file mode 100755 (executable)
index 0000000..7a25ff1
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ Class: ParseNodeDOTVisitor
+ Author: Dan Roy
+ Purpose: Traverses a ParseNode tree and generates a DOT file that represents the parse
+          tree.
+
+*/
+
+package MCC.IR;
+
+import java.util.*;
+
+public class ParseNodeDOTVisitor {
+    
+    java.io.PrintWriter output;
+    int tokennumber;
+    int color;
+
+    private ParseNodeDOTVisitor(java.io.OutputStream output) {
+        tokennumber = 0;
+        color = 0;
+        this.output = new java.io.PrintWriter(output, true);
+    }
+
+    private String getNewID(String name) {
+        tokennumber = tokennumber + 1;
+        return new String (name+tokennumber);
+    }
+
+    public static void visit(java.io.OutputStream output, ParseNode root) {
+        ParseNodeDOTVisitor visitor = new ParseNodeDOTVisitor(output);
+        visitor.make(root);
+    }
+    
+    private void make(ParseNode root) {
+        output.println("digraph dotvisitor {");
+        output.println("\tsize=\"7, 10\";");
+        traverse(root, getNewID("root"));
+        output.println("}\n");
+    }
+
+    private String newColor() {
+
+
+        if (color == 0) {
+            color++;
+            return new String("red");
+        } else if (color == 1) {
+            color++;
+            return new String("green");
+        } else {
+            color = 0;
+            return new String("blue");            
+        }
+    }
+
+    private void traverse(ParseNode node, String nodeid) {
+        output.println("\t" + nodeid + " [label=\"" + node.getLabel() + "\",shape=box];");       
+        ParseNodeVector children = node.getChildren();
+        for (int i = 0; i < children.size(); i++) {
+            ParseNode child = children.elementAt(i);
+            String childid = getNewID("node");
+            output.println("\t" + nodeid + " -> " + childid + ";");
+            if (child.getLabel()=="rule") {
+                output.println("\tnode [color=" + newColor() + "];");
+            }
+            traverse(child, childid);
+        }
+    }
+}
diff --git a/Repair/RepairCompiler/MCC/IR/ParseNodeVector.java b/Repair/RepairCompiler/MCC/IR/ParseNodeVector.java
new file mode 100755 (executable)
index 0000000..7f330d3
--- /dev/null
@@ -0,0 +1,27 @@
+package MCC.IR;
+
+import java.util.Vector;
+
+public class ParseNodeVector {
+    private Vector v;
+
+    public ParseNodeVector() {
+       v = new Vector();
+    }
+
+    public void addElement(ParseNode pn) {
+        v.addElement(pn);
+    }
+
+    public void insertElementAt(ParseNode pn, int n) {
+       v.insertElementAt(pn, n);
+    }
+
+    public ParseNode elementAt(int i) {
+        return (ParseNode) v.elementAt(i);
+    }
+
+    public int size() {
+        return v.size();
+    }
+}
diff --git a/Repair/RepairCompiler/MCC/IR/Predicate.java b/Repair/RepairCompiler/MCC/IR/Predicate.java
new file mode 100755 (executable)
index 0000000..6c1539e
--- /dev/null
@@ -0,0 +1,8 @@
+package MCC.IR;
+
+import java.util.*;
+
+public abstract class Predicate extends LogicStatement {
+    protected Predicate() {}
+}
+    
diff --git a/Repair/RepairCompiler/MCC/IR/PrettyPrinter.java b/Repair/RepairCompiler/MCC/IR/PrettyPrinter.java
new file mode 100755 (executable)
index 0000000..f862d3c
--- /dev/null
@@ -0,0 +1,7 @@
+package MCC.IR;
+
+import java.util.*;
+
+public interface PrettyPrinter {
+    void output(String s);
+}
diff --git a/Repair/RepairCompiler/MCC/IR/Quantifier.java b/Repair/RepairCompiler/MCC/IR/Quantifier.java
new file mode 100755 (executable)
index 0000000..4185cff
--- /dev/null
@@ -0,0 +1,10 @@
+package MCC.IR;
+
+import java.util.*;
+
+public abstract class Quantifier {
+
+    public abstract Set getRequiredDescriptors();
+
+    public abstract void generate_open(CodeWriter writer);
+}
diff --git a/Repair/RepairCompiler/MCC/IR/RelationDescriptor.java b/Repair/RepairCompiler/MCC/IR/RelationDescriptor.java
new file mode 100755 (executable)
index 0000000..61328b7
--- /dev/null
@@ -0,0 +1,46 @@
+package MCC.IR;
+
+/**
+ * RelationDescriptor
+ *
+ * represents a set in the model space
+ */
+
+public class RelationDescriptor extends Descriptor {
+
+    SetDescriptor domain;
+    SetDescriptor range;
+    boolean bStatic;
+
+    public RelationDescriptor(String name) {
+        super(name);
+        bStatic = false;
+        domain = null;
+        range = null;
+    }
+    
+    public boolean isStatic() {
+        return bStatic;
+    }
+    
+    public void isStatic(boolean newvalue) {
+        bStatic = newvalue;
+    }
+
+    public void setDomain(SetDescriptor td) {
+        domain = td;
+    }
+
+    public SetDescriptor getDomain() {
+        return domain;
+    }
+
+    public void setRange(SetDescriptor td) {
+        range = td;
+    }
+
+    public SetDescriptor getRange() {
+        return range;
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/RelationExpr.java b/Repair/RepairCompiler/MCC/IR/RelationExpr.java
new file mode 100755 (executable)
index 0000000..6e1380a
--- /dev/null
@@ -0,0 +1,126 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class RelationExpr extends Expr {
+
+    // #TBD#: right now i'm not sure if this is the best way to organize the relationexpr... it may be better
+    // to have one class represent each a.B.B'.B'' expression with a VarDescriptor for the a and a vector 
+    // for the list of B
+    RelationExpr subdomain;
+    VarDescriptor domain;
+
+    RelationDescriptor relation;
+    boolean inverse;
+
+    public RelationExpr() {
+        this.domain = null;
+        this.subdomain = null;
+        this.relation = null;
+        this.inverse = false;
+    }
+
+    public RelationExpr(RelationExpr subdomain) {
+        this.subdomain = subdomain;
+        this.domain = null;
+        this.relation = null;
+        this.inverse = false;
+    }
+
+    public void setRelation(RelationDescriptor rd, boolean inverse) {
+        this.relation = rd;
+        this.inverse = inverse;
+    }
+
+    public void setDomain(VarDescriptor vd) {
+        this.domain = vd;
+    }
+
+    public Set getRequiredDescriptors() {
+        HashSet v = new HashSet();
+        v.add(relation);
+        if (subdomain != null) {
+            v.addAll(subdomain.getRequiredDescriptors());
+        }
+        return v;
+    }
+
+    public void generate(CodeWriter writer, VarDescriptor dest) {
+        if (domain != null) { /* base case */
+            writer.outputline(relation.getRange().getType().getSafeSymbol() + " " + dest.getSymbol() + " = " + relation.getSafeSymbol() + "_hash.getFirst(" + domain.getSafeSymbol() + ");");
+        } else {
+            VarDescriptor ld = VarDescriptor.makeNew();
+            subdomain.generate(writer, ld);
+            writer.outputline(relation.getRange().getType().getSafeSymbol() + " " + dest.getSymbol() + " = " + relation.getSafeSymbol() + "_hash.getFirst(" + ld.getSafeSymbol() + ");");
+        }            
+
+    }
+
+    public void generate_set(CodeWriter writer, VarDescriptor dest) {
+        if (domain != null) { /* base case */
+            writer.outputline("Set " + dest.getSymbol() + " = " + relation.getSafeSymbol() + "_hash.get(" + domain.getSafeSymbol() + ");");
+        } else {
+            VarDescriptor ld = VarDescriptor.makeNew();
+            subdomain.generate(writer, ld);
+            writer.outputline("Set " + dest.getSymbol() + " = " + relation.getSafeSymbol() + "_hash.get(" + domain.getSafeSymbol() + ");");
+        }     
+    }
+
+    public void prettyPrint(PrettyPrinter pp) {
+        if (subdomain != null) {
+            subdomain.prettyPrint(pp);
+        } else {
+            pp.output(domain.getSafeSymbol());
+        }
+
+        pp.output(".");
+        
+        if (inverse) {
+            pp.output("~");
+        }
+
+        pp.output(relation.getSafeSymbol());
+    }
+
+    public TypeDescriptor typecheck(SemanticAnalyzer sa) {
+        TypeDescriptor type = null;
+        
+        if (domain != null) {
+            type = domain.getType();            
+        } else {
+            type = subdomain.typecheck(sa);
+        }
+
+        if (type == null) {
+            return null;
+        }
+
+        /* check to make sure that the types of the relation match up */
+        if (inverse) {
+            TypeDescriptor rangetype = relation.getRange().getType();
+            
+            if (rangetype != type) {
+                sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() + 
+                                    "' but must be the '" + rangetype.getSymbol() + 
+                                    "', the type of the range of the relation '" + relation.getSymbol() + "'");
+                return null;
+            }
+            
+            this.td = relation.getDomain().getType();
+            return this.td;
+        } else { /* not inverse */
+            TypeDescriptor domaintype = relation.getDomain().getType();
+            
+            if (domaintype != type) {
+                sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() + 
+                                    "' but must be the '" + domaintype.getSymbol() + 
+                                    "', the type of the range of the relation '" + relation.getSymbol() + "'");
+                return null;
+            }
+
+            this.td = relation.getRange().getType();
+            return this.td;
+        }
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/RelationInclusion.java b/Repair/RepairCompiler/MCC/IR/RelationInclusion.java
new file mode 100755 (executable)
index 0000000..f0fd0c4
--- /dev/null
@@ -0,0 +1,62 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class RelationInclusion extends Inclusion {
+    
+    Expr leftelementexpr, rightelementexpr;
+    RelationDescriptor relation;
+
+    public RelationInclusion(Expr leftelementexpr, Expr rightelementexpr, RelationDescriptor relation) {
+        this.leftelementexpr = leftelementexpr;
+        this.rightelementexpr = rightelementexpr;
+        this.relation = relation;
+    }
+
+    public Set getTargetDescriptors() {
+        HashSet v = new HashSet();
+        v.add(relation);
+        return v;
+    }
+
+    public Set getRequiredDescriptors() {
+        Set v = leftelementexpr.getRequiredDescriptors();
+        v.addAll(rightelementexpr.getRequiredDescriptors());
+        return v;
+    }
+
+    public void generate(CodeWriter writer) {
+        VarDescriptor ld = VarDescriptor.makeNew("leftele");
+        leftelementexpr.generate(writer, ld);
+        VarDescriptor rd = VarDescriptor.makeNew("rightele");
+        rightelementexpr.generate(writer, rd);
+        writer.outputline(relation.getSafeSymbol() + "_hash->add((int)" + ld.getSafeSymbol() + ", (int)" + rd.getSafeSymbol() + ");");
+        //writer.outputline("printf(\"" + relation.getSafeSymbol() + " (add): <%d, %d>\\n\", " + ld.getSafeSymbol() + ", " + rd.getSafeSymbol() + ");");
+    }
+
+    public boolean typecheck(SemanticAnalyzer sa) {
+        TypeDescriptor ld = leftelementexpr.typecheck(sa);
+        TypeDescriptor rd = rightelementexpr.typecheck(sa);
+        
+        if (ld == null || rd == null) {
+            return false;
+        }
+
+        boolean ok = true;
+
+        if (ld != relation.getDomain().getType()) {
+            sa.getErrorReporter().report(null, "Type of left element '" + ld.getSymbol() + "' must match domain type '" + relation.getDomain().getType().getSymbol() + "'");
+            ok = false;
+        }
+
+        if (rd != relation.getRange().getType()) {
+            assert rd.getSymbol() != null;
+            assert relation.getRange().getType() != null : relation.getRange().getSymbol();
+            sa.getErrorReporter().report(null, "Type of right element '" + rd.getSymbol() + "' must match range type '" + relation.getRange().getType().getSymbol() + "'");
+            ok = false;
+        }
+
+        return ok;
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/RelationQuantifier.java b/Repair/RepairCompiler/MCC/IR/RelationQuantifier.java
new file mode 100755 (executable)
index 0000000..ae6886e
--- /dev/null
@@ -0,0 +1,39 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class RelationQuantifier extends Quantifier {
+
+    RelationDescriptor relation;
+    VarDescriptor x, y; // y = x.relation
+
+    public RelationQuantifier() {}
+
+    public void setRelation(RelationDescriptor rd) {
+        relation = rd; 
+    }
+
+    public void setTuple(VarDescriptor x, VarDescriptor y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    public Set getRequiredDescriptors() {
+        HashSet v = new HashSet();
+        v.add(relation);
+        return v;
+    }
+
+    public String toString() {
+        return "relation quantifier <" + x.getSymbol() + "," + y.getSymbol() + "> in " + relation.getSymbol();
+    }
+
+    public void generate_open(CodeWriter writer) {
+        writer.outputline("for (SimpleIterator* " + x.getSafeSymbol() + "_iterator = " + relation.getSafeSymbol() + "_hash->iterator(); " + x.getSafeSymbol() + "_iterator->hasNext(); ) {");
+        writer.indent();
+        writer.outputline(y.getType().getSafeSymbol() + " " + y.getSafeSymbol() + " = (" + y.getType().getSafeSymbol() + ") " + x.getSafeSymbol() + "_iterator->next();");        
+        // #ATTN#: key is called second because next() forwards ptr and key does not! 
+        writer.outputline(x.getType().getSafeSymbol() + " " + x.getSafeSymbol() + " = (" + x.getType().getSafeSymbol() + ") " + x.getSafeSymbol() + "_iterator->key();");
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/ReservedFieldDescriptor.java b/Repair/RepairCompiler/MCC/IR/ReservedFieldDescriptor.java
new file mode 100755 (executable)
index 0000000..e89b938
--- /dev/null
@@ -0,0 +1,18 @@
+package MCC.IR;
+
+/**
+ * ReservedFieldDescriptor
+ *
+ * represents an unreferencable region of a structure. usually used
+ * for padding structures or for allocating generic memory space
+ */
+
+public class ReservedFieldDescriptor extends FieldDescriptor {
+
+    static int number = 0;
+
+    public ReservedFieldDescriptor() {
+        super("#RESERVED-" + ReservedFieldDescriptor.number++ + "#");
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/ReservedSetDescriptor.java b/Repair/RepairCompiler/MCC/IR/ReservedSetDescriptor.java
new file mode 100755 (executable)
index 0000000..9667144
--- /dev/null
@@ -0,0 +1,16 @@
+package MCC.IR;
+
+/**
+ * ReservedSetDescriptor
+ *
+ * handles reserved sets: int and Token
+ */
+
+public class ReservedSetDescriptor extends SetDescriptor {
+
+    public ReservedSetDescriptor(String name, TypeDescriptor td) {
+        super(name);
+        setType(td);
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/ReservedTypeDescriptor.java b/Repair/RepairCompiler/MCC/IR/ReservedTypeDescriptor.java
new file mode 100755 (executable)
index 0000000..a02dd31
--- /dev/null
@@ -0,0 +1,31 @@
+package MCC.IR;
+
+/**
+ * ReservedTypeDescriptor
+ *
+ * handles reserved types: bit, byte, short, int
+ */
+
+public class ReservedTypeDescriptor extends TypeDescriptor {
+
+    IntegerLiteralExpr size;
+
+    public static final ReservedTypeDescriptor BIT = new ReservedTypeDescriptor("bit", 1);
+    public static final ReservedTypeDescriptor BYTE = new ReservedTypeDescriptor("byte", 8);
+    public static final ReservedTypeDescriptor SHORT = new ReservedTypeDescriptor("short", 16);
+    public static final ReservedTypeDescriptor INT = new ReservedTypeDescriptor("int", 32);
+
+    private ReservedTypeDescriptor(String name, int size) {
+        super(name);
+        this.size = new IntegerLiteralExpr(size);
+    }
+
+    public Expr getSizeExpr() {
+        return size;
+    }
+
+    public String getSafeSymbol() {
+        return getSymbol();
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/Rule.java b/Repair/RepairCompiler/MCC/IR/Rule.java
new file mode 100755 (executable)
index 0000000..16087e2
--- /dev/null
@@ -0,0 +1,80 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class Rule {
+    
+    static int count = 1;
+
+    Vector quantifiers = new Vector();
+    boolean isstatic = false;
+    boolean isdelay = false;
+    Expr guard = null;
+    Inclusion inclusion = null;    
+    SymbolTable st = new SymbolTable();
+    
+    String label;
+
+    public Rule () {
+        label = new String("rule" + count++);
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public void setStatic(boolean val) {
+        isstatic = val;
+    }
+
+    public void setDelay(boolean val) {
+        isdelay = val;
+    }
+
+    public void addQuantifier(Quantifier q) {
+        quantifiers.addElement(q);
+    }
+
+    public ListIterator quantifiers() {
+        return quantifiers.listIterator();
+    }
+
+    public void setGuardExpr(Expr guard) {
+        this.guard = guard;
+    }
+    
+    public Expr getGuardExpr() {
+        return guard;
+    }
+
+    public void setInclusion(Inclusion inclusion) {
+        this.inclusion = inclusion;
+    }
+
+    public Inclusion getInclusion() {
+        return inclusion;
+    }
+    
+    public SymbolTable getSymbolTable() {
+        return st;
+    }
+
+    public Set getRequiredDescriptors() {
+
+        HashSet topdescriptors = new HashSet();
+
+        for (int i = 0; i < quantifiers.size(); i++) {            
+            Quantifier q = (Quantifier) quantifiers.elementAt(i);
+            topdescriptors.addAll(q.getRequiredDescriptors());                
+        }
+
+        assert guard != null;            
+        topdescriptors.addAll(guard.getRequiredDescriptors());
+        
+        assert inclusion != null;
+        topdescriptors.addAll(inclusion.getRequiredDescriptors());
+        
+        return SetDescriptor.expand(topdescriptors);
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/ScheduleEvent.java b/Repair/RepairCompiler/MCC/IR/ScheduleEvent.java
new file mode 100755 (executable)
index 0000000..ea3cd51
--- /dev/null
@@ -0,0 +1,11 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class ScheduleEvent {
+
+    Vector preconditions;
+    Vector postconditions;
+
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/SemanticAnalyzer.java b/Repair/RepairCompiler/MCC/IR/SemanticAnalyzer.java
new file mode 100755 (executable)
index 0000000..2f14553
--- /dev/null
@@ -0,0 +1,11 @@
+package MCC.IR;
+
+import java.util.*;
+
+public interface SemanticAnalyzer {
+    
+    IRErrorReporter getErrorReporter();
+
+    SymbolTable getSymbolTable();
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/SemanticChecker.java b/Repair/RepairCompiler/MCC/IR/SemanticChecker.java
new file mode 100755 (executable)
index 0000000..be4e07d
--- /dev/null
@@ -0,0 +1,1605 @@
+package MCC.IR;
+
+import java.util.*;
+import java.math.BigInteger;
+import MCC.State;
+
+public class SemanticChecker {
+
+    private static final boolean CREATE_MISSING = true;
+
+    public State state;
+
+    Vector vConstraints;
+    Vector vRules;
+
+    SymbolTableStack sts;
+
+    SymbolTable stSets;
+    SymbolTable stRelations;
+    SymbolTable stTypes;
+    SymbolTable stGlobals;
+
+    StructureTypeDescriptor dCurrentType;
+
+    IRErrorReporter er;
+    
+    public SemanticChecker () {
+        dCurrentType = null;
+       stTypes = null;
+       er = null;
+    }
+
+    public boolean check(State state, IRErrorReporter er) {
+
+       this.state = state;
+       State.currentState = state;
+
+       // Don't clear the state!!  Do clear the IR-related state
+       this.state.stTypes = null;
+
+       if (er == null) {
+           throw new IRException("IRBuilder.build: Received null ErrorReporter");
+       } else {
+           this.er = er;
+       }
+
+       if (state.ptStructures == null) {
+           throw new IRException("IRBuilder.build: Received null ParseNode");
+       }
+
+        state.vConstraints = new Vector();
+        vConstraints = state.vConstraints;
+
+        state.vRules = new Vector();
+        vRules = state.vRules;
+
+       state.stTypes = new SymbolTable();
+       stTypes = state.stTypes;
+
+       state.stSets = new SymbolTable();
+       stSets = state.stSets;
+
+       state.stRelations = new SymbolTable();
+       stRelations = state.stRelations;
+
+        state.stGlobals = new SymbolTable();
+        stGlobals = state.stGlobals;
+
+        sts = new SymbolTableStack();
+       
+       // add int and bool to the types list
+       stTypes.add(ReservedTypeDescriptor.BIT);
+       stTypes.add(ReservedTypeDescriptor.BYTE);
+       stTypes.add(ReservedTypeDescriptor.SHORT);
+       stTypes.add(ReservedTypeDescriptor.INT);
+
+        stSets.add(new ReservedSetDescriptor("int", ReservedTypeDescriptor.INT));
+        stSets.add(new ReservedSetDescriptor("token", ReservedTypeDescriptor.INT));
+
+       boolean ok = true; 
+
+        er.setFilename(state.infile + ".struct");
+        if (!parse_structures(state.ptStructures)) {
+            ok = false;
+        }
+
+        er.setFilename(state.infile + ".space");
+        if (!parse_space(state.ptSpace)) {
+            ok = false;
+        }
+        
+        er.setFilename(state.infile + ".constraints");
+        if (!parse_constraints(state.ptConstraints)) {
+            ok = false;
+        }
+
+        er.setFilename(state.infile + ".model");
+        if (!parse_rules(state.ptModel)) {
+            ok = false;
+        }
+
+        return ok;
+    }
+
+    /********************** HELPER FUNCTIONS ************************/ 
+
+    /**
+     * special case lookup that returns null if no such type exists 
+     */
+    private TypeDescriptor lookupType(String typename) {
+        return lookupType(typename, false);
+    }
+
+    /**
+     * does a look up in the types symbol table. if the type is
+     * not found than a missing type descriptor is returned
+     */
+    private TypeDescriptor lookupType(String typename, boolean createmissing) {
+        if (stTypes.get(typename) != null) {
+            // the type exists, so plug in the descriptor directly 
+            return (TypeDescriptor) stTypes.get(typename);              
+        } else if (createmissing) {
+            return new MissingTypeDescriptor(typename);
+        } else {
+            return null;
+        }       
+    }
+
+    /**
+     * reserve a name 
+     */
+    private VarDescriptor reserveName(ParseNode pn) {
+        assert pn != null;
+        String varname = pn.getTerminal();
+        assert varname != null;
+                
+        /* do semantic check and if valid, add it to symbol table
+           and add it to the quantifier as well */
+        if (sts.peek().contains(varname)) {
+            /* Semantic Error: redefinition */
+            er.report(pn, "Redefinition of '" + varname + "'");
+            return null;
+        } else {
+            VarDescriptor vd = new VarDescriptor(varname);
+            sts.peek().add(vd);
+            return vd;
+        }
+    }
+
+    /**
+     * special case lookup that returns null if no such set exists 
+     */
+    private SetDescriptor lookupSet(String setname) {
+        return lookupSet(setname, false);
+    }
+
+    /**
+     * does a look up in the set's symbol table. if the set is
+     * not found than a missing set descriptor is returned
+     */
+    private SetDescriptor lookupSet(String setname, boolean createmissing) {
+        if (stSets.get(setname) != null) {
+            // the set exists, so plug in the descriptor directly 
+            return (SetDescriptor) stSets.get(setname);              
+        } else if (createmissing) {
+            return new MissingSetDescriptor(setname);
+        } else {
+            return null;
+        }       
+    }
+    
+    /**
+     * does a look up in the set's symbol table. if the set is
+     * not found than a missing set descriptor is returned
+     */
+    private RelationDescriptor lookupRelation(String relname) {
+        if (stRelations.get(relname) != null) {
+            // the relation exists, so plug in the descriptor directly 
+            return (RelationDescriptor) stRelations.get(relname);              
+        } else {
+            return null;
+        }       
+    }
+    
+    
+    private static int count = 0;
+    private boolean precheck(ParseNode pn, String label) {             
+       if (pn == null) {
+            er.report(pn, "IE: Expected '" + label + "', got null");
+            assert false;
+           return false;
+       }
+
+       if (! pn.getLabel().equals(label)) {
+           er.report(pn, "IE: Expected '" + label + "', got '" + pn.getLabel() + "'");
+            assert false;
+           return false;
+       }
+
+        if (state.verbose >= 2) {
+            System.err.println("visiting*" + (count++) + ": " + label);
+        }
+
+       return true;
+    }
+
+    /********************* PARSING FUNCTIONS ************************/ 
+
+    private boolean parse_rules(ParseNode pn) {
+        if (!precheck(pn, "rules")) {
+            return false;
+        }
+
+        boolean ok = true;
+        ParseNodeVector rules = pn.getChildren();
+        
+        for (int i = 0; i < rules.size(); i++) {
+            ParseNode rule = rules.elementAt(i);
+            if (!parse_rule(rule)) {
+                ok = false;
+            }
+        }
+               
+        /* type check */       
+        Iterator ruleiterator = state.vRules.iterator();
+        
+        while (ruleiterator.hasNext()) {
+            Rule rule = (Rule) ruleiterator.next();            
+            Expr guard = rule.getGuardExpr();
+            final SymbolTable rulest = rule.getSymbolTable();
+            SemanticAnalyzer sa = new SemanticAnalyzer() {
+                    public IRErrorReporter getErrorReporter() { return er; }
+                    public SymbolTable getSymbolTable() { return rulest; }
+                };
+            TypeDescriptor guardtype = guard.typecheck(sa);
+            
+            if (guardtype == null) {
+                ok = false;
+            } else if (guardtype != ReservedTypeDescriptor.INT) {
+                er.report(null, "Type of guard must be 'int' not '" + guardtype.getSymbol() + "'");
+                ok = false;
+            }
+            
+            if (!rule.getInclusion().typecheck(sa)) {
+                ok = false;
+            }           
+            
+            Iterator quantifiers = rule.quantifiers();
+            
+            while (quantifiers.hasNext()) {
+                Quantifier q = (Quantifier) quantifiers.next();
+                
+                if (q instanceof ForQuantifier && !((ForQuantifier)q).typecheck(sa)) {
+                    ok = false;
+                }
+            }              
+        }        
+
+        /* do any post checks ?? */
+
+        return ok;
+    }
+
+    private boolean parse_rule(ParseNode pn) {
+        if (!precheck(pn, "rule")) {
+            return false;
+        }
+
+        boolean ok = true;
+        Rule rule = new Rule();
+        
+        /* get rule type */
+        boolean isstatic = pn.getChild("static") != null;
+        boolean isdelay = pn.getChild("delay") != null;
+        rule.setStatic(isstatic);
+        rule.setDelay(isdelay);
+
+        /* set up symbol table for constraint */
+        assert sts.empty();
+        sts.push(stGlobals);
+        sts.push(rule.getSymbolTable());
+
+        /* optional quantifiers */
+        if (pn.getChild("quantifiers") != null) {
+            ParseNodeVector quantifiers = pn.getChild("quantifiers").getChildren();
+            
+            for (int i = 0; i < quantifiers.size(); i++) {
+                ParseNode qn = quantifiers.elementAt(i);
+                Quantifier quantifier = parse_quantifier(qn);
+
+                if (quantifier == null) {
+                    ok = false;
+                } else {
+                    rule.addQuantifier(quantifier);
+                }
+            }             
+        }
+        
+        /* get guard expr */
+        Expr guard = parse_expr(pn.getChild("expr"));
+
+        if (guard == null) {
+            ok = false;
+        } else {
+            rule.setGuardExpr(guard);
+        }
+
+        /* inclusion constraint */
+        Inclusion inclusion = parse_inclusion(pn.getChild("inclusion"));
+        
+        if (inclusion == null) {
+            ok = false;
+        } else {
+            rule.setInclusion(inclusion);
+        }
+        
+        /* pop symbol table stack */
+        SymbolTable st = sts.pop();
+        sts.pop(); /* pop off globals */
+
+        /* make sure the stack we pop is our rule s.t. */
+        assert st == rule.getSymbolTable(); 
+        assert sts.empty();
+
+        /* add rule to global set */
+        vRules.addElement(rule);
+
+        return ok;
+    }
+
+    private Inclusion parse_inclusion(ParseNode pn) {
+        if (!precheck(pn, "inclusion")) {
+            return null;
+        }
+
+        if (pn.getChild("set") != null) {
+            ParseNode set = pn.getChild("set");
+            Expr expr = parse_expr(set.getChild("expr"));
+            
+            if (expr == null) {
+                return null;
+            }
+
+            String setname = set.getChild("name").getTerminal();
+            assert setname != null;
+            SetDescriptor sd = lookupSet(setname);
+            
+            if (sd == null) {
+                er.report(set.getChild("name"), "Undefined set '" + setname + "'");
+                return null;
+            }
+
+            return new SetInclusion(expr, sd);
+        } else if (pn.getChild("relation") != null) {
+            ParseNode relation = pn.getChild("relation");
+            Expr leftexpr = parse_expr(relation.getChild("left").getChild("expr"));
+            Expr rightexpr = parse_expr(relation.getChild("right").getChild("expr"));
+            
+            if ((leftexpr == null) || (rightexpr == null)) {
+                return null;
+            }
+
+            String relname = relation.getChild("name").getTerminal();
+            assert relname != null;
+            RelationDescriptor rd = lookupRelation(relname);
+
+            if (rd == null) {
+                er.report(relation.getChild("name"), "Undefined relation '" + relname + "'");
+                return null;
+            }
+
+            return new RelationInclusion(leftexpr, rightexpr, rd);
+        } else {
+            throw new IRException();
+        }
+    }
+
+    private boolean parse_constraints(ParseNode pn) {
+        if (!precheck(pn, "constraints")) {
+            return false;
+        }
+
+        boolean ok = true;
+        ParseNodeVector constraints = pn.getChildren();
+        
+        for (int i = 0; i < constraints.size(); i++) {
+            ParseNode constraint = constraints.elementAt(i);
+            assert constraint.getLabel().equals("constraint");
+            if (!parse_constraint(constraint)) {
+                ok = false;
+            }
+        }
+
+        /* do any post checks... (type constraints, etc?) */
+         
+        return ok;
+    }
+
+    private boolean parse_constraint(ParseNode pn) {
+        if (!precheck(pn, "constraint")) {
+            return false;
+        }
+
+        boolean ok = true;
+        Constraint constraint = new Constraint();
+
+        /* test crash */
+        boolean crash = pn.getChild("crash") != null;
+        constraint.setCrash(crash);
+
+        /* set up symbol table for constraint */
+        assert sts.empty();
+        sts.push(constraint.getSymbolTable());
+        
+        /* get quantifiers */
+        if (pn.getChild("quantifiers") != null) {
+            ParseNodeVector quantifiers = pn.getChild("quantifiers").getChildren();
+            
+            for (int i = 0; i < quantifiers.size(); i++) {
+                ParseNode qn = quantifiers.elementAt(i);
+                assert qn.getLabel().equals("quantifier");
+                Quantifier quantifier = parse_quantifier(qn);
+                if (quantifier == null) {
+                    ok = false;
+                } else {
+                    constraint.addQuantifier(quantifier);
+                }
+            }
+        }
+                                                      
+        /* get body */
+        LogicStatement logicexpr = parse_body(pn.getChild("body"));
+
+        if (logicexpr == null) {
+            ok = false;
+        } else {
+            constraint.setLogicStatement(logicexpr);
+        }
+        
+        /* pop symbol table stack */
+        SymbolTable st = sts.pop();
+
+        /* make sure the stack we pop is our constraint s.t. */
+        assert st == constraint.getSymbolTable(); 
+        assert sts.empty();
+
+        /* add to vConstraints */
+        vConstraints.addElement(constraint);           
+
+        return ok;
+    }
+
+    private Quantifier parse_quantifier(ParseNode pn) {
+        if (!precheck(pn, "quantifier")) {
+            return null;           
+        }
+
+        if (pn.getChild("forall") != null) { /* forall element in Set */
+            SetQuantifier sq = new SetQuantifier();
+
+            /* get var */
+            VarDescriptor vd = reserveName(pn.getChild("var"));
+            
+            if (vd == null) {
+                return null;
+            } 
+
+            sq.setVar(vd);
+
+            /* parse the set */
+            SetDescriptor set = parse_set(pn.getChild("set"));
+            assert set != null;
+            sq.setSet(set);
+
+            vd.setType(set.getType());
+
+            /* return to caller */
+            return sq;
+
+        } else if (pn.getChild("relatiion") != null) { /* for < v1, v2 > in Relation */
+            RelationQuantifier rq = new RelationQuantifier();
+
+            /* get vars */
+            VarDescriptor vd1 = reserveName(pn.getChild("left"));
+            VarDescriptor vd2 = reserveName(pn.getChild("right"));
+            
+            if ((vd1 == null) || (vd2 == null)) {
+                return null;
+            }
+            
+            rq.setTuple(vd1, vd2);
+            
+            /* get relation */
+            String relationname = pn.getChild("relation").getTerminal();
+            assert relationname != null;
+            RelationDescriptor rd = lookupRelation(relationname);
+
+            if (rd == null) {
+                return null;
+            }
+            
+            rq.setRelation(rd);
+            vd1.setType(rd.getDomain().getType());
+            vd2.setType(rd.getRange().getType());
+            return rq;
+        } else if (pn.getChild("for") != null) { /* for j = x to y */
+            ForQuantifier fq = new ForQuantifier();
+            
+            /* grab var */
+            VarDescriptor vd = reserveName(pn.getChild("var"));
+
+            if (vd == null) {
+                return null;
+            }
+
+            vd.setType(ReservedTypeDescriptor.INT);
+            fq.setVar(vd);
+
+            /* grab lower/upper bounds */
+            Expr lower = parse_expr(pn.getChild("lower").getChild("expr"));
+            Expr upper = parse_expr(pn.getChild("upper").getChild("expr"));
+
+            if ((lower == null) || (upper == null)) {
+                return null;
+            }
+
+            fq.setBounds(lower, upper);
+
+            return fq;
+        } else {
+            throw new IRException("not supported yet");
+        }
+
+    }
+
+    private LogicStatement parse_body(ParseNode pn) {
+        if (!precheck(pn, "body")) {
+            return null;           
+        }
+        
+        if (pn.getChild("and") != null) {
+            /* body AND body */
+            LogicStatement left, right;
+            left = parse_body(pn.getChild("and").getChild("left").getChild("body"));
+            right = parse_body(pn.getChild("and").getChild("right").getChild("body"));
+            
+            if ((left == null) || (right == null)) {
+                return null;
+            }
+            
+            // what do we want to call the and/or/not body classes?
+            return new LogicStatement(LogicStatement.AND, left, right);
+        } else if (pn.getChild("or") != null) {
+            /* body OR body */
+            LogicStatement left, right;
+            left = parse_body(pn.getChild("or").getChild("left").getChild("body"));
+            right = parse_body(pn.getChild("or").getChild("right").getChild("body"));
+            
+            if ((left == null) || (right == null)) {
+                return null;
+            }
+
+            return new LogicStatement(LogicStatement.OR, left, right);
+        } else if (pn.getChild("not") != null) {
+            /* NOT body */
+            LogicStatement left = parse_body(pn.getChild("not").getChild("left").getChild("body"));
+            
+            if (left == null) {
+                return null;
+            }
+            
+            return new LogicStatement(LogicStatement.NOT, left);
+        } else if (pn.getChild("predicate") != null) {
+            return parse_predicate(pn.getChild("predicate"));
+        } else {
+            throw new IRException();
+        }                        
+    }
+
+    private Predicate parse_predicate(ParseNode pn) {
+        if (!precheck(pn, "predicate")) {
+            return null;
+        }
+
+        if (pn.getChild("comparison") != null) {
+            ParseNode cn = pn.getChild("comparison");
+            
+            /* get the expr's */
+            Expr left = parse_expr(cn.getChild("left").getChild("expr"));
+            Expr right = parse_expr(cn.getChild("right").getChild("expr"));
+
+            if ((left == null) || (right == null)) {
+                return null;
+            }
+
+            /* get comparison operator */
+            String comparison = cn.getChild("compare").getTerminal();
+            assert comparison != null;
+                         
+            return new ComparisonPredicate(comparison, left, right);
+        } else if (pn.getChild("inclusion") != null) {
+            ParseNode in = pn.getChild("inclusion");
+            
+            /* get quantiifer var */
+            VarDescriptor vd = parse_quantifiervar(in.getChild("quantifiervar"));
+           
+            if (vd == null) { 
+                return null;
+            }
+
+            /* get set expr */
+            SetExpr setexpr = parse_setexpr(in.getChild("setexpr"));
+
+            if (setexpr == null) {
+                return null;
+            }
+
+            return new InclusionPredicate(vd, setexpr);
+        } else {
+            throw new IRException();
+        }       
+    }
+
+    private SetDescriptor parse_set(ParseNode pn) {
+        if (!precheck(pn, "set")) {
+            return null;
+        }
+    
+        if (pn.getChild("name") != null) {
+            String setname = pn.getChild("name").getTerminal();
+            assert setname != null;
+                
+            if (!stSets.contains(setname)) {
+                /* Semantic Error: unknown set */
+                er.report(pn, "Unknown set '" + setname + "' referenced in quantifier");
+                return null;
+            } else {
+                /* all good, get setdescriptor */
+                SetDescriptor sd = (SetDescriptor) stSets.get(setname);
+                assert sd != null;
+                return sd;
+            }            
+        } else if (pn.getChild("listofliterals") != null) {            
+            TokenSetDescriptor tokenset = new TokenSetDescriptor();
+            ParseNodeVector token_literals = pn.getChild("listofliterals").getChildren();
+            assert token_literals.size() > 0;
+            
+            for (int i = 0; i < token_literals.size(); i++) {
+                ParseNode literal = token_literals.elementAt(i);
+                assert literal.getLabel().equals("literal");
+                LiteralExpr litexpr = parse_literal(literal);
+
+                if (litexpr == null) {
+                    return null;
+                }
+                
+                if (litexpr instanceof TokenLiteralExpr || litexpr instanceof IntegerLiteralExpr) {
+                    tokenset.addLiteral(litexpr);
+                } else {
+                    er.report(literal, "Elements of a user-defined set must be of type token or integer");
+                    // return null; /* don't think we need to return null */
+                }
+            }               
+
+            return tokenset;
+        } else {
+            throw new IRException(pn.getTerminal());
+        }
+    }
+    
+    private boolean parse_space(ParseNode pn) {
+        if (!precheck(pn, "space")) {
+            return false;
+        }
+        
+        boolean ok = true;
+        ParseNodeVector sets = pn.getChildren("setdefinition");
+        ParseNodeVector relations = pn.getChildren("relationdefinition");
+
+        assert pn.getChildren().size() == (sets.size() + relations.size());
+        
+        /* parse sets */
+        for (int i = 0; i < sets.size(); i++) {
+            if (!parse_setdefinition(sets.elementAt(i))) {
+                ok = false;
+            }
+        }
+
+        /* parse relations */
+        for (int i = 0; i < relations.size(); i++) {
+            if (!parse_relationdefinition(relations.elementAt(i))) {
+                ok = false;
+            }
+        }
+
+        // ok, all the spaces have been parsed, now we should typecheck and check
+        // for cycles etc.
+
+        // #TBD#: typecheck and check for cycles
+      
+        /* replace missing with actual */
+        Iterator allsets = state.stSets.descriptors();
+        
+        while (allsets.hasNext()) {
+            SetDescriptor sd = (SetDescriptor) allsets.next();
+            Vector subsets = sd.getSubsets();
+
+            for (int i = 0; i < subsets.size(); i++) {
+                SetDescriptor subset = (SetDescriptor) subsets.elementAt(i);
+                
+                if (subset instanceof MissingSetDescriptor) {
+                    SetDescriptor newsubset = lookupSet(subset.getSymbol());
+
+                    if (newsubset == null) {
+                        er.report(null, "Unknown subset '" + subset.getSymbol() + "'");
+                    } else {
+                        subsets.setElementAt(newsubset, i);
+                    }
+                }
+            }
+        }
+        
+        return ok;
+    }
+
+    private boolean parse_setdefinition(ParseNode pn) {
+        if (!precheck(pn, "setdefinition")) {
+            return false;
+        }
+        
+        boolean ok = true;
+        
+        /* get set name */
+        String setname = pn.getChild("name").getTerminal();
+        assert (setname != null);
+
+        SetDescriptor sd = new SetDescriptor(setname);
+        
+        /* get set type */
+        String settype = pn.getChild("type").getTerminal();
+        TypeDescriptor type = lookupType(settype);
+        if (type == null) {
+            er.report(pn, "Undefined type '" + settype + "'");
+            ok = false; 
+        } else {
+            sd.setType(type);
+        }
+
+        /* is this a partition? */
+        boolean partition = pn.getChild("partition") != null;
+        sd.isPartition(partition); 
+
+        /* if set has subsets, add them to set descriptor */
+        if (pn.getChild("setlist") != null) {
+            ParseNodeVector setlist = pn.getChild("setlist").getChildren();
+            
+            for (int i = 0; i < setlist.size(); i++) {
+                String subsetname = setlist.elementAt(i).getLabel();
+                sd.addSubset(lookupSet(subsetname, CREATE_MISSING));
+            }            
+        }
+
+        /* add set to symbol table */
+        if (stSets.contains(setname)) {
+            // Semantic Check: redefinition
+            er.report(pn, "Redefinition of set: " + setname);
+            ok = false;
+        } else {
+            stSets.add(sd);
+        }
+
+        return ok;
+    }
+
+    private boolean parse_relationdefinition(ParseNode pn) {
+        if (!precheck(pn, "relationdefinition")) {
+            return false;
+        }
+
+        boolean ok = true;
+
+        /* get relation name */
+        String relname = pn.getChild("name").getTerminal();
+        assert relname != null;
+
+        RelationDescriptor rd = new RelationDescriptor(relname);
+
+        /* check if static */
+        boolean bStatic = pn.getChild("static") != null;
+        rd.isStatic(bStatic);
+
+        /* get domain */
+        String domainsetname = pn.getChild("domain").getChild("type").getTerminal();
+        assert domainsetname != null;
+
+        /* get range */
+        String rangesetname = pn.getChild("range").getChild("type").getTerminal();
+        assert rangesetname != null;
+
+        /* get domain multiplicity */
+        String domainmult = pn.getChild("domain").getChild("mult").getTerminal();
+        assert domainmult != null;
+
+        /* get range multiplicity */
+        String rangemult = pn.getChild("range").getChild("mult").getTerminal();
+        assert rangemult != null;
+
+        /* NOTE: it is assumed that the sets have been parsed already so that the 
+           set namespace is fully populated. any missing setdescriptors for the set
+           symbol table will be assumed to be errors and reported. */
+
+        SetDescriptor domainset = lookupSet(domainsetname);
+        if (domainset == null) {
+            er.report(pn, "Undefined set '" + domainsetname + "' referenced in relation '" + relname + "'");
+            ok = false;
+        } else {
+            rd.setDomain(domainset);
+        }
+
+        SetDescriptor rangeset = lookupSet(rangesetname);
+        if (rangeset == null) {
+            er.report(pn, "Undefined set '" + rangesetname + "' referenced in relation '" + relname + "'");
+            ok = false;
+        } else {
+            rd.setRange(rangeset);
+        }
+
+        // #TBD#: eventually we'll use the multiplicities but now we don't... oh well
+
+        /* lets add the relation to the global symbol table */
+        if (!stRelations.contains(relname)) {
+            stRelations.add(rd);
+        } else {
+            er.report(pn, "Redefinition of relation '" + relname + "'");
+            ok = false;
+        }
+
+        return ok;
+    }
+
+    private boolean parse_structures(ParseNode pn) {
+        if (!precheck(pn, "structures")) {
+            return false;
+        }
+        
+        boolean ok = true;
+        ParseNodeVector structures = pn.getChildren("structure");
+
+        for (int i = 0; i < structures.size(); i++) {
+            if (!parse_structure(structures.elementAt(i))) {
+                ok = false;
+            }
+        }
+
+        ParseNodeVector globals = pn.getChildren("global");
+
+        for (int i = 0; i < globals.size(); i++) {
+            if (!parse_global(globals.elementAt(i))) {
+                ok = false;
+            }
+        }
+
+        // ok, all the structures have been parsed, now we gotta type check       
+
+        Enumeration types = stTypes.getDescriptors();
+        while (types.hasMoreElements()) {
+            TypeDescriptor t = (TypeDescriptor) types.nextElement();
+
+            if (t instanceof ReservedTypeDescriptor) {
+                // we don't need to check reserved types
+            } else if (t instanceof StructureTypeDescriptor) {
+                
+                StructureTypeDescriptor type = (StructureTypeDescriptor) t;
+                TypeDescriptor subtype = type.getSubType();
+
+                // check that the subtype is valid
+                if (subtype instanceof MissingTypeDescriptor) {
+                    TypeDescriptor newtype = lookupType(subtype.getSymbol());
+                    if (newtype == null) {
+                        // subtype not defined anywheere
+                        // #TBD#: somehow determine how we can get the original parsenode (global function?)
+                        er.report(null, "Undefined subtype '" + subtype.getSymbol() + "'");
+                        ok = false;
+                    } else {
+                        type.setSubType(newtype);
+                    }
+                }
+
+                Iterator fields = type.getFields();
+
+                while (fields.hasNext()) {
+                    FieldDescriptor field = (FieldDescriptor) fields.next();                        
+                    TypeDescriptor fieldtype = field.getType();
+
+                    assert fieldtype != null;
+
+                    // check that the type is valid
+                    if (fieldtype instanceof MissingTypeDescriptor) {
+                        TypeDescriptor newtype = lookupType(fieldtype.getSymbol());
+                        if (newtype == null) {
+                            // type never defined
+                            // #TBD#: replace new ParseNode with original parsenode
+                            er.report(null, "Undefined type '" + fieldtype.getSymbol() + "'");
+                            ok = false;
+                        } else {
+                            assert newtype != null;
+                            field.setType(newtype);
+                        }
+                    }                        
+                }
+
+                Iterator labels = type.getLabels();
+
+                while (labels.hasNext()) {
+                    LabelDescriptor label = (LabelDescriptor) labels.next();
+                    TypeDescriptor labeltype = label.getType();
+
+                    assert labeltype != null;
+
+                    // check that the type is valid
+                    if (labeltype instanceof MissingTypeDescriptor) {
+                        TypeDescriptor newtype = lookupType(labeltype.getSymbol());
+                        if (newtype == null) {
+                            // type never defined
+                            // #TBD#: replace new ParseNode with original parsenode
+                            er.report(null, "Undefined type '" + labeltype.getSymbol() + "'");
+                            ok = false;
+                        } else {
+                            assert newtype != null;
+                            label.setType(newtype);
+                        }
+                    }
+                }
+                
+            } else {
+                throw new IRException("shouldn't be any other typedescriptor classes");
+            }
+        }
+
+        if (!ok) {
+            return false;
+        }
+
+        types = stTypes.getDescriptors();
+
+        while (types.hasMoreElements()) {
+            TypeDescriptor t = (TypeDescriptor) types.nextElement();
+
+            if (t instanceof ReservedTypeDescriptor) {
+                // we don't need to check reserved types
+            } else if (t instanceof StructureTypeDescriptor) {
+                
+                StructureTypeDescriptor type = (StructureTypeDescriptor)t;
+                TypeDescriptor subtype = type.getSubType();
+                Iterator fields = type.getFields();
+
+                while (fields.hasNext()) {
+                    FieldDescriptor field = (FieldDescriptor) fields.next();                        
+
+                    if (field instanceof ArrayDescriptor) {
+                        ArrayDescriptor ad = (ArrayDescriptor) field;
+                        Expr indexbound = ad.getIndexBound();
+                        TypeDescriptor indextype = indexbound.typecheck(new SemanticAnalyzer() {
+                                public IRErrorReporter getErrorReporter() { return er; }
+                                public SymbolTable getSymbolTable() { return stGlobals; }
+                            });
+
+                        if (indextype == null) {
+                            ok = false;
+                        } else if (indextype != ReservedTypeDescriptor.INT) {
+                            er.report(null, "'" + type.getSymbol() + "." + field.getSymbol() + "' index bounds must be type 'int' not '" + indextype.getSymbol() + "'");
+                            ok = false;
+                        }
+                    }
+                }
+
+                Iterator labels = type.getLabels();
+
+                while (labels.hasNext()) {
+                    LabelDescriptor label = (LabelDescriptor) labels.next();
+                    Expr index = label.getIndex();
+
+                    if (index != null) {
+                        TypeDescriptor indextype = index.typecheck(new SemanticAnalyzer() {
+                                public IRErrorReporter getErrorReporter() { return er; }
+                                public SymbolTable getSymbolTable() { return stGlobals; }
+                            });
+                        
+                        if (indextype != ReservedTypeDescriptor.INT) {
+                            er.report(null, "Label '" + type.getSymbol() + "." + label.getSymbol() + "' index must be type 'int' not '" + indextype.getSymbol() + "'");
+                            ok = false;
+                        }
+                    }
+                }
+                
+            } else {
+                throw new IRException("shouldn't be any other typedescriptor classes");
+            }
+
+        }
+
+        // #TBD#: need to make sure that no cycles exist in any of the declarations or subtypes
+        // subtypes, of course, are not real subtypes, they are merely a way to validate a 
+        // cast, i believe
+
+        return ok;
+    }
+
+    private boolean parse_global(ParseNode pn) {
+        if (!precheck(pn, "global")) {
+            return false;
+        }
+
+        String name = pn.getChild("name").getTerminal();
+        assert name != null;
+
+        String type = pn.getChild("type").getTerminal();
+        assert type != null;
+        TypeDescriptor td = lookupType(type);
+        assert td != null;
+        assert !(td instanceof ReservedTypeDescriptor);
+        
+        if (stGlobals.contains(name)) {
+            /* redefinition of global */
+            er.report(pn, "Redefinition of global '" + name + "'");
+            return false;
+        }
+
+        stGlobals.add(new VarDescriptor(name, name, td));
+        return true;
+    }
+
+    private boolean parse_structure(ParseNode pn) {
+        if (!precheck(pn, "structure")) {
+            return false;
+        }
+
+        boolean ok = true;
+        String typename = pn.getChild("name").getTerminal();
+        StructureTypeDescriptor type = new StructureTypeDescriptor(typename);
+        
+        if (pn.getChild("subtype") != null) {
+            // has a subtype, lets try to resolve it
+            String subtype = pn.getChild("subtype").getTerminal();
+
+            if (subtype.equals(typename)) {
+                // Semantic Error: cyclic inheritance
+                er.report(pn, "Cyclic inheritance prohibited");
+                ok = false;
+            }
+
+            /* lookup the type to get the type descriptor */
+            type.setSubType(lookupType(subtype, CREATE_MISSING));
+        }
+
+        // set the current type so that the recursive parses on the labels
+        // and fields can add themselves automatically to the current type         
+        dCurrentType = type;
+        
+        // parse the labels and fields
+        if (!parse_labelsandfields(pn.getChild("lf"))) {
+            ok = false;
+        }
+
+        if (stTypes.contains(typename)) {
+            er.report(pn, "Redefinition of type '" + typename + "'");
+            ok = false;
+        } else {
+            stTypes.add(type);
+        }
+        
+        return ok;
+    }
+
+    private boolean parse_labelsandfields(ParseNode pn) {
+        if (!precheck(pn, "lf")) {
+            return false;
+        }
+
+        boolean ok = true;
+     
+        // check the fields first (need the field names 
+        // to type check the labels)
+        if (!parse_fields(pn.getChild("fields"))) {
+            ok = false;
+        }
+
+        // check the labels now that all the fields are sorted
+        if (!parse_labels(pn.getChild("labels"))) {
+            ok = false;
+        }
+
+        return ok;
+    }
+
+    private boolean parse_fields(ParseNode pn) {
+        if (!precheck(pn, "fields")) {
+            return false;
+        }
+        
+        boolean ok = true;
+        
+        /* NOTE: because the order of the fields is important when defining a data structure,
+           and because the order is defined by the order of the fields defined in the field
+           vector, its important that the parser returns the fields in the correct order */
+        
+        ParseNodeVector fields = pn.getChildren();
+
+        for (int i = 0; i < fields.size(); i++) {
+            ParseNode field = fields.elementAt(i);            
+            FieldDescriptor fd;
+            boolean reserved;
+            String name = null;
+
+            if (field.getChild("reserved") != null) {
+                // reserved field
+                // #TBD#: it will be necessary for reserved field descriptors to generate
+                // a unique symbol for the type descriptor requires it for its hashtable
+                fd = new ReservedFieldDescriptor();
+                reserved = true;
+            } else {
+                name = field.getChild("name").getTerminal();                
+                fd = new FieldDescriptor(name);
+                reserved = false;
+            }
+
+            String type = field.getChild("type").getTerminal();
+            boolean ptr = field.getChild("*") != null;
+            fd.setPtr(ptr);
+
+            fd.setType(lookupType(type, CREATE_MISSING));
+
+            if (field.getChild("index") != null) {
+                // field is an array, so create an array descriptor to wrap the 
+                // field descriptor and then replace the top level field descriptor with
+                // this array descriptor
+                Expr expr = parse_expr(field.getChild("index").getChild("expr"));
+                if (expr == null) {
+                    // #ATTN#: do we really want to return an exception here?
+                    throw new IRException("invalid index expression");
+                }
+                ArrayDescriptor ad = new ArrayDescriptor(fd, expr);               
+                fd = ad;
+            }
+
+            // add the current field to the current type
+            if (reserved == false) {
+                // lets double check that we are redefining a field
+                if (dCurrentType.getField(name) != null) {
+                    // Semantic Error: field redefinition 
+                    er.report(pn, "Redefinition of field '" + name + "'");
+                    ok = false;
+                } else {
+                    dCurrentType.addField(fd);
+                }
+            } else {
+                dCurrentType.addField(fd);
+            }
+        }
+        
+        return ok;
+    }
+
+    private boolean parse_labels(ParseNode pn) {
+        if (!precheck(pn, "labels")) {
+            return false;
+        }
+
+        boolean ok = true;
+
+        /* NOTE: parse_labels should be called after the fields have been parsed because any
+           labels not found in the field set of the current type will be flagged as errors */
+
+        ParseNodeVector labels = pn.getChildren();
+
+        for (int i = 0; i < labels.size(); i++) {           
+            ParseNode label = labels.elementAt(i);
+            String name = label.getChild("name").getTerminal();
+            LabelDescriptor ld = new LabelDescriptor(name); 
+
+            if (label.getChild("index") != null) {
+                Expr expr = parse_expr(label.getChild("index").getChild("expr"));
+                if (expr == null) {
+                    /* #ATTN#: do we really want to return an exception here? */
+                    throw new IRException("Invalid expression");
+                }
+                ld.setIndex(expr);                
+            } 
+            
+            String type = label.getChild("type").getTerminal();
+
+            ld.setType(lookupType(type, CREATE_MISSING));
+                        
+            String field = label.getChild("field").getTerminal();           
+            FieldDescriptor fd = dCurrentType.getField(field);
+
+            if (fd == null) {
+                /* Semantic Error: Undefined field in label */
+                er.report(label, "Undefined field '" + field + "' in label");
+                ok = false;
+            } else {
+                ld.setField(fd);
+            }
+
+            /* add label to current type */
+            if (dCurrentType.getLabel(name) != null) {
+                /* semantic error: label redefinition */
+                er.report(pn, "Redefinition of label '" + name + "'");
+                ok = false;
+            } else {
+                dCurrentType.addLabel(ld);            
+            }
+        }
+
+        return ok;
+    }
+
+    private Expr parse_expr(ParseNode pn) {
+        if (!precheck(pn, "expr")) {
+            return null;
+        }
+
+        if (pn.getChild("var") != null) {
+            // we've got a variable reference... we'll have to scope check it later
+            // when we are completely done... there are also some issues of cyclic definitions
+            return new VarExpr(pn.getChild("var").getTerminal());
+        } else if (pn.getChild("literal") != null) {
+            return parse_literal(pn.getChild("literal"));
+        } else if (pn.getChild("operator") != null) {
+            return parse_operator(pn.getChild("operator"));
+        } else if (pn.getChild("relation") != null) {
+            return parse_relation(pn.getChild("relation"));
+        } else if (pn.getChild("sizeof") != null) {
+            return parse_sizeof(pn.getChild("sizeof"));
+        } else if (pn.getChild("simple_expr") != null) {
+            return parse_simple_expr(pn.getChild("simple_expr"));        
+        } else if (pn.getChild("elementof") != null) {
+            return parse_elementof(pn.getChild("elementof"));        
+        } else if (pn.getChild("tupleof") != null) {
+            return parse_tupleof(pn.getChild("tupleof"));        
+        } else if (pn.getChild("isvalid") != null) {
+            er.report(pn, "Operation 'isvalid' is currently unsupported.");
+            return null;
+        } else {
+            er.report(pn, "Unknown or invalid expression type '" + pn.getTerminal() + "'");
+            return null;
+        }            
+    }
+
+    private Expr parse_elementof(ParseNode pn) {
+        if (!precheck(pn, "elementof")) {
+            return null;
+        }
+
+        /* get setname */
+        String setname = pn.getChild("name").getTerminal();
+        assert setname != null;
+        SetDescriptor sd = lookupSet(setname);
+
+        if (sd == null) {
+            er.report(pn, "Undefined set '" + setname + "'");
+            return null;
+        }
+
+        /* get left side expr */
+        Expr expr = parse_expr(pn.getChild("expr"));
+        
+        if (expr == null) {
+            return null;
+        }
+
+        return new ElementOfExpr(expr, sd);
+    }
+
+    private Expr parse_tupleof(ParseNode pn) {
+        if (!precheck(pn, "tupleof")) {
+            return null;
+        }
+        
+        /* get relation */
+        String relname = pn.getChild("name").getTerminal();
+        assert relname != null;
+        RelationDescriptor rd = lookupRelation(relname);
+
+        if (rd == null) {
+            er.report(pn, "Undefined relation '" + relname + "'");
+            return null;
+        }
+
+        Expr left = parse_expr(pn.getChild("left").getChild("expr"));
+        Expr right = parse_expr(pn.getChild("right").getChild("expr"));
+
+        if ((left == null) || (right == null)) {
+            return null;
+        }
+
+        return new TupleOfExpr(left, right, rd);
+    }
+
+    private Expr parse_simple_expr(ParseNode pn) {
+        if (!precheck(pn, "simple_expr")) {
+            return null;
+        }
+
+        // only locations so far
+        return parse_location(pn.getChild("location"));
+    }
+
+    private Expr parse_location(ParseNode pn) {
+        if (!precheck(pn, "location")) {
+            return null;
+        }
+
+        if (pn.getChild("var") != null) {
+            // should be changed into a namespace check */
+            return new VarExpr(pn.getChild("var").getTerminal());
+        } else if (pn.getChild("cast") != null) {
+            return parse_cast(pn.getChild("cast"));
+        } else if (pn.getChild("dot") != null) {
+            return parse_dot(pn.getChild("dot"));
+        } else {
+            throw new IRException();
+        }
+    }
+
+    private RelationExpr parse_relation(ParseNode pn) {
+        if (!precheck(pn, "relation")) {
+            return null;
+        }
+
+        RelationExpr re = new RelationExpr();
+
+        /* get quantitifer var */
+        VarDescriptor vd = parse_quantifiervar(pn.getChild("quantifiervar"));
+        
+        if (vd == null) {
+            return null;
+        }
+
+        // #TBD#: bad name
+        re.setDomain(vd);
+
+        /* grab list of relations */
+        ParseNodeVector relations = pn.getChild("relations").getChildren();
+        assert relations.size() >= 1;
+        
+        // #TBD#: verify that the relations are in the correct order and that the 
+        // first relation is getting the correct "inv" assigned from "expr"
+
+        /* lets verify that these relations are defined */
+        for (int i = 0; i < relations.size(); i++) {           
+            ParseNode rn = relations.elementAt(i);
+            String relname = rn.getLabel();
+            boolean inverse = rn.getChild("inv") != null;
+            
+            RelationDescriptor relation = lookupRelation(relname);
+            
+            if (relation == null) {
+                /* Semantic Error: relation not definied" */
+                er.report(rn, "Undefined relation '" + relname + "'");
+                return null;
+            }                       
+
+            re.setRelation(relation, inverse);
+            
+            /* if we are not at end of list then create new relation and 
+               replace it to chain the relations */
+            if (i + 1 < relations.size()) {
+                re = new RelationExpr(re);  // should create relation with domain as older 're'
+            } 
+        }
+
+        return re;                  
+    }
+
+    private SizeofExpr parse_sizeof(ParseNode pn) {
+        if (!precheck(pn, "sizeof")) {
+            return null;
+        }
+
+        /* get setexpr */
+        SetExpr setexpr = parse_setexpr(pn.getChild("setexpr"));
+        
+        if (setexpr == null) {
+            return null;
+        }
+
+        return new SizeofExpr(setexpr);
+    }
+
+    private CastExpr parse_cast(ParseNode pn) {
+        if (!precheck(pn, "cast")) {
+            return null;
+        }
+
+        /* get type */
+        String typename = pn.getChild("type").getTerminal();
+        assert typename != null;
+        TypeDescriptor type = lookupType(typename);
+
+        if (type == null) {
+            /* semantic error: undefined type in cast */
+            er.report(pn, "Undefined type '" + typename + "' in cast operator");
+            return null;
+        } 
+
+        /* get expr */
+        Expr expr = parse_simple_expr(pn.getChild("simple_expr"));
+        
+        if (expr == null) {
+            return null;
+        } 
+
+        return new CastExpr(type, expr);
+    }
+
+    private SetExpr parse_setexpr(ParseNode pn) {
+        if (!precheck(pn, "setexpr")) {
+            return null;
+        }
+
+        // #TBD#: setexpr and parse_relation seem to be cousins... is there a reduction/refactor possible?
+
+        if (pn.getChild("set") != null) {
+            String setname = pn.getChild("set").getTerminal();
+            assert setname != null;
+            SetDescriptor sd = lookupSet(setname);
+
+            if (sd == null) {
+                er.report(pn, "Unknown or undefined set '" + setname + "'");             
+                return null;
+            } else {                         
+                return new SetExpr(sd);
+            }
+        } else if (pn.getChild("dot") != null) {
+            VarDescriptor vd = parse_quantifiervar(pn.getChild("dot").getChild("quantifiervar"));
+            RelationDescriptor relation = lookupRelation(pn.getChild("dot").getChild("relation").getTerminal());
+            return new ImageSetExpr(vd, relation);
+        } else if (pn.getChild("dotinv") != null) {
+            VarDescriptor vd = parse_quantifiervar(pn.getChild("dotinv").getChild("quantifiervar"));
+            RelationDescriptor relation = lookupRelation(pn.getChild("dotinv").getChild("relation").getTerminal());
+            return new ImageSetExpr(ImageSetExpr.INVERSE, vd, relation);
+        } else {
+            throw new IRException();
+        }
+    }
+
+    private VarDescriptor parse_quantifiervar(ParseNode pn) {
+        if (!precheck(pn, "quantifiervar")) {
+            return null;
+        }
+
+        /* get var */
+        String varname = pn.getTerminal();
+        assert varname != null;
+        
+        /* NOTE: quantifier var's are only found in the constraints and
+           model definitions... therefore we can do a semantic check here 
+           to make sure that the variables exist in the symbol table */
+
+        /* NOTE: its assumed that the symbol table stack is appropriately
+           set up with the parent quantifier symbol table */
+        assert !sts.empty();          
+
+        /* do semantic check and if valid, add it to symbol table
+           and add it to the quantifier as well */
+        if (sts.peek().contains(varname)) {
+            return new VarDescriptor(varname);
+        } else {
+            /* Semantic Error: undefined variable */
+            er.report(pn, "Undefined variable '" + varname + "'");
+            return null;
+        }
+    }
+    
+    private LiteralExpr parse_literal(ParseNode pn) {
+        if (!precheck(pn, "literal")) {
+            return null;
+        }
+
+        if (pn.getChild("boolean") != null) {
+            if (pn.getChild("boolean").getChild("true") != null) {
+                return new BooleanLiteralExpr(true);
+            } else {
+                return new BooleanLiteralExpr(false);
+            } 
+        } else if (pn.getChild("decimal") != null) {            
+            String integer = pn.getChild("decimal").getTerminal();
+
+            /* Check for integer literal overflow */
+            BigInteger intLitBI = new BigInteger(integer);
+            BigInteger intMax = new BigInteger("" + Integer.MAX_VALUE);
+            BigInteger intMin = new BigInteger("" + Integer.MIN_VALUE);
+            int value;
+
+            if (intLitBI.compareTo(intMin) < 0) {
+                value = Integer.MIN_VALUE;
+                er.warn(pn, "Integer literal overflow");
+            } else if (intLitBI.compareTo(intMax) > 0) {
+                value = Integer.MAX_VALUE;
+                er.warn(pn, "Integer literal overflow");
+            } else {
+                /* no truncation needed */
+                value = Integer.parseInt(integer);
+            }
+
+            return new IntegerLiteralExpr(value);
+        } else if (pn.getChild("token") != null) {
+            return new TokenLiteralExpr(pn.getChild("token").getTerminal());
+        } else if (pn.getChild("string") != null) {
+            throw new IRException("string unsupported");
+        } else if (pn.getChild("char") != null) {
+            throw new IRException("char unsupported");
+        } else {
+            throw new IRException("unknown literal expression type.");
+        }
+    }
+
+    private OpExpr parse_operator(ParseNode pn) {
+        if (!precheck(pn, "operator")) {
+            return null; 
+        }
+
+        String opname = pn.getChild("op").getTerminal();
+
+        Opcode opcode;
+
+        if (opname.equals("add")) {
+            opcode = Opcode.ADD;
+        } else if (opname.equals("sub")) {
+            opcode = Opcode.SUB;
+        } else if (opname.equals("mult")) {
+            opcode = Opcode.MULT;
+        } else if (opname.equals("div")) {
+            opcode = Opcode.DIV;
+        } else if (opname.equals("and")) {
+            opcode = Opcode.AND;
+        } else if (opname.equals("or")) {
+            opcode = Opcode.OR;
+        } else if (opname.equals("not")) {
+            opcode = Opcode.NOT;
+        } else if (opname.equals("gt")) {
+            opcode = Opcode.GT;
+        } else if (opname.equals("ge")) {
+            opcode = Opcode.GE;
+        } else if (opname.equals("lt")) {
+            opcode = Opcode.LT;
+        } else if (opname.equals("le")) {
+            opcode = Opcode.LE;
+        } else if (opname.equals("eq")) {
+            opcode = Opcode.EQ;
+        } else if (opname.equals("ne")) {
+            opcode = Opcode.NE;
+        } else {
+            er.report(pn, "Unsupported operation: " + opname);
+            return null;
+        }
+        
+        Expr left = parse_expr(pn.getChild("left").getChild("expr"));
+        Expr right = null;
+        
+        if (pn.getChild("right") != null) {
+            right = parse_expr(pn.getChild("right").getChild("expr"));
+        }
+
+        if (left == null) {           
+            return null;
+        }
+
+        if (right == null && opcode != Opcode.NOT) {
+            er.report(pn, "Two arguments required.");
+            return null;
+        }
+
+        return new OpExpr(opcode, left, right);
+    }
+
+    private DotExpr parse_dot(ParseNode pn) {
+        if (!precheck(pn, "dot")) {
+            return null;
+        }
+
+        Expr left = parse_simple_expr(pn.getChild("simple_expr"));
+
+        if (left == null) {
+            return null;
+        }
+
+        String field = pn.getChild("field").getTerminal();
+
+        Expr index = null;
+
+        if (pn.getChild("index") != null) {
+            index = parse_expr(pn.getChild("index").getChild("expr"));
+            
+            if (index == null) {
+                return null;
+            }
+        }
+
+        return new DotExpr(left, field, index);        
+    }
+
+}
+
diff --git a/Repair/RepairCompiler/MCC/IR/SetDescriptor.java b/Repair/RepairCompiler/MCC/IR/SetDescriptor.java
new file mode 100755 (executable)
index 0000000..6bd62ed
--- /dev/null
@@ -0,0 +1,93 @@
+/**
+ * SetDescriptor
+ *
+ * represents a set in the model space
+ */
+
+package MCC.IR;
+import java.util.*;
+
+public class SetDescriptor extends Descriptor {
+    
+    TypeDescriptor type;
+    boolean partition;
+    Vector subsets;       
+
+    public SetDescriptor(String name) {
+        super(name);
+        subsets = new Vector();
+        partition = false;
+    }
+
+    public static Set expand(Set descriptors) {
+        HashSet expanded = new HashSet();
+        Iterator d = descriptors.iterator();
+        
+        while (d.hasNext()) {
+            Descriptor descriptor = (Descriptor) d.next();
+            
+            if (descriptor instanceof SetDescriptor) {
+                expanded.addAll(((SetDescriptor) descriptor).allSubsets());
+            }
+        }
+
+        expanded.addAll(descriptors);
+        return expanded;        
+    }
+
+    public boolean isPartition() {
+        return partition;
+    }
+    
+    public void isPartition(boolean newvalue) {
+        partition = newvalue;
+    }
+
+    public void setType(TypeDescriptor td) {
+        type = td;
+    }
+
+    public TypeDescriptor getType() {
+        return type;
+    }
+
+    public void addSubset(SetDescriptor sd) {
+        subsets.addElement(sd);
+    }
+
+    public Vector getSubsets() {
+        return subsets;
+    }
+
+    public Iterator subsets() {
+        return subsets.iterator();
+    }
+
+    public boolean isSubset(SetDescriptor sd) {
+        if (sd == this) {
+            return true;
+        }
+        for (int i = 0; i < subsets.size(); i++) {
+            SetDescriptor subset = (SetDescriptor) subsets.elementAt(i);
+            if (subset.isSubset(sd)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public Set allSubsets() {
+        Set v = new HashSet();
+        v.add(this);
+
+        for (int i = 0; i < subsets.size(); i++) {
+            SetDescriptor subset = (SetDescriptor) subsets.elementAt(i);
+            v.addAll(subset.allSubsets());
+        }
+        
+        return v;
+    }        
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/SetExpr.java b/Repair/RepairCompiler/MCC/IR/SetExpr.java
new file mode 100755 (executable)
index 0000000..deb9a1b
--- /dev/null
@@ -0,0 +1,40 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class SetExpr extends Expr {
+
+    SetDescriptor sd;
+
+    public SetExpr(SetDescriptor sd) {
+        this.sd = sd;
+    }
+    
+    public SetExpr() {
+        this.sd = null;
+    }
+
+    public Set getRequiredDescriptors() {
+        HashSet v = new HashSet();
+        v.add(sd);
+        return v;
+    }
+
+    public void generate(CodeWriter writer, VarDescriptor vd) {
+        throw new IRException("unsupported");
+    }
+
+    public void generate_set(CodeWriter writer, VarDescriptor vd) {
+        writer.outputline("Set " + vd.getSafeSymbol() + " = " + sd.getSafeSymbol() + "_hash;");
+    }    
+
+    public void prettyPrint(PrettyPrinter pp) {
+        pp.output(sd.getSafeSymbol());
+    }
+
+    public TypeDescriptor typecheck(SemanticAnalyzer sa) {
+        this.td = sd.getType();
+        return this.td;
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/SetInclusion.java b/Repair/RepairCompiler/MCC/IR/SetInclusion.java
new file mode 100755 (executable)
index 0000000..deb6ea5
--- /dev/null
@@ -0,0 +1,49 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class SetInclusion extends Inclusion {
+    
+    Expr elementexpr;
+    SetDescriptor set;
+
+    public SetInclusion(Expr elementexpr, SetDescriptor set) {
+        this.elementexpr = elementexpr;
+        this.set = set;
+    }
+
+    public Set getTargetDescriptors() {
+        HashSet v = new HashSet();
+        v.add(set);
+        return v;
+    }
+
+    public Set getRequiredDescriptors() {
+        return elementexpr.getRequiredDescriptors();
+    }
+
+    public void generate(CodeWriter writer) {
+        VarDescriptor vd = VarDescriptor.makeNew("element");
+        elementexpr.generate(writer, vd);
+        writer.outputline(set.getSafeSymbol() + "_hash->add((int)" + vd.getSafeSymbol() +  ", (int)" + vd.getSafeSymbol() + ");");
+        //writer.outputline("printf(\"" + set.getSafeSymbol() + " (add): %d\\n\", " + vd.getSafeSymbol() + ");");
+    }
+
+    public boolean typecheck(SemanticAnalyzer sa) {
+        TypeDescriptor td = elementexpr.typecheck(sa);
+        
+        if (td == null) {
+            return false;
+        }
+
+        TypeDescriptor settype = set.getType();
+
+        if (!td.equals(settype)) {
+            sa.getErrorReporter().report(null, "Type mismatch: attempting to test for types '" + td.getSymbol() + "' in set of type '" + settype.getSymbol() + "'");
+            return false;
+        }
+        
+        return true;
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/SetQuantifier.java b/Repair/RepairCompiler/MCC/IR/SetQuantifier.java
new file mode 100755 (executable)
index 0000000..8ef4804
--- /dev/null
@@ -0,0 +1,42 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class SetQuantifier extends Quantifier {
+
+    VarDescriptor var;
+    SetDescriptor set;
+
+    public SetQuantifier() {
+        this.var = null;
+    }
+
+    public void setVar(VarDescriptor vd) {
+        this.var = vd;
+    }
+
+    public void setSet(SetDescriptor sd) {
+        this.set = sd;
+    }
+
+    public Set getRequiredDescriptors() {
+        HashSet v = new HashSet();
+        v.add(set);
+        return v;
+    }
+
+    public SetDescriptor getSet() {
+        return set;
+    }
+
+    public String toString() {
+        return "set quantifier " + var.getSymbol() + " in " + set.getSymbol();
+    }
+
+    public void generate_open(CodeWriter writer) {
+        writer.outputline("for (SimpleIterator* " + var.getSafeSymbol() + "_iterator = " + set.getSafeSymbol() + "_hash->iterator(); " + var.getSafeSymbol() + "_iterator->hasNext(); ) {");
+        writer.indent();
+        writer.outputline(var.getType().getGenerateType() + " " + var.getSafeSymbol() + " = (" + var.getType().getGenerateType() + ") " + var.getSafeSymbol() + "_iterator->next();");
+    }
+  
+}
diff --git a/Repair/RepairCompiler/MCC/IR/SimpleIRErrorReporter.java b/Repair/RepairCompiler/MCC/IR/SimpleIRErrorReporter.java
new file mode 100755 (executable)
index 0000000..3c64101
--- /dev/null
@@ -0,0 +1,93 @@
+package MCC.IR;
+
+import java.util.Vector;
+
+public class SimpleIRErrorReporter implements IRErrorReporter {
+    
+    public boolean error;
+
+    String filename;
+    Vector messages;
+    
+
+    public SimpleIRErrorReporter () {
+       messages = new Vector();
+       error = false;
+        filename = null;
+    }
+
+    public void setFilename(String filename) {
+        this.filename = new String(filename + ":");
+    } 
+
+    public void report(ParseNode v, String s) {
+
+       LinedMessage sem = new LinedMessage();
+       sem.error = true;
+       sem.pn = v;
+       sem.message = s;
+
+       add(sem);
+       
+       error = true;
+    }
+
+    public void warn(ParseNode v, String s) {
+       
+       LinedMessage sem = new LinedMessage();
+       sem.error = false;
+       sem.pn = v;
+       sem.message = s;
+       
+       add(sem);
+    }
+
+    private void add(LinedMessage sem) {
+
+       if (sem.pn == null) {
+           messages.addElement(sem);
+           return;
+       }
+
+       int i;
+       for (i = 0; i < messages.size(); i++) {
+
+           LinedMessage cur = (LinedMessage)messages.elementAt(i);
+
+           if (cur.pn.getLine() > sem.pn.getLine()) {
+               break;
+           }
+       }
+
+       messages.insertElementAt(sem, i);
+    }
+
+    public String toString() {
+       String output = new String();
+
+       for (int i = 0; i < messages.size(); i++) {
+           LinedMessage sem = (LinedMessage)messages.elementAt(i);
+           if (sem.error) {
+               output += "error";
+           } else {
+               output += "warning";
+           }
+
+           if (sem.pn != null) {
+               output += " (" + filename + sem.pn.getLine() + "): ";
+           } else {
+                output += " : ";
+            }
+
+           output += sem.message;
+           output += "\n";
+       }
+       return output;
+    }
+}
+
+class LinedMessage {
+    boolean error;
+    public ParseNode pn;
+    public String message;
+}
diff --git a/Repair/RepairCompiler/MCC/IR/SizeofExpr.java b/Repair/RepairCompiler/MCC/IR/SizeofExpr.java
new file mode 100755 (executable)
index 0000000..691b135
--- /dev/null
@@ -0,0 +1,39 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class SizeofExpr extends Expr {
+
+    SetExpr setexpr;
+
+    public SizeofExpr(SetExpr setexpr) {
+        if (setexpr == null) {
+            throw new NullPointerException();
+        }
+
+        this.setexpr = setexpr;
+    }
+
+    public Set getRequiredDescriptors() {
+        return setexpr.getRequiredDescriptors();
+    }
+
+    public void generate(CodeWriter writer, VarDescriptor dest) {
+        VarDescriptor sd = VarDescriptor.makeNew();
+        setexpr.generate_set(writer, sd);
+        writer.outputline("int " + dest.getSafeSymbol() + " = " + sd.getSafeSymbol() + ".size();");
+    }
+
+    public void prettyPrint(PrettyPrinter pp) {
+        pp.output("sizeof(");
+        setexpr.prettyPrint(pp);
+        pp.output(")");
+    }
+
+    public TypeDescriptor typecheck(SemanticAnalyzer sa) {
+        this.td = ReservedTypeDescriptor.INT;
+        return this.td;        
+    }
+
+        
+}
diff --git a/Repair/RepairCompiler/MCC/IR/StructureTypeDescriptor.java b/Repair/RepairCompiler/MCC/IR/StructureTypeDescriptor.java
new file mode 100755 (executable)
index 0000000..a9fd29c
--- /dev/null
@@ -0,0 +1,141 @@
+package MCC.IR;
+
+/**
+ * StructureTypeDescriptor
+ *
+ * represents structure types
+ */
+
+import java.util.*;
+
+public class StructureTypeDescriptor extends TypeDescriptor {
+
+    TypeDescriptor subtype;
+
+    Hashtable fields = new Hashtable(); /* fast lookups */
+    Vector fieldlist = new Vector(); /* ordering information */
+    Hashtable labels = new Hashtable();
+
+    public StructureTypeDescriptor(String name) {
+        super(name);
+    }
+
+    public TypeDescriptor getGenerateType() {
+        return ReservedTypeDescriptor.INT;
+    }
+
+    public Enumeration getFieldKeys() {
+        return fields.keys();
+    }
+   
+    private Vector getFieldSizes() {
+        Vector fieldsizes = new Vector();
+                
+        for (int i = 0; i < fieldlist.size(); i++) {
+            FieldDescriptor fd = (FieldDescriptor) fieldlist.elementAt(i);
+            TypeDescriptor td = fd.getType();
+            boolean ptr = fd.getPtr();
+
+            Expr basesize; 
+            if (ptr) { /* ptrs are 32bits */
+                basesize = new IntegerLiteralExpr(32);
+            } else {
+                basesize = td.getSizeExpr();
+            }
+
+            if (fd instanceof ArrayDescriptor) {
+                Expr totalsize = new OpExpr(Opcode.MULT, basesize, ((ArrayDescriptor) fd).getIndexBound());
+                fieldsizes.addElement(totalsize);
+            } else {
+                fieldsizes.addElement(basesize);
+            }
+        }
+
+        return fieldsizes;
+    }
+    
+    public Expr getSizeExpr() {        
+        Vector fieldsizes = getFieldSizes();
+
+        /* we've got the field sizes! now return the addition! */
+        Expr size = new IntegerLiteralExpr(0);
+        
+        for (int i = 0; i < fieldsizes.size(); i++) {
+            Expr fieldsize = (Expr) fieldsizes.elementAt(i);
+            size = new OpExpr(Opcode.ADD, fieldsize, size);
+        }
+        
+        return size;
+    }
+
+    public Expr getOffsetExpr(FieldDescriptor field) {
+        Vector fieldsizes = getFieldSizes();
+
+        // #ATTN#: getOffsetExpr needs to be called with the fielddescriptor obect that is in teh vector list
+        // this means that if the field is an arraydescriptor you have to call getOffsetExpr with the array 
+
+        /* we've got the field sizes! now return the addition! */
+        Expr size = new IntegerLiteralExpr(0);
+        
+        for (int i = 0; i < fieldsizes.size(); i++) {
+            FieldDescriptor fd = (FieldDescriptor)fieldlist.elementAt(i);
+
+            if (fd == field) { /* stop, reached target field */
+                break; 
+            }
+
+            Expr fieldsize = (Expr) fieldsizes.elementAt(i);
+            size = new OpExpr(Opcode.ADD, fieldsize, size);
+        }
+        
+        return size;        
+    }
+
+    public Iterator getFields() {
+        return fields.values().iterator();
+    }
+
+    public Iterator getLabels() {
+        return labels.values().iterator();
+    }
+
+    public FieldDescriptor getField(String name) {
+        return (FieldDescriptor) fields.get(name);       
+    }
+
+    public LabelDescriptor getLabel(String name) {
+        return (LabelDescriptor) labels.get(name);
+    }
+
+    public void addField(FieldDescriptor fd) {
+        if (getField(fd.getSymbol()) != null) {
+            throw new IRException("Can not overwrite a field once it has been added.");
+        }        
+        fields.put(fd.getSymbol(), fd);
+        fieldlist.addElement(fd);
+    }
+
+    public void addLabel(LabelDescriptor ld) {
+        if (getLabel(ld.getSymbol()) != null) {
+            throw new IRException("Can not overwrite a label once it has been added.");
+        }
+        labels.put(ld.getSymbol(), ld);
+    }
+
+    public TypeDescriptor getSubType() {
+        return subtype;
+    }
+
+    public void setSubType(TypeDescriptor td) {
+        subtype = td;
+    }
+
+    public boolean isSubtypeOf(TypeDescriptor td) {
+        if (td == this) {
+            return true;
+        } else {
+            return subtype.isSubtypeOf(td);
+        }
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/SymbolTable.java b/Repair/RepairCompiler/MCC/IR/SymbolTable.java
new file mode 100755 (executable)
index 0000000..8bb1c46
--- /dev/null
@@ -0,0 +1,140 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class SymbolTable {
+
+    private Hashtable table;
+    private SymbolTable parent;
+  
+    public SymbolTable() {
+       table = new Hashtable();
+       this.parent = null;
+    }
+
+    public SymbolTable(SymbolTable parent) {
+       table = new Hashtable();
+       this.parent = parent;
+    }
+
+    //public void add(String name, Descriptor d) {
+       //table.put(name, d);
+    //}
+
+    public void add(Descriptor d) {
+       table.put(d.getSymbol(), d);
+    }
+    
+    public void add(String name, Descriptor d) {
+       table.put(name, d);
+       
+    }
+
+    public void dump() {
+       Enumeration e = getDescriptors();
+       while (e.hasMoreElements()) {
+           Descriptor d = (Descriptor) e.nextElement();
+           System.out.println(d.getSymbol());
+       }
+       if (parent != null) {
+           System.out.println("parent:");
+           parent.dump();
+       }
+    }
+    
+    public Descriptor get(String name) {
+       Descriptor d = (Descriptor) table.get(name);
+       if (d == null && parent != null) {
+           return parent.get(name);
+       } else {
+           return d;
+       }
+    }
+
+    public Descriptor getFromSameScope(String name) {
+       return (Descriptor)table.get(name);
+    }
+    
+    public Enumeration getNames() {
+       return table.keys();
+    }
+
+    public Enumeration getDescriptors() {
+       return table.elements();
+    }
+
+    public Iterator descriptors() {
+        return table.values().iterator();
+    }
+
+    public Vector getAllDescriptors() {
+       Vector d;
+       if (parent == null) {
+           d = new Vector();
+       } else {
+           d = parent.getAllDescriptors();
+       }
+
+       Enumeration e = getDescriptors();
+       while(e.hasMoreElements()) {
+           d.addElement(e.nextElement());
+       }
+
+       return d;
+    }
+
+    public boolean contains(String name) {
+        return (get(name) != null);
+    }
+           
+       
+    public int size() {
+       return table.size();
+    }
+
+    public int sizeAll() {
+       if (parent != null) {
+           return parent.sizeAll() + table.size();
+       } else {
+           return table.size();
+       }
+    }
+
+    public SymbolTable getParent() {
+       return parent;
+    }
+    
+    public void setParent(SymbolTable parent) {
+       this.parent = parent;
+    }
+
+    /**
+     * Adds contents of st2.table to this.table and returns a
+     * Vector of shared names, unless there are no shared names,
+     * in which case returns null.
+     */
+    public Vector merge(SymbolTable st2) {
+        Vector v = new Vector();
+        Enumeration names = st2.table.keys();
+
+        while (names.hasMoreElements()) {
+            Object o = names.nextElement();
+
+            if (table.containsKey(o)) {
+                v.addElement(o);
+            } else {
+                table.put(o, st2.table.get(o));
+            }
+        }
+
+        if (v.size() == 0) {
+            return null;
+        } else {
+            return v;
+        }
+    }
+
+    public String toString() {
+        return "ST: " + table.toString();               
+    }
+}
diff --git a/Repair/RepairCompiler/MCC/IR/SymbolTableStack.java b/Repair/RepairCompiler/MCC/IR/SymbolTableStack.java
new file mode 100755 (executable)
index 0000000..06d2ab7
--- /dev/null
@@ -0,0 +1,43 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class SymbolTableStack {
+
+    SymbolTable st;
+
+    SymbolTableStack() {
+       st = null;
+    }
+
+    SymbolTableStack(SymbolTable st) {
+       this.st = st;
+    }
+
+    boolean empty() {
+        return st == null;
+    }
+
+    SymbolTable peek() {
+       return st;
+    }
+
+    SymbolTable pop() {
+       if (st == null) {
+           throw new IRException("SymbolTableStack: tried to pop empty stack.");
+        }
+
+       SymbolTable lastst = st;
+       st = st.getParent();
+       return lastst;
+    }
+
+    // Link and push.
+    void push(SymbolTable st) {
+        if (st != null) {
+            st.setParent(this.st);
+        }
+
+       this.st = st;
+    }
+}
diff --git a/Repair/RepairCompiler/MCC/IR/TokenLiteralExpr.java b/Repair/RepairCompiler/MCC/IR/TokenLiteralExpr.java
new file mode 100755 (executable)
index 0000000..7754240
--- /dev/null
@@ -0,0 +1,42 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class TokenLiteralExpr extends LiteralExpr {
+
+    String token;
+    Integer num;
+
+    static int count = 100;
+    static Hashtable tokens = new Hashtable(); 
+
+    public TokenLiteralExpr(String token) {               
+        this.token = token;
+        td = ReservedTypeDescriptor.INT;
+        
+        if (tokens.contains(token)) {
+            num = (Integer) tokens.get(token);
+        } else {
+            num = new Integer(count++);
+            tokens.put(token, num);
+        }           
+    }
+
+    public String getValue() {
+        return token;
+    }
+
+    public void generate(CodeWriter writer, VarDescriptor dest) {
+        writer.outputline("int " + dest.getSafeSymbol() + " = " + num.toString().toString() + ";");
+    }
+    
+    public void prettyPrint(PrettyPrinter pp) {
+        pp.output("{" + token + " = " + num + "}"); 
+    }
+
+    public TypeDescriptor typecheck(SemanticAnalyzer sa) {
+        td = ReservedTypeDescriptor.INT;
+        return td;
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/TokenSetDescriptor.java b/Repair/RepairCompiler/MCC/IR/TokenSetDescriptor.java
new file mode 100755 (executable)
index 0000000..65070b2
--- /dev/null
@@ -0,0 +1,26 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class TokenSetDescriptor extends SetDescriptor {
+    
+    private static int count = 0;
+    Vector literals = new Vector();
+    
+    public TokenSetDescriptor() {
+        super("toketsetdescriptor" + count++);
+    }
+    
+    public void addLiteral(LiteralExpr lit) {
+        literals.addElement(lit);
+    }
+
+    public TypeDescriptor getType() {
+        return ReservedTypeDescriptor.INT;
+    }
+
+    public void setType(TypeDescriptor td) {
+        throw new IRException("invalid");
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/TupleOfExpr.java b/Repair/RepairCompiler/MCC/IR/TupleOfExpr.java
new file mode 100755 (executable)
index 0000000..c3fa76e
--- /dev/null
@@ -0,0 +1,77 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class TupleOfExpr extends Expr {
+
+    Expr left = null;
+    Expr right = null;
+    RelationDescriptor relation = null;
+
+    public TupleOfExpr(Expr left, Expr right, RelationDescriptor relation) {
+        if ((left == null) || (right == null) || (relation == null)) {
+            throw new NullPointerException();
+        }
+        
+        this.left = left;
+        this.right = right;
+        this.relation = relation;
+    }
+
+    public Set getRequiredDescriptors() {
+        Set v = left.getRequiredDescriptors();
+        v.addAll(right.getRequiredDescriptors());
+        v.add(relation);
+        return v;
+    }
+
+    public void generate(CodeWriter writer, VarDescriptor dest) {
+        VarDescriptor ld = VarDescriptor.makeNew();
+        left.generate(writer, ld);
+
+        VarDescriptor rd = VarDescriptor.makeNew();
+        right.generate(writer, rd);
+
+        writer.outputline("int " + dest.getSafeSymbol() + " = " + 
+                          relation.getSafeSymbol() + "_hash->get(" + ld.getSafeSymbol() + 
+                          ") == " + rd.getSafeSymbol() + ";");
+    }
+
+    public void prettyPrint(PrettyPrinter pp) {
+        pp.output("<");
+        left.prettyPrint(pp);
+        pp.output(", ");
+        right.prettyPrint(pp);
+        pp.output("> in? " + relation.getSafeSymbol());
+    }
+
+    public TypeDescriptor typecheck(SemanticAnalyzer sa) {
+        TypeDescriptor ld = left.typecheck(sa);
+        TypeDescriptor rd = right.typecheck(sa);
+        
+        if (ld == null || rd == null) {
+            return null;
+        }
+
+        boolean ok = true;
+
+        if (ld != relation.getDomain().getType()) {
+            sa.getErrorReporter().report(null, "Type of left element '" + ld.getSymbol() + "' must match domain type '" + relation.getDomain().getType().getSymbol() + "'");
+            ok = false;
+        }
+
+        if (rd != relation.getRange().getType()) {
+            sa.getErrorReporter().report(null, "Type of right element '" + rd.getSymbol() + "' must match range type '" + relation.getRange().getType().getSymbol() + "'");
+            ok = false;
+        }
+
+        if (!ok) {
+            return null;
+        }
+
+        this.td = ReservedTypeDescriptor.INT;
+        return this.td;
+    }
+
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/TypeDescriptor.java b/Repair/RepairCompiler/MCC/IR/TypeDescriptor.java
new file mode 100755 (executable)
index 0000000..5392f1b
--- /dev/null
@@ -0,0 +1,25 @@
+package MCC.IR;
+
+/**
+ * TypeDescriptor 
+ *
+ * represents types in the language (bit, short, etc. as well as structures)
+ */
+
+public abstract class TypeDescriptor extends Descriptor {
+
+    public TypeDescriptor(String name) {
+        super(name);
+    }
+
+    public boolean isSubtypeOf(TypeDescriptor td) {
+        return false;
+    }
+
+    public TypeDescriptor getGenerateType() {
+        return this;
+    }
+
+    public abstract Expr getSizeExpr();
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/VarDescriptor.java b/Repair/RepairCompiler/MCC/IR/VarDescriptor.java
new file mode 100755 (executable)
index 0000000..6fca9ce
--- /dev/null
@@ -0,0 +1,39 @@
+package MCC.IR;
+
+public class VarDescriptor extends Descriptor {
+    
+    private static int count = 0;
+
+    TypeDescriptor td = null;
+
+    public VarDescriptor(String name) {
+        super(name);
+    }
+
+    public VarDescriptor(String name, TypeDescriptor td) {
+        super(name);
+        this.td = td;
+    }
+
+    public VarDescriptor(String name, String safename, TypeDescriptor td) {
+        super(name, safename);
+        this.td = td;
+    }
+
+    public void setType(TypeDescriptor td) {
+        this.td = td;
+    }
+
+    public TypeDescriptor getType() {
+        return td;
+    }
+
+    public static VarDescriptor makeNew() {
+        return makeNew("tempvar");
+    }
+
+    public static VarDescriptor makeNew(String name) {
+        return new VarDescriptor(name + count++);
+    }
+
+}
diff --git a/Repair/RepairCompiler/MCC/IR/VarExpr.java b/Repair/RepairCompiler/MCC/IR/VarExpr.java
new file mode 100755 (executable)
index 0000000..64587da
--- /dev/null
@@ -0,0 +1,42 @@
+package MCC.IR;
+
+import java.util.*;
+
+public class VarExpr extends Expr {
+
+    String varname;
+    VarDescriptor vd = null;
+
+    public VarExpr(String varname) {
+        this.varname = varname; 
+    }
+
+    public Set getRequiredDescriptors() {
+        return new HashSet();
+    }
+
+    public void generate(CodeWriter writer, VarDescriptor dest) {        
+        writer.outputline(vd.getType().getGenerateType().getSafeSymbol() + " " + dest.getSafeSymbol() + 
+                          " = (" + vd.getType().getGenerateType().getSafeSymbol() + ") " + vd.getSafeSymbol() + ";");
+    }
+
+    public void prettyPrint(PrettyPrinter pp) {
+        pp.output(varname);
+    }
+
+    public TypeDescriptor typecheck(SemanticAnalyzer sa) {
+        vd = (VarDescriptor) sa.getSymbolTable().get(varname);
+
+        if (vd == null) {
+            System.out.println(varname);
+            sa.getErrorReporter().report(null, "Undefined variable '" + varname + "'");
+            return null;
+        }
+        
+        assert vd.getType() != null;
+
+        this.td = vd.getType();
+        return this.td;
+    }
+    
+}
diff --git a/Repair/RepairCompiler/MCC/IR/Walkable.java b/Repair/RepairCompiler/MCC/IR/Walkable.java
new file mode 100755 (executable)
index 0000000..d605327
--- /dev/null
@@ -0,0 +1,35 @@
+
+package MCC.IR;
+
+/**
+ * The Walkable interface specifies a set of methods that defines a web. 
+ */
+
+public interface Walkable {
+
+    /**
+     * Returns the name of the node
+     */
+    public String getNodeName();
+
+
+    /**
+     * Returns the number of neighbors from this node
+     */
+    public int getNeighborCount();
+
+
+    /**
+     * Returns a specific neighbor
+     */
+    public Object getNeighbor(int index);
+
+    /**
+     * Returns a pretty print of the representation of the node. 
+     *
+     * @param indent    number of blank spaces to skip for a new line
+     * @param recursive if true, recursively print children
+     */
+    public String PPrint(int indent, boolean recursive);
+}
+