package org.simantics.scl.compiler.elaboration.chr.plan; import java.util.ArrayList; import org.simantics.scl.compiler.compilation.CompilationContext; import org.simantics.scl.compiler.constants.Constant; import org.simantics.scl.compiler.constants.JavaComparisonOperation; import org.simantics.scl.compiler.constants.singletons.NullCheck; import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.Variable; 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 IterateConstraintOp extends PlanOp { public CHRConstraint constraint; public Variable[] variables; public Expression[] expressions; public int boundMask; public boolean killAfterMatch; public boolean passive; public IterateConstraintOp(long location, CHRConstraint constraint, Variable[] variables, Expression[] expressions, int boundMask, boolean killAfterMatch, boolean passive) { super(location); this.constraint = constraint; this.variables = variables; this.expressions = expressions; this.boundMask = boundMask; this.killAfterMatch = killAfterMatch; this.passive = passive; } @Override public void toString(StringBuilder b) { b.append("ITERATE ").append(constraint); for(int i=0;i parameters = new ArrayList(expressions.length+1); parameters.add(planContext.storeVar); for(int i=0;i>i)&1)==1) parameters.add(expressions[i].toVal(context.environment, w)); w.jump(bodyContinuation, w.apply(location, constraint.fetchFromIndex(context, boundMask), parameters.toArray(new IVal[parameters.size()]))); body.branchAwayIf(body.apply(location, NullCheck.INSTANCE.createSpecialization(constraint.factType), fact), end.getContinuation()); IVal id = body.apply(location, constraint.accessId, fact); for(PartnerFact partnerFact : planContext.partnerFacts) if(partnerFact.active && !passive) { body.branchAwayUnless(body.apply(location, JavaComparisonOperation.ILESS, id, partnerFact.id), nextFact.getContinuation()); } else if(partnerFact.constraint == constraint) { body.branchAwayIf(body.apply(location, JavaComparisonOperation.IEQUAL, id, partnerFact.id), nextFact.getContinuation()); } for(int i=0;i>i)&1)==0) variables[i].setVal(constraint.accessComponent(location, body, fact, i)); Constant nextElement = constraint.nextElement(context, boundMask); planContext.partnerFacts.add(new PartnerFact(false, id, constraint, fact, constraint.mayBeRemoved(), killAfterMatch, nextElement, bodyContinuation, end.getContinuation())); planContext.nextOp(body); if(body.isUnfinished()) body.jump(nextFact.getContinuation()); nextFact.jump(bodyContinuation, nextFact.apply(location, nextElement, fact)); w.continueAs(end); } }