Iterator targets = inclusion.getTargetDescriptors().iterator();
String additionallabel = new String();
+ /* #ATTN#: is this meant to be while, not if? */
+ /* perhaps there is only one descriptor for targets */
if (targets.hasNext()) {
Descriptor d = (Descriptor)targets.next();
additionallabel = "\\n" + d.getSymbol();
String field;
Expr index;
+ /*
+ static int memoryindents = 0;
+
+ public static void generate_memory_endblocks(CodeWriter cr) {
+ while (memoryindents > 0) {
+ memoryindents --;
+ cr.endblock();
+ }
+ memoryindents = 0;
+ }
+ */
+
public DotExpr(Expr left, String field, Expr index) {
this.left = left;
this.field = field;
String high = VarDescriptor.makeNew("high").getSafeSymbol();
writer.outputline("int " + high + " = " + low + " + " + sizeof.getSafeSymbol() + ";");
writer.outputline("assertvalidmemory(" + low + ", " + high + ");");
+
+ // we need to null value check and conditionalize the rest of the rule... we'll use a hack
+ // here where we store the number of indents in this class... and then provide a static
+ // method to unwind...
+ //writer.outputline("// assertvalidmemory ");
+ //DotExpr.memoryindents++;
+ //writer.outputline("if (" + dest.getSafeSymbol() + " != NULL)");
+ //writer.startblock();
}
}
writer.startblock();
}
+ public int generate_worklistload(CodeWriter writer, int offset) {
+ String varname = var.getSafeSymbol();
+ writer.outputline("int " + varname + " = wi->word" + offset + ";");
+ return offset + 1;
+ }
+
+ public int generate_workliststore(CodeWriter writer, int offset) {
+ String varname = var.getSafeSymbol();
+ writer.outputline("wi->word" + offset + " = " + varname + ";");
+ return offset + 1;
+ }
+
+
public boolean typecheck(SemanticAnalyzer sa) {
TypeDescriptor lt = lower.typecheck(sa);
TypeDescriptor ut = upper.typecheck(sa);
rule.getInclusion().generate(cr);
cr.endblock();
+ // close startblocks generated by DotExpr memory checks
+ //DotExpr.generate_memory_endblocks(cr);
+
while (quantifiers.hasPrevious()) {
Quantifier quantifier = (Quantifier) quantifiers.previous();
cr.endblock();
public abstract Set getRequiredDescriptors();
public abstract void generate_open(CodeWriter writer);
+
+ public abstract int generate_worklistload(CodeWriter writer, int offset);
+ public abstract int generate_workliststore(CodeWriter writer, int offset);
+
}
public void generate(CodeWriter writer, VarDescriptor dest) {
VarDescriptor domain = VarDescriptor.makeNew("domain");
+ String strinverse = inverse ? "inv" : "";
String found = (VarDescriptor.makeNew("found")).getSafeSymbol();
expr.generate(writer, domain);
writer.outputline(relation.getRange().getType().getGenerateType().getSafeSymbol() + " " + dest.getSafeSymbol() + ";");
- writer.outputline("int " + found + " = " + relation.getSafeSymbol() + "_hash->get(" + domain.getSafeSymbol() + ", " + dest.getSafeSymbol() + ");");
+ writer.outputline("int " + found + " = " + relation.getSafeSymbol() + "_hash" + strinverse + "->get(" + domain.getSafeSymbol() + ", " + dest.getSafeSymbol() + ");");
writer.outputline("if (!" + found + ") { maybe = 1; }");
}
// #TBD#: this flag needs to be set by some static analysis
boolean typesafe = true;
+ static boolean worklist = true;
public RelationInclusion(Expr leftelementexpr, Expr rightelementexpr, RelationDescriptor relation) {
this.leftelementexpr = leftelementexpr;
check += "1;"; // terminate boolean expression
writer.outputline(check);
- writer.outputline("if (" + typesafecheck + ") {");
- writer.indent();
+ writer.outputline("if (" + typesafecheck + ")");
+ writer.startblock();
}
-
+
+ String addeditem = (VarDescriptor.makeNew("addeditem")).getSafeSymbol();
+ writer.outputline("int " + addeditem + ";");
+
if (relation.testUsage(RelationDescriptor.IMAGE)) {
- writer.outputline(relation.getSafeSymbol() + "_hash->add((int)" + ld.getSafeSymbol() + ", (int)" + rd.getSafeSymbol() + ");");
+ writer.outputline(addeditem + " = " + relation.getSafeSymbol() + "_hash->add((int)" + ld.getSafeSymbol() + ", (int)" + rd.getSafeSymbol() + ");");
}
if (relation.testUsage(RelationDescriptor.INVIMAGE)) {
- writer.outputline(relation.getSafeSymbol() + "_hashinv->add((int)" + rd.getSafeSymbol() + ", (int)" + ld.getSafeSymbol() + ");");
+ writer.outputline(addeditem + " = " + relation.getSafeSymbol() + "_hashinv->add((int)" + rd.getSafeSymbol() + ", (int)" + ld.getSafeSymbol() + ");");
}
+ if (RelationInclusion.worklist) {
+ writer.outputline("if (" + addeditem + ")");
+ writer.startblock(); {
+ WorkList.generate_dispatch(writer, relation, rd.getSafeSymbol(), ld.getSafeSymbol());
+ }
+ writer.endblock();
+ }
+
if (!typesafe) {
- writer.unindent();
- writer.outputline("}");
+ writer.endblock();
}
//writer.outputline("printf(\"" + relation.getSafeSymbol() + " (add): <%d, %d>\\n\", " + ld.getSafeSymbol() + ", " + rd.getSafeSymbol() + ");");
writer.outputline(x.getType().getSafeSymbol() + " " + x.getSafeSymbol() + " = (" + x.getType().getSafeSymbol() + ") " + x.getSafeSymbol() + "_iterator->key();");
}
+ public int generate_worklistload(CodeWriter writer, int offset) {
+ String varx = x.getSafeSymbol();
+ String vary = y.getSafeSymbol();
+ writer.outputline("int " + varx + " = wi->word" + offset + "; // r1");
+ writer.outputline("int " + vary + " = wi->word" + (offset + 1) + "; //r2");
+ return offset + 2;
+ }
+
+ public int generate_workliststore(CodeWriter writer, int offset) {
+ String varx = x.getSafeSymbol();
+ String vary = y.getSafeSymbol();
+ writer.outputline("wi->word" + offset + " = " + varx + "; // r1");
+ writer.outputline("wi->word" + (offset+1) + " = " + vary + "; // r2");
+ return offset + 2;
+ }
+
+
}
SymbolTable st = new SymbolTable();
String label;
+
+ int num;
public Rule () {
+ num = count;
label = new String("rule" + count++);
}
+
+ public int getNum() {
+ return num;
+ }
public String getLabel() {
return label;
Expr elementexpr;
SetDescriptor set;
+ static boolean worklist = true;
+
public SetInclusion(Expr elementexpr, SetDescriptor set) {
this.elementexpr = elementexpr;
this.set = set;
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() + ");");
+
+ String addeditem = (VarDescriptor.makeNew("addeditem")).getSafeSymbol();
+ writer.outputline("int " + addeditem + ";");
+
+ writer.outputline(addeditem + " = " + set.getSafeSymbol() + "_hash->add((int)" + vd.getSafeSymbol()
+ + ", (int)" + vd.getSafeSymbol() + ");");
+
+ if (SetInclusion.worklist) {
+ writer.outputline("if (" + addeditem + ")");
+ writer.startblock(); {
+ WorkList.generate_dispatch(writer, set, vd.getSafeSymbol());
+ }
+ writer.endblock();
+ }
+
}
public boolean typecheck(SemanticAnalyzer sa) {
return v;
}
+ public VarDescriptor getVar() {
+ return var;
+ }
+
public SetDescriptor getSet() {
return set;
}
writer.outputline(var.getType().getGenerateType() + " " + var.getSafeSymbol() + " = (" + var.getType().getGenerateType() + ") " + var.getSafeSymbol() + "_iterator->next();");
}
+ public int generate_worklistload(CodeWriter writer, int offset) {
+ String varname = var.getSafeSymbol();
+ writer.outputline("int " + varname + " = wi->word" + offset + ";");
+ return offset + 1;
+ }
+
+ public int generate_workliststore(CodeWriter writer, int offset) {
+ String varname = var.getSafeSymbol();
+ writer.outputline("wi->word" + offset + " = " + varname + ";");
+ return offset + 1;
+ }
+
+
}
--- /dev/null
+package MCC.IR;
+
+import MCC.State;
+import java.util.*;
+
+public class WorkList {
+
+
+ public static Vector getrulelist(Descriptor d) {
+
+ Vector dispatchrules = new Vector();
+ Vector rules = State.currentState.vRules;
+
+ for (int i = 0; i < rules.size(); i++) {
+ Rule rule = (Rule) rules.elementAt(i);
+ Set requiredsymbols = rule.getRequiredDescriptors();
+
+ // #TBD#: in general this is wrong because these descriptors may contain descriptors
+ // bound in "in?" expressions which need to be dealt with in a topologically sorted
+ // fashion...
+
+ if (rule.getRequiredDescriptors().contains(d)) {
+ dispatchrules.addElement(rule);
+ }
+ }
+
+ return dispatchrules;
+ }
+
+
+ public static void generate_dispatch(CodeWriter cr, RelationDescriptor rd, String leftvar, String rightvar) {
+
+ cr.outputline("// RELATION DISPATCH ");
+
+ Vector dispatchrules = getrulelist(rd);
+
+ if (dispatchrules.size() == 0) {
+ cr.outputline("// nothing to dispatch");
+ return;
+ }
+
+ for(int i = 0; i < dispatchrules.size(); i++) {
+ Rule rule = (Rule) dispatchrules.elementAt(i);
+ cr.outputline("need to dispatch for " + rule.getLabel());
+ }
+
+ assert false; // unsupported
+
+ }
+
+
+ public static void generate_dispatch(CodeWriter cr, SetDescriptor sd, String setvar) {
+
+ cr.outputline("// SET DISPATCH ");
+
+ Vector dispatchrules = getrulelist(sd);
+
+ if (dispatchrules.size() == 0) {
+ cr.outputline("// nothing to dispatch");
+ return;
+ }
+
+ for(int i = 0; i < dispatchrules.size(); i++) {
+ Rule rule = (Rule) dispatchrules.elementAt(i);
+
+ ListIterator quantifiers = rule.quantifiers();
+ Vector otherq = new Vector(); // quantifiers that we need to iterate over to add workitems
+
+ cr.outputline("// " + rule.getLabel());
+ cr.startblock();
+
+
+ // #ATTN#: this may/does not handle multiple instances of the same quantifier being bound
+ // solution is probabyl to iterate over all bindings
+
+ // find quantifier that we have bound
+ String boundname = null;
+ int size = 4; // starts at 4 because we have to store the ID
+ while (quantifiers.hasNext()) {
+ Quantifier quantifier = (Quantifier) quantifiers.next();
+ if (quantifier instanceof SetQuantifier) {
+ size += 4;
+ SetQuantifier sq = (SetQuantifier) quantifier;
+ if (sq.getSet() == sd) {
+ // we have found our quantifier
+ boundname = sq.getVar().getSafeSymbol();
+
+ break;
+ }
+ } else if (quantifier instanceof RelationQuantifier) {
+ size += 8;
+ } else { // ForQuantifier
+ size += 4;
+ }
+
+ otherq.addElement(quantifier);
+ }
+
+ assert boundname != null;
+
+ // bind bound variable
+ cr.outputline("int " + boundname + " = " + setvar + ";");
+
+ // add the rest of the quantifiers and continue to calculate size
+ while (quantifiers.hasNext()) {
+ Quantifier quantifier = (Quantifier) quantifiers.next();
+ if (quantifier instanceof RelationQuantifier) {
+ size += 8;
+ } else {
+ size += 4;
+ }
+ }
+
+ ListIterator otheriterator = otherq.listIterator();
+ while (otheriterator.hasNext()) {
+ Quantifier quantifier = (Quantifier) otheriterator.next();
+ quantifier.generate_open(cr);
+ // implicitly opens bracket
+ }
+
+ cr.outputline("// dispatching to " + rule.getLabel());
+ // #TODO#: add code to do worklist addition
+
+ cr.outputline("WORKITEM *wi = (WORKITEM *) malloc(" + size + ");");
+ cr.outputline("wi->id = " + rule.getNum() + ";");
+
+ // reset quantifiers
+ quantifiers = rule.quantifiers();
+
+ // list quantifier so the order's match!
+ int offset = 0;
+ while (quantifiers.hasNext()) {
+ Quantifier quantifier = (Quantifier) quantifiers.next();
+ offset = quantifier.generate_workliststore(cr, offset);
+ }
+
+ // now store in worklist!
+ cr.outputline("WORKLIST->add((int) wi);");
+
+ // close all those brackets
+ while (otheriterator.hasPrevious()) {
+ otheriterator.previous(); // throw away
+ cr.endblock();
+ }
+
+ // end rule
+ cr.endblock();
+
+ }
+ }
+
+}
--- /dev/null
+package MCC.IR;
+
+import java.io.*;
+import java.util.*;
+import MCC.State;
+
+public class WorklistGenerator {
+
+ State state;
+ java.io.PrintWriter output = null;
+
+ public WorklistGenerator(State state) {
+ this.state = state;
+ }
+
+ public void generate(java.io.OutputStream output) {
+ this.output = new java.io.PrintWriter(output, true);
+
+ generate_tokentable();
+ generate_hashtables();
+ generate_worklist();
+ generate_rules();
+ generate_implicit_checks();
+ generate_checks();
+ generate_teardown();
+
+ }
+
+ private void generate_tokentable() {
+
+ CodeWriter cr = new StandardCodeWriter(output);
+ Iterator tokens = TokenLiteralExpr.tokens.keySet().iterator();
+
+ cr.outputline("");
+ cr.outputline("// Token values");
+ cr.outputline("");
+
+ while (tokens.hasNext()) {
+ Object token = tokens.next();
+ cr.outputline("// " + token.toString() + " = " + TokenLiteralExpr.tokens.get(token).toString());
+ }
+
+ cr.outputline("");
+ cr.outputline("");
+ }
+
+ private void generate_hashtables() {
+
+ CodeWriter cr = new StandardCodeWriter(output);
+ cr.outputline("int __Success = 1;\n");
+ 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();
+
+ if (relation.testUsage(RelationDescriptor.IMAGE)) {
+ cr.outputline("SimpleHash* " + relation.getSafeSymbol() + "_hash = new SimpleHash();");
+ }
+
+ if (relation.testUsage(RelationDescriptor.INVIMAGE)) {
+ cr.outputline("SimpleHash* " + relation.getSafeSymbol() + "_hashinv = new SimpleHash();");
+ }
+ }
+
+ cr.outputline("");
+ cr.outputline("");
+ }
+
+ private void generate_worklist() {
+
+ CodeWriter cr = new StandardCodeWriter(output);
+ cr.outputline("WORKLIST = new SimpleList();");
+
+ }
+
+ private void generate_teardown() {
+
+ CodeWriter cr = new StandardCodeWriter(output);
+ cr.outputline("WORKLIST->reset();");
+ cr.outputline("while (WORKLIST->hasMoreElements())");
+ cr.startblock();
+ cr.outputline("free ((WORKITEM *) WORKLIST->nextElement());");
+ cr.endblock();
+ cr.outputline("delete WORKLIST;");
+
+ }
+
+ private void generate_rules() {
+
+ /* first we must sort the rules */
+ Iterator allrules = state.vRules.iterator();
+
+ Vector emptyrules = new Vector(); // rules with no quantifiers
+ Vector worklistrules = new Vector(); // the rest of the rules
+
+ while (allrules.hasNext()) {
+ Rule rule = (Rule) allrules.next();
+ ListIterator quantifiers = rule.quantifiers();
+
+ boolean noquantifiers = true;
+ while (quantifiers.hasNext()) {
+ Quantifier quantifier = (Quantifier) quantifiers.next();
+ if (quantifier instanceof ForQuantifier) {
+ // ok, because integers exist already!
+ } else {
+ // real quantifier
+ noquantifiers = false;
+ break;
+ }
+ }
+
+ if (noquantifiers) {
+ emptyrules.add(rule);
+ } else {
+ worklistrules.add(rule);
+ }
+ }
+
+ Iterator iterator_er = emptyrules.iterator();
+ while (iterator_er.hasNext()) {
+
+ Rule rule = (Rule) iterator_er.next();
+
+ {
+ final SymbolTable st = rule.getSymbolTable();
+ CodeWriter cr = new StandardCodeWriter(output) {
+ public SymbolTable getSymbolTable() { return st; }
+ };
+
+ cr.outputline("// build " + rule.getLabel());
+ cr.startblock();
+
+ 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.startblock();
+
+ /* now we have to generate the inclusion code */
+ rule.getInclusion().generate(cr);
+ cr.endblock();
+
+ while (quantifiers.hasPrevious()) {
+ Quantifier quantifier = (Quantifier) quantifiers.previous();
+ cr.endblock();
+ }
+
+ cr.endblock();
+ cr.outputline("");
+ cr.outputline("");
+ }
+ }
+
+ CodeWriter cr2 = new StandardCodeWriter(output);
+
+ cr2.outputline("WORKLIST->reset();");
+ cr2.outputline("while (WORKLIST->hasMoreElements())");
+ cr2.startblock();
+ cr2.outputline("WORKITEM *wi = (WORKITEM *) WORKLIST->nextElement();");
+
+ String elseladder = "if";
+
+ Iterator iterator_rules = worklistrules.iterator();
+ while (iterator_rules.hasNext()) {
+
+ Rule rule = (Rule) iterator_rules.next();
+ int dispatchid = rule.getNum();
+
+ {
+ final SymbolTable st = rule.getSymbolTable();
+ CodeWriter cr = new StandardCodeWriter(output) {
+ public SymbolTable getSymbolTable() { return st; }
+ };
+
+ cr.indent();
+ cr.outputline(elseladder + " (wi->id == " + dispatchid + ")");
+ cr.startblock();
+
+ cr.outputline("// build " + rule.getLabel());
+
+ ListIterator quantifiers = rule.quantifiers();
+
+ int count = 0;
+ while (quantifiers.hasNext()) {
+ Quantifier quantifier = (Quantifier) quantifiers.next();
+ count = quantifier.generate_worklistload(cr, count );
+ }
+
+ /* 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.startblock();
+
+ /* now we have to generate the inclusion code */
+ rule.getInclusion().generate(cr);
+ cr.endblock();
+
+ // close startblocks generated by DotExpr memory checks
+ //DotExpr.generate_memory_endblocks(cr);
+
+ cr.endblock(); // end else-if WORKLIST ladder
+
+ elseladder = "else if";
+ }
+ }
+
+ cr2.outputline("else");
+ cr2.startblock();
+ cr2.outputline("printf(\"VERY BAD !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\\n\\n\");");
+ cr2.outputline("exit(1);");
+ cr2.endblock();
+
+ // end block created for worklist
+ cr2.endblock();
+
+ }
+
+ private void generate_implicit_checks() {
+
+ /* do post checks */
+
+ CodeWriter cr = new StandardCodeWriter(output);
+
+ // #TBD#: these should be implicit checks added to the set of constraints
+ //output.println("check multiplicity");
+ }
+
+ private void generate_checks() {
+
+ /* do constraint checks */
+ Vector constraints = state.vConstraints;
+
+ for (int i = 0; i < constraints.size(); i++) {
+
+ Constraint constraint = (Constraint) constraints.elementAt(i);
+
+ {
+
+ final SymbolTable st = constraint.getSymbolTable();
+
+ CodeWriter cr = new StandardCodeWriter(output) {
+ public SymbolTable getSymbolTable() { return st; }
+ };
+
+ cr.outputline("// checking " + constraint.getLabel());
+ cr.startblock();
+
+ ListIterator quantifiers = constraint.quantifiers();
+
+ while (quantifiers.hasNext()) {
+ Quantifier quantifier = (Quantifier) quantifiers.next();
+ quantifier.generate_open(cr);
+ }
+
+ cr.outputline("int maybe = 0;");
+
+ /* now we have to generate the guard test */
+
+ VarDescriptor constraintboolean = VarDescriptor.makeNew("constraintboolean");
+ constraint.getLogicStatement().generate(cr, constraintboolean);
+
+ cr.outputline("if (maybe)");
+ cr.startblock();
+ cr.outputline("__Success = 0;");
+ cr.outputline("printf(\"maybe fail " + (i+1) + ". \");");
+ cr.outputline("exit(1);");
+ cr.endblock();
+
+ cr.outputline("else if (!" + constraintboolean.getSafeSymbol() + ")");
+ cr.startblock();
+
+ cr.outputline("__Success = 0;");
+ cr.outputline("printf(\"fail " + (i+1) + ". \");");
+ cr.outputline("exit(1);");
+ cr.endblock();
+
+ while (quantifiers.hasPrevious()) {
+ Quantifier quantifier = (Quantifier) quantifiers.previous();
+ cr.endblock();
+ }
+
+ cr.endblock();
+ cr.outputline("");
+ cr.outputline("");
+ }
+
+ }
+
+ output.println("// if (__Success) { printf(\"all tests passed\"); }");
+ }
+
+}
+
+
+