]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectFreeVariablesVisitor.java
(refs #7375) Replaced collectFreeVariables method by a visitor
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / visitors / CollectFreeVariablesVisitor.java
1 package org.simantics.scl.compiler.elaboration.expressions.visitors;
2
3 import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
4 import org.simantics.scl.compiler.elaboration.chr.CHRQuery;
5 import org.simantics.scl.compiler.elaboration.chr.CHRRule;
6 import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;
7 import org.simantics.scl.compiler.elaboration.expressions.Assignment;
8 import org.simantics.scl.compiler.elaboration.expressions.Case;
9 import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
10 import org.simantics.scl.compiler.elaboration.expressions.EBind;
11 import org.simantics.scl.compiler.elaboration.expressions.ECHRSelect;
12 import org.simantics.scl.compiler.elaboration.expressions.ELet;
13 import org.simantics.scl.compiler.elaboration.expressions.ERuleset.DatalogRule;
14 import org.simantics.scl.compiler.elaboration.expressions.ESelect;
15 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
16 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet;
17 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
18 import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
19 import org.simantics.scl.compiler.elaboration.expressions.EWhen;
20 import org.simantics.scl.compiler.elaboration.expressions.Expression;
21 import org.simantics.scl.compiler.elaboration.expressions.Variable;
22 import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
23 import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
24 import org.simantics.scl.compiler.elaboration.query.QExists;
25
26 import gnu.trove.set.hash.THashSet;
27
28 public class CollectFreeVariablesVisitor extends StandardExpressionVisitor {
29     private THashSet<Variable> freeVariables = new THashSet<Variable>();
30     
31     private StandardExpressionVisitor collectBoundVariablesVisitor = new StandardExpressionVisitor() {
32         @Override
33         public void visit(EVariable expression) {
34             if(expression.variable != null)
35                 freeVariables.remove(expression.variable);
36         }
37         
38         
39         @Override
40         public void visit(EAsPattern expression) {
41             freeVariables.remove(expression.var);
42             expression.pattern.accept(this);
43         }
44         
45         @Override
46         public void visit(EViewPattern expression) {
47             expression.expression.accept(CollectFreeVariablesVisitor.this);
48             expression.pattern.accept(this);
49         }
50     };
51     
52     @Override
53     public void visit(EVariable expression) {
54         if(expression.variable != null)
55             freeVariables.add(expression.variable);
56     }
57     
58     @Override
59     public void visit(EBind expression) {
60         if(expression.monadEvidence != null)
61             visit(expression.monadEvidence);
62         expression.in.accept(this);
63         expression.value.accept(this);
64         expression.pattern.accept(collectBoundVariablesVisitor);
65     }
66     
67     @Override
68     public void visit(Assignment assignment) {
69         assignment.value.accept(this);
70         assignment.pattern.accept(collectBoundVariablesVisitor);
71     }
72     
73     @Override
74     public void visit(ELet expression) {
75         expression.in.accept(this);
76         for(int i=expression.assignments.length-1;i>=0;--i)
77             visit(expression.assignments[i]);
78     }
79     
80     @Override
81     public void visit(Case case_) {
82         case_.value.accept(this);
83         for(Expression pattern : case_.patterns)
84             pattern.accept(collectBoundVariablesVisitor);
85     }
86     
87     @Override
88     public void visit(ESimpleLambda expression) {
89         expression.value.accept(this);
90         freeVariables.remove(expression.parameter);
91     }
92     
93     @Override
94     public void visit(ESimpleLet expression) {
95         expression.in.accept(this);
96         expression.value.accept(this);
97         freeVariables.remove(expression.variable);
98     }
99     
100     @Override
101     public void visit(ECHRSelect expression) {
102         expression.expression.accept(this);
103         visit(expression.query);
104         for(Variable variable : expression.existentialVariables)
105             freeVariables.remove(variable);
106     }
107     
108     @Override
109     public void visit(ESelect expression) {
110         expression.expression.accept(this);
111         expression.query.accept(this);
112         for(Variable variable : expression.variables)
113             freeVariables.remove(variable);
114     }
115     
116     @Override
117     public void visit(EWhen expression) {
118         expression.action.accept(this);
119         expression.query.accept(this);
120         for(Variable variable : expression.variables)
121             freeVariables.remove(variable);
122     }
123
124     @Override
125     public void visit(DatalogRule rule) {
126         for(Expression parameter : rule.headParameters)
127             parameter.accept(this);
128         rule.body.accept(this);
129         for(Variable variable : rule.variables)
130             freeVariables.remove(variable);
131     }
132     
133     @Override
134     public void visit(ListGenerator qualifier) {
135         qualifier.pattern.accept(collectBoundVariablesVisitor);
136         qualifier.value.accept(this);
137     }
138     
139     @Override
140     public void visit(ListAssignment qualifier) {
141         qualifier.pattern.accept(collectBoundVariablesVisitor);
142         qualifier.value.accept(this);
143     }
144     
145     @Override
146     public void visit(CHRLiteral literal) {
147         if(literal.relation == SpecialCHRRelation.ASSIGN) {
148             literal.parameters[0].accept(collectBoundVariablesVisitor);
149             literal.parameters[1].accept(this);
150         }
151         else {
152             for(Expression parameter : literal.parameters)
153                 parameter.accept(this);
154             if(literal.typeConstraintEvidenceParameters != null)
155                 for(Expression parameter : literal.typeConstraintEvidenceParameters)
156                     parameter.accept(this);
157         }
158     }
159     
160     @Override
161     public void visit(CHRQuery query) {
162         for(int i=query.literals.length-1;i>=0;--i) {
163             visit(query.literals[i]);
164         }
165     }
166     
167     @Override
168     public void visit(CHRRule rule) {
169         super.visit(rule);
170         for(Variable variable : rule.existentialVariables)
171             freeVariables.remove(variable);
172     }
173     
174     @Override
175     public void visit(QExists query) {
176         query.query.accept(this);
177         for(Variable variable : query.variables)
178             freeVariables.remove(variable);
179     }
180     
181     public THashSet<Variable> getFreeVariables() {
182         return freeVariables;
183     }
184 }