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