1 package org.simantics.scl.compiler.elaboration.expressions.visitors;
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;
26 import gnu.trove.set.hash.THashSet;
28 public class CollectFreeVariablesVisitor extends StandardExpressionVisitor {
29 private THashSet<Variable> freeVariables = new THashSet<Variable>();
31 private StandardExpressionVisitor collectBoundVariablesVisitor = new StandardExpressionVisitor() {
33 public void visit(EVariable expression) {
34 if(expression.variable != null)
35 freeVariables.remove(expression.variable);
40 public void visit(EAsPattern expression) {
41 freeVariables.remove(expression.var);
42 expression.pattern.accept(this);
46 public void visit(EViewPattern expression) {
47 expression.expression.accept(CollectFreeVariablesVisitor.this);
48 expression.pattern.accept(this);
53 public void visit(EVariable expression) {
54 if(expression.variable != null)
55 freeVariables.add(expression.variable);
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);
68 public void visit(Assignment assignment) {
69 assignment.value.accept(this);
70 assignment.pattern.accept(collectBoundVariablesVisitor);
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]);
81 public void visit(Case case_) {
82 case_.value.accept(this);
83 for(Expression pattern : case_.patterns)
84 pattern.accept(collectBoundVariablesVisitor);
88 public void visit(ESimpleLambda expression) {
89 expression.value.accept(this);
90 freeVariables.remove(expression.parameter);
94 public void visit(ESimpleLet expression) {
95 expression.in.accept(this);
96 expression.value.accept(this);
97 freeVariables.remove(expression.variable);
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);
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);
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);
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);
134 public void visit(ListGenerator qualifier) {
135 qualifier.pattern.accept(collectBoundVariablesVisitor);
136 qualifier.value.accept(this);
140 public void visit(ListAssignment qualifier) {
141 qualifier.pattern.accept(collectBoundVariablesVisitor);
142 qualifier.value.accept(this);
146 public void visit(CHRLiteral literal) {
147 if(literal.relation == SpecialCHRRelation.ASSIGN) {
148 literal.parameters[0].accept(collectBoundVariablesVisitor);
149 literal.parameters[1].accept(this);
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);
161 public void visit(CHRQuery query) {
162 for(int i=query.literals.length-1;i>=0;--i) {
163 visit(query.literals[i]);
168 public void visit(CHRRule rule) {
170 for(Variable variable : rule.existentialVariables)
171 freeVariables.remove(variable);
175 public void visit(QExists query) {
176 query.query.accept(this);
177 for(Variable variable : query.variables)
178 freeVariables.remove(variable);
181 public THashSet<Variable> getFreeVariables() {
182 return freeVariables;