1 package org.simantics.scl.compiler.elaboration.chr.plan;
\r
3 import org.simantics.scl.compiler.compilation.CompilationContext;
\r
4 import org.simantics.scl.compiler.constants.IntegerConstant;
\r
5 import org.simantics.scl.compiler.constants.singletons.NullCheck;
\r
6 import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
\r
7 import org.simantics.scl.compiler.internal.codegen.continuations.ICont;
\r
8 import org.simantics.scl.compiler.internal.codegen.references.IVal;
\r
9 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
\r
11 public class PostCommitOp extends PlanOp {
\r
14 public PostCommitOp(long location, int priority) {
\r
16 this.priority = priority;
\r
20 public void toString(StringBuilder b) {
\r
21 b.append("POST_COMMIT " + priority);
\r
25 public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {
\r
26 if(planContext.currentId != null) {
\r
27 w.apply(location, planContext.ruleset.writeCurrentId, planContext.storeVar, planContext.currentId);
\r
28 planContext.currentId = null;
\r
29 w.apply(location, planContext.ruleset.activateProcedure, planContext.storeVar, new IntegerConstant(priority));
\r
31 for(PartnerFact activeFact : planContext.partnerFacts) {
\r
32 if(activeFact.killAfterMatch) {
\r
33 if(activeFact.nextFact == null)
\r
34 w.jump(activeFact.finishCont);
\r
36 CodeWriter iterateAlive = w.createBlock(activeFact.constraint.factType);
\r
37 w.jump(iterateAlive.getContinuation(), w.apply(location, activeFact.nextFact, activeFact.factVar));
\r
38 iterateUntilLiveFactFound(iterateAlive, activeFact);
\r
42 else if(activeFact.mayBeRemoved) {
\r
43 if(activeFact.nextFact == null) {
\r
44 w.branchAwayUnless(activeFact.isAlive(location, w), activeFact.finishCont);
\r
47 CodeWriter failure = w.createBlock();
\r
48 CodeWriter iterateAlive = w.createBlock(activeFact.constraint.factType);
\r
49 w.branchAwayUnless(activeFact.isAlive(location, w), failure.getContinuation());
\r
50 failure.jump(iterateAlive.getContinuation(), failure.apply(location, activeFact.nextFact, activeFact.factVar));
\r
51 iterateUntilLiveFactFound(iterateAlive, activeFact);
\r
55 // PostCommit does not call nextOp
\r
58 private void iterateUntilLiveFactFound(CodeWriter w, PartnerFact activeFact) {
\r
59 ICont initialContinuation = w.getContinuation();
\r
60 CHRConstraint constraint = activeFact.constraint;
\r
61 IVal fact = w.getParameters()[0];
\r
62 CodeWriter dead = w.createBlock();
\r
63 w.branchAwayIf(w.apply(location, NullCheck.INSTANCE.createSpecialization(constraint.factType), fact), activeFact.finishCont);
\r
64 w.branchAwayUnless(activeFact.isAlive(location, w, fact), dead.getContinuation());
\r
65 w.jump(activeFact.continueCont, fact);
\r
66 dead.jump(initialContinuation, dead.apply(location, activeFact.nextFact, fact));
\r