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;
15 import org.simantics.scl.compiler.types.Types;
17 public class IterateConstraintOp extends PlanOp {
19 public CHRConstraint constraint;
20 public Variable[] variables;
21 public Expression[] expressions;
23 public boolean killAfterMatch;
24 public boolean passive;
26 public IterateConstraintOp(long location, CHRConstraint constraint, Variable[] variables, Expression[] expressions,
27 int boundMask, boolean killAfterMatch, boolean passive) {
29 this.constraint = constraint;
30 this.variables = variables;
31 this.expressions = expressions;
32 this.boundMask = boundMask;
33 this.killAfterMatch = killAfterMatch;
34 this.passive = passive;
39 public void toString(StringBuilder b) {
40 b.append("ITERATE ").append(constraint);
41 for(int i=0;i<expressions.length;++i)
42 if((boundMask & (1 << i)) != 0) {
43 b.append(" (").append(expressions[i]).append(")");
46 b.append(" ").append(variables[i]);
51 public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) {
52 CodeWriter body = w.createBlock(constraint.factType);
53 CodeWriter nextFact = w.createBlock();
54 ICont bodyContinuation = body.getContinuation();
55 CodeWriter end = w.createBlock();
56 IVal fact = body.getParameters()[0];
58 ArrayList<IVal> parameters = new ArrayList<IVal>(expressions.length+1);
59 parameters.add(planContext.storeVar);
60 for(int i=0;i<expressions.length;++i)
61 if(((boundMask>>i)&1)==1)
62 parameters.add(expressions[i].toVal(context.environment, w));
63 w.jump(bodyContinuation, w.apply(location,
64 constraint.fetchFromIndex(context, boundMask), parameters.toArray(new IVal[parameters.size()])));
66 body.branchAwayIf(body.apply(location, NullCheck.INSTANCE.createSpecialization(constraint.factType), fact),
67 end.getContinuation());
68 IVal id = body.apply(location, constraint.accessId, fact);
69 for(PartnerFact partnerFact : planContext.partnerFacts)
70 if(partnerFact.active && !passive) {
71 body.branchAwayUnless(body.apply(location, JavaComparisonOperation.ILESS, id, partnerFact.id),
72 nextFact.getContinuation());
74 else if(partnerFact.constraint == constraint) {
75 body.branchAwayIf(body.apply(location, JavaComparisonOperation.IEQUAL, id, partnerFact.id),
76 nextFact.getContinuation());
79 for(int i=0;i<variables.length;++i)
80 if(((boundMask>>i)&1)==0)
81 variables[i].setVal(constraint.accessComponent(location, body, fact, i));
82 Constant nextElement = constraint.nextElement(context, boundMask);
83 planContext.partnerFacts.add(new PartnerFact(false, id, constraint, fact, constraint.mayBeRemoved(), killAfterMatch, nextElement, bodyContinuation, end.getContinuation()));
84 planContext.nextOp(body);
85 if(body.isUnfinished())
86 body.jump(nextFact.getContinuation());
87 nextFact.jump(bodyContinuation, nextFact.apply(location, nextElement, fact));