-package org.simantics.scl.compiler.elaboration.chr.plan;\r
-\r
-import org.simantics.scl.compiler.compilation.CompilationContext;\r
-import org.simantics.scl.compiler.constants.IntegerConstant;\r
-import org.simantics.scl.compiler.constants.singletons.NullCheck;\r
-import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
-import org.simantics.scl.compiler.internal.codegen.continuations.ICont;\r
-import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
-import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
-\r
-public class PostCommitOp extends PlanOp {\r
- int priority;\r
- \r
- public PostCommitOp(long location, int priority) {\r
- super(location);\r
- this.priority = priority;\r
- }\r
-\r
- @Override\r
- public void toString(StringBuilder b) {\r
- b.append("POST_COMMIT " + priority);\r
- }\r
-\r
- @Override\r
- public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {\r
- if(planContext.currentId != null) {\r
- w.apply(location, planContext.ruleset.writeCurrentId, planContext.storeVar, planContext.currentId);\r
- planContext.currentId = null;\r
- w.apply(location, planContext.ruleset.activateProcedure, planContext.storeVar, new IntegerConstant(priority));\r
- }\r
- for(PartnerFact activeFact : planContext.partnerFacts) {\r
- if(activeFact.killAfterMatch) {\r
- if(activeFact.nextFact == null)\r
- w.jump(activeFact.finishCont);\r
- else {\r
- CodeWriter iterateAlive = w.createBlock(activeFact.constraint.factType);\r
- w.jump(iterateAlive.getContinuation(), w.apply(location, activeFact.nextFact, activeFact.factVar));\r
- iterateUntilLiveFactFound(iterateAlive, activeFact); \r
- }\r
- break;\r
- }\r
- else if(activeFact.mayBeRemoved) {\r
- if(activeFact.nextFact == null) {\r
- w.branchAwayUnless(activeFact.isAlive(location, w), activeFact.finishCont);\r
- }\r
- else {\r
- CodeWriter failure = w.createBlock();\r
- CodeWriter iterateAlive = w.createBlock(activeFact.constraint.factType);\r
- w.branchAwayUnless(activeFact.isAlive(location, w), failure.getContinuation());\r
- failure.jump(iterateAlive.getContinuation(), failure.apply(location, activeFact.nextFact, activeFact.factVar));\r
- iterateUntilLiveFactFound(iterateAlive, activeFact); \r
- }\r
- }\r
- }\r
- // PostCommit does not call nextOp\r
- }\r
- \r
- private void iterateUntilLiveFactFound(CodeWriter w, PartnerFact activeFact) {\r
- ICont initialContinuation = w.getContinuation();\r
- CHRConstraint constraint = activeFact.constraint;\r
- IVal fact = w.getParameters()[0];\r
- CodeWriter dead = w.createBlock();\r
- w.branchAwayIf(w.apply(location, NullCheck.INSTANCE.createSpecialization(constraint.factType), fact), activeFact.finishCont);\r
- w.branchAwayUnless(activeFact.isAlive(location, w, fact), dead.getContinuation());\r
- w.jump(activeFact.continueCont, fact);\r
- dead.jump(initialContinuation, dead.apply(location, activeFact.nextFact, fact));\r
- }\r
-\r
-}\r
+package org.simantics.scl.compiler.elaboration.chr.plan;
+
+import org.simantics.scl.compiler.compilation.CompilationContext;
+import org.simantics.scl.compiler.constants.IntegerConstant;
+import org.simantics.scl.compiler.constants.singletons.NullCheck;
+import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
+import org.simantics.scl.compiler.internal.codegen.continuations.ICont;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
+
+public class PostCommitOp extends PlanOp {
+ int priority;
+
+ public PostCommitOp(long location, int priority) {
+ super(location);
+ this.priority = priority;
+ }
+
+ @Override
+ public void toString(StringBuilder b) {
+ b.append("POST_COMMIT " + priority);
+ }
+
+ @Override
+ public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {
+ if(planContext.currentId != null) {
+ w.apply(location, planContext.ruleset.writeCurrentId, planContext.contextVar, planContext.currentId);
+ planContext.currentId = null;
+ w.apply(location, CHRRuleset.ACTIVATE, planContext.contextVar, new IntegerConstant(priority+planContext.ruleset.initialPriorityNumber));
+ }
+ for(PartnerFact activeFact : planContext.partnerFacts) {
+ if(activeFact.killAfterMatch) {
+ if(activeFact.nextFact == null)
+ w.jump(activeFact.finishCont);
+ else {
+ CodeWriter iterateAlive = w.createBlock(activeFact.constraint.factType);
+ w.jump(iterateAlive.getContinuation(), w.apply(location, activeFact.nextFact, activeFact.factVar));
+ iterateUntilLiveFactFound(iterateAlive, activeFact);
+ }
+ break;
+ }
+ else if(activeFact.mayBeRemoved) {
+ if(activeFact.nextFact == null) {
+ w.branchAwayUnless(activeFact.isAlive(location, w), activeFact.finishCont);
+ }
+ else {
+ CodeWriter failure = w.createBlock();
+ CodeWriter iterateAlive = w.createBlock(activeFact.constraint.factType);
+ w.branchAwayUnless(activeFact.isAlive(location, w), failure.getContinuation());
+ failure.jump(iterateAlive.getContinuation(), failure.apply(location, activeFact.nextFact, activeFact.factVar));
+ iterateUntilLiveFactFound(iterateAlive, activeFact);
+ }
+ }
+ }
+ // PostCommit does not call nextOp
+ }
+
+ private void iterateUntilLiveFactFound(CodeWriter w, PartnerFact activeFact) {
+ ICont initialContinuation = w.getContinuation();
+ CHRConstraint constraint = activeFact.constraint;
+ IVal fact = w.getParameters()[0];
+ CodeWriter dead = w.createBlock();
+ w.branchAwayIf(w.apply(location, NullCheck.INSTANCE.createSpecialization(constraint.factType), fact), activeFact.finishCont);
+ w.branchAwayUnless(activeFact.isAlive(location, w, fact), dead.getContinuation());
+ w.jump(activeFact.continueCont, fact);
+ dead.jump(initialContinuation, dead.apply(location, activeFact.nextFact, fact));
+ }
+
+}