]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/items/EqualsPrePlanItem.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / chr / planning / items / EqualsPrePlanItem.java
1 package org.simantics.scl.compiler.elaboration.chr.planning.items;
2
3 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
4 import org.simantics.scl.compiler.elaboration.chr.plan.AssignOp;
5 import org.simantics.scl.compiler.elaboration.chr.plan.CheckOp;
6 import org.simantics.scl.compiler.elaboration.chr.plan.MatchOp;
7 import org.simantics.scl.compiler.elaboration.chr.planning.PrePlanItem;
8 import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;
9 import org.simantics.scl.compiler.elaboration.expressions.EApply;
10 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
11 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
12 import org.simantics.scl.compiler.elaboration.expressions.Expression;
13 import org.simantics.scl.compiler.elaboration.expressions.Variable;
14 import org.simantics.scl.compiler.elaboration.java.Builtins;
15
16 import gnu.trove.set.hash.TIntHashSet;
17
18 public class EqualsPrePlanItem extends PrePlanItem {
19     public Expression expression1, expression2;
20     public TIntHashSet variableSet1, variableSet2;
21
22     public EqualsPrePlanItem(Expression expression1, Expression expression2, TIntHashSet variableSet1, TIntHashSet variableSet2, int secondaryPriority) {
23         super(secondaryPriority);
24         this.expression1 = expression1;
25         this.expression2 = expression2;
26         this.variableSet1 = variableSet1;
27         this.variableSet2 = variableSet2;
28         updatePrimaryPriority();
29     }
30
31     private void updatePrimaryPriority() {
32         if(variableSet2.isEmpty()) {
33             if(variableSet1.isEmpty())
34                 primaryPriority = 0;
35             else 
36                 primaryPriority = 1;
37         }
38         else {
39             if(variableSet1.isEmpty() && expression2.isPattern(0))
40                 primaryPriority = 0.0;
41         }
42     }
43
44     @Override
45     public void initializeListeners(QueryPlanningContext context) {
46         context.listen(variableSet1, this);
47         context.listen(variableSet2, this);
48     }
49
50     @Override
51     public void variableSolved(QueryPlanningContext context, int variableId) {
52         variableSet1.remove(variableId);
53         variableSet2.remove(variableId);
54         updatePrimaryPriority();
55         context.priorityQueue.adjust(this);
56     }
57     
58     @Override
59     public void generate(QueryPlanningContext context) {
60         if(variableSet1.isEmpty() && variableSet2.isEmpty()) {
61             context.addPlanOp(new CheckOp(location, new EApply(location, new EConstant(Builtins.EQUALS, expression1.getType()), expression1, expression2)));
62         }
63         else if(variableSet2.isEmpty()) {
64             Variable variable = ((EVariable)expression1).getVariable();
65             context.addPlanOp(new AssignOp(location, variable, expression2));
66             context.bind(variableSet1);
67         }
68         else if(variableSet1.isEmpty()) {
69             if(expression2 instanceof EVariable) {
70                 Variable variable = ((EVariable)expression2).getVariable();
71                 context.addPlanOp(new AssignOp(location, variable, expression1));
72             }
73             else {
74                 context.addPlanOp(new MatchOp(location, expression1, expression2));
75             }
76             context.bind(variableSet2);
77         }
78         else
79             throw new InternalCompilerError("Unsolvable query.");
80     }
81 }