1 package org.simantics.scl.compiler.elaboration.chr.plan;
3 import java.util.ArrayList;
5 import org.simantics.scl.compiler.compilation.CompilationContext;
6 import org.simantics.scl.compiler.constants.Constant;
7 import org.simantics.scl.compiler.constants.JavaComparisonOperation;
8 import org.simantics.scl.compiler.constants.singletons.NullCheck;
9 import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
10 import org.simantics.scl.compiler.elaboration.expressions.Expression;
11 import org.simantics.scl.compiler.elaboration.expressions.Variable;
12 import org.simantics.scl.compiler.internal.codegen.continuations.ICont;
13 import org.simantics.scl.compiler.internal.codegen.references.IVal;
14 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
16 public class IterateConstraintOp extends PlanOp {
18 public CHRConstraint constraint;
19 public Variable[] variables;
20 public Expression[] expressions;
22 public boolean killAfterMatch;
23 public boolean passive;
25 public IterateConstraintOp(long location, CHRConstraint constraint, Variable[] variables, Expression[] expressions,
26 int boundMask, boolean killAfterMatch, boolean passive) {
28 this.constraint = constraint;
29 this.variables = variables;
30 this.expressions = expressions;
31 this.boundMask = boundMask;
32 this.killAfterMatch = killAfterMatch;
33 this.passive = passive;
38 public void toString(StringBuilder b) {
39 b.append("ITERATE ").append(constraint);
40 for(int i=0;i<expressions.length;++i)
41 if((boundMask & (1 << i)) != 0) {
42 b.append(" (").append(expressions[i]).append(")");
45 b.append(" ").append(variables[i]);
50 public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {
51 CodeWriter body = w.createBlock(constraint.factType);
52 CodeWriter nextFact = w.createBlock();
53 ICont bodyContinuation = body.getContinuation();
54 CodeWriter end = w.createBlock();
55 IVal fact = body.getParameters()[0];
57 ArrayList<IVal> parameters = new ArrayList<IVal>(expressions.length+1);
58 parameters.add(planContext.storeVar);
59 for(int i=0;i<expressions.length;++i)
60 if(((boundMask>>i)&1)==1)
61 parameters.add(expressions[i].toVal(context.environment, w));
62 w.jump(bodyContinuation, w.apply(location,
63 constraint.fetchFromIndex(context, boundMask), parameters.toArray(new IVal[parameters.size()])));
65 body.branchAwayIf(body.apply(location, NullCheck.INSTANCE.createSpecialization(constraint.factType), fact),
66 end.getContinuation());
67 IVal id = body.apply(location, constraint.accessId, fact);
68 for(PartnerFact partnerFact : planContext.partnerFacts)
69 if(partnerFact.active && !passive) {
70 body.branchAwayUnless(body.apply(location, JavaComparisonOperation.ILESS, id, partnerFact.id),
71 nextFact.getContinuation());
73 else if(partnerFact.constraint == constraint) {
74 body.branchAwayIf(body.apply(location, JavaComparisonOperation.IEQUAL, id, partnerFact.id),
75 nextFact.getContinuation());
78 for(int i=0;i<variables.length;++i)
79 if(((boundMask>>i)&1)==0)
80 variables[i].setVal(constraint.accessComponent(location, body, fact, i));
81 Constant nextElement = constraint.nextElement(context, boundMask);
82 planContext.partnerFacts.add(new PartnerFact(false, id, constraint, fact, constraint.mayBeRemoved(), killAfterMatch, nextElement, bodyContinuation, end.getContinuation()));
83 planContext.nextOp(body);
84 if(body.isUnfinished())
85 body.jump(nextFact.getContinuation());
86 nextFact.jump(bodyContinuation, nextFact.apply(location, nextElement, fact));