]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/IterateConstraintOp.java
Merge "Improved Statement API in Simantics/DB"
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / chr / plan / IterateConstraintOp.java
1 package org.simantics.scl.compiler.elaboration.chr.plan;
2
3 import java.util.ArrayList;
4
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;
16
17 public class IterateConstraintOp extends PlanOp {
18     
19     public CHRConstraint constraint;
20     public Variable[] variables;
21     public Expression[] expressions;
22     public int boundMask;
23     public boolean killAfterMatch;
24     public boolean passive;
25     
26     public IterateConstraintOp(long location, CHRConstraint constraint, Variable[] variables, Expression[] expressions,
27             int boundMask, boolean killAfterMatch, boolean passive) {
28         super(location);
29         this.constraint = constraint;
30         this.variables = variables;
31         this.expressions = expressions;
32         this.boundMask = boundMask;
33         this.killAfterMatch = killAfterMatch;
34         this.passive = passive;
35         
36     }
37
38     @Override
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(")");
44             }
45             else {
46                 b.append(" ").append(variables[i]);
47             }
48     }
49
50     @Override
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];
57
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()])));
65
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());
73             }
74             else if(partnerFact.constraint == constraint) {
75                 body.branchAwayIf(body.apply(location, JavaComparisonOperation.IEQUAL, id, partnerFact.id),
76                         nextFact.getContinuation());
77             }
78
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));
88
89         w.continueAs(end);
90     }   
91 }