(refs #7375) Replaced collectFreeVariables method by a visitor
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / visitors / StandardExpressionTransformer.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.CHRRuleset;
7 import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstAtom;
8 import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstBinds;
9 import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstConjunction;
10 import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstEquals;
11 import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstNegation;
12 import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery;
13 import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQueryVisitor;
14 import org.simantics.scl.compiler.elaboration.equation.EqBasic;
15 import org.simantics.scl.compiler.elaboration.equation.EqGuard;
16 import org.simantics.scl.compiler.elaboration.equation.Equation;
17 import org.simantics.scl.compiler.elaboration.equation.EquationVisitor;
18 import org.simantics.scl.compiler.elaboration.expressions.Assignment;
19 import org.simantics.scl.compiler.elaboration.expressions.Case;
20 import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous;
21 import org.simantics.scl.compiler.elaboration.expressions.EApply;
22 import org.simantics.scl.compiler.elaboration.expressions.EApplyType;
23 import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
24 import org.simantics.scl.compiler.elaboration.expressions.EBinary;
25 import org.simantics.scl.compiler.elaboration.expressions.EBinaryRightSide;
26 import org.simantics.scl.compiler.elaboration.expressions.EBind;
27 import org.simantics.scl.compiler.elaboration.expressions.EBlock;
28 import org.simantics.scl.compiler.elaboration.expressions.ECHRRuleset;
29 import org.simantics.scl.compiler.elaboration.expressions.ECHRRulesetConstructor;
30 import org.simantics.scl.compiler.elaboration.expressions.ECHRSelect;
31 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
32 import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;
33 import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
34 import org.simantics.scl.compiler.elaboration.expressions.EEquations;
35 import org.simantics.scl.compiler.elaboration.expressions.EError;
36 import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
37 import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
38 import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint;
39 import org.simantics.scl.compiler.elaboration.expressions.EIf;
40 import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
41 import org.simantics.scl.compiler.elaboration.expressions.ELambda;
42 import org.simantics.scl.compiler.elaboration.expressions.ELambdaType;
43 import org.simantics.scl.compiler.elaboration.expressions.ELet;
44 import org.simantics.scl.compiler.elaboration.expressions.EListComprehension;
45 import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
46 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
47 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
48 import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder;
49 import org.simantics.scl.compiler.elaboration.expressions.EPreLet;
50 import org.simantics.scl.compiler.elaboration.expressions.EPreRuleset;
51 import org.simantics.scl.compiler.elaboration.expressions.ERange;
52 import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
53 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
54 import org.simantics.scl.compiler.elaboration.expressions.ERuleset;
55 import org.simantics.scl.compiler.elaboration.expressions.ESelect;
56 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
57 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet;
58 import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral;
59 import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
60 import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;
61 import org.simantics.scl.compiler.elaboration.expressions.EVar;
62 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
63 import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
64 import org.simantics.scl.compiler.elaboration.expressions.EWhen;
65 import org.simantics.scl.compiler.elaboration.expressions.Expression;
66 import org.simantics.scl.compiler.elaboration.expressions.ExpressionTransformer;
67 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
68 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
69 import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer;
70 import org.simantics.scl.compiler.elaboration.expressions.accessor.ExpressionAccessor;
71 import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement;
72 import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement;
73 import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
74 import org.simantics.scl.compiler.elaboration.expressions.block.IncludeStatement;
75 import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
76 import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;
77 import org.simantics.scl.compiler.elaboration.expressions.block.Statement;
78 import org.simantics.scl.compiler.elaboration.expressions.block.StatementVisitor;
79 import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
80 import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
81 import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard;
82 import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
83 import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifierTransformer;
84 import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq;
85 import org.simantics.scl.compiler.elaboration.expressions.list.ListThen;
86 import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
87 import org.simantics.scl.compiler.elaboration.query.QAlternative;
88 import org.simantics.scl.compiler.elaboration.query.QAtom;
89 import org.simantics.scl.compiler.elaboration.query.QConjunction;
90 import org.simantics.scl.compiler.elaboration.query.QDisjunction;
91 import org.simantics.scl.compiler.elaboration.query.QExists;
92 import org.simantics.scl.compiler.elaboration.query.QIf;
93 import org.simantics.scl.compiler.elaboration.query.QMapping;
94 import org.simantics.scl.compiler.elaboration.query.QNegation;
95 import org.simantics.scl.compiler.elaboration.query.Query;
96 import org.simantics.scl.compiler.elaboration.query.pre.QPreBinds;
97 import org.simantics.scl.compiler.elaboration.query.pre.QPreEquals;
98 import org.simantics.scl.compiler.elaboration.query.pre.QPreExists;
99 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
100
101 public class StandardExpressionTransformer implements
102 ExpressionTransformer, QueryTransformer, ListQualifierTransformer, StatementVisitor,
103 EquationVisitor, CHRAstQueryVisitor {
104
105     @Override
106     public Expression transform(EAmbiguous expression) {
107         if(expression.resolvedExpression != null)
108             expression.resolvedExpression = expression.resolvedExpression.accept(this);
109         return expression;
110     }
111
112     @Override
113     public Expression transform(EApply expression) {
114         expression.function = expression.function.accept(this);
115         for(int i=0;i<expression.parameters.length;++i)
116             expression.parameters[i] = expression.parameters[i].accept(this);
117         return expression;
118     }
119
120     @Override
121     public Expression transform(EApplyType expression) {
122         expression.expression = expression.expression.accept(this);
123         return expression;
124     }
125
126     @Override
127     public Expression transform(EAsPattern expression) {
128         expression.pattern = expression.pattern.accept(this);
129         return expression;
130     }
131
132     @Override
133     public Expression transform(EBinary expression) {
134         expression.left = expression.left.accept(this);
135         for(EBinaryRightSide rs : expression.rights)
136             rs.right = rs.right.accept(this);
137         return expression;
138     }
139
140     @Override
141     public Expression transform(EBind expression) {
142         expression.pattern = expression.pattern.accept(this);
143         expression.value = expression.value.accept(this);
144         expression.in = expression.in.accept(this);
145         return expression;
146     }
147
148     @Override
149     public Expression transform(EViewPattern expression) {
150         expression.expression = expression.expression.accept(this);
151         expression.pattern = expression.pattern.accept(this);
152         return expression;
153     }
154     
155     @Override
156     public Expression transform(EBlock expression) {
157         for(Statement statement : expression.statements)
158             statement.accept(this);
159         return expression;
160     }
161     
162     @Override
163     public void visit(BindStatement statement) {
164         statement.pattern = statement.pattern.accept(this);
165         statement.value = statement.value.accept(this);
166     }
167     
168     @Override
169     public void visit(GuardStatement statement) {
170         statement.value = statement.value.accept(this);        
171     }
172     
173     @Override
174     public void visit(LetStatement statement) {
175         statement.pattern = statement.pattern.accept(this);
176         statement.value = statement.value.accept(this);
177     }
178     
179     @Override
180     public void visit(RuleStatement statement) {
181         statement.head = statement.head.accept(this);
182         statement.body = statement.body.accept(this);
183     }
184
185     @Override
186     public void visit(IncludeStatement statement) {
187         statement.value = statement.value.accept(this);
188     }
189     
190     public void transform(CHRQuery query) {
191         for(CHRLiteral lit : query.literals)
192             for(int i=0;i<lit.parameters.length;++i)
193                 lit.parameters[i] = lit.parameters[i].accept(this);
194     }
195     
196     public void transform(CHRRuleset ruleset) {
197         for(CHRRule rule : ruleset.rules) {
198             transform(rule.head);
199             transform(rule.body);
200         }
201     }
202     
203     @Override
204     public Expression transform(ECHRRuleset expression) {
205         expression.in = expression.in.accept(this);
206         transform(expression.ruleset);
207         return expression;
208     }
209     
210     @Override
211     public Expression transform(ECHRSelect expression) {
212         expression.expression = expression.expression.accept(this);
213         transform(expression.query);
214         return expression;
215     }
216     
217     @Override
218     public Expression transform(ECHRRulesetConstructor expression) {
219         transform(expression.ruleset);
220         return expression;
221     }
222
223     @Override
224     public Expression transform(EConstant expression) {
225         return expression;
226     }
227
228     @Override
229     public Expression transform(EEnforce expression) {
230         expression.query = expression.query.accept(this);
231         return expression;
232     }
233
234     @Override
235     public Expression transform(EError expression) {
236         return expression;
237     }
238
239     @Override
240     public Expression transform(EExternalConstant expression) {
241         return expression;
242     }
243
244     @Override
245     public Expression transform(EFieldAccess expression) {
246         expression.parent = expression.parent.accept(this);
247         if(expression.accessor instanceof ExpressionAccessor) {
248                 ExpressionAccessor expAcc = (ExpressionAccessor)expression.accessor;
249                 expAcc.fieldName = expAcc.fieldName.accept(this);
250         }
251         return expression;
252     }
253
254     @Override
255     public Expression transform(EGetConstraint expression) {
256         return expression;
257     }
258
259     @Override
260     public Expression transform(EIf expression) {
261         expression.condition = expression.condition.accept(this);
262         expression.then_ = expression.then_.accept(this);
263         if(expression.else_ != null)
264             expression.else_ = expression.else_.accept(this);
265         return expression;
266     }
267
268     @Override
269     public Expression transform(EIntegerLiteral expression) {
270         return expression;
271     }
272
273     protected void transformCases(Case[] cases) {
274         for(Case case_ : cases) {
275             for(int i=0;i<case_.patterns.length;++i)
276                 case_.patterns[i] = case_.patterns[i].accept(this);
277             case_.value = case_.value.accept(this);
278         }
279     }
280     
281     @Override
282     public Expression transform(ELambda expression) {
283         transformCases(expression.cases);
284         return expression;
285     }
286
287     @Override
288     public Expression transform(ELambdaType expression) {
289         expression.value = expression.value.accept(this);
290         return expression;
291     }
292
293     @Override
294     public Expression transform(ELet expression) {
295         expression.in = expression.in.accept(this);
296         for(Assignment assign : expression.assignments) {
297             assign.pattern = assign.pattern.accept(this);
298             assign.value = assign.value.accept(this);
299         }
300         return expression;
301     }
302
303     @Override
304     public Expression transform(EListComprehension expression) {
305         expression.head = expression.head.accept(this);
306         expression.qualifier =  expression.qualifier.accept(this);
307         return expression;
308     }
309
310     @Override
311     public Expression transform(EListLiteral expression) {
312         for(int i=0;i<expression.components.length;++i)
313             expression.components[i] = expression.components[i].accept(this);
314         return expression;
315     }
316
317     @Override
318     public Expression transform(ELiteral expression) {
319         return expression;
320     }
321
322     @Override
323     public Expression transform(EMatch expression) {
324         for(int i=0;i<expression.scrutinee.length;++i)
325             expression.scrutinee[i] = expression.scrutinee[i].accept(this);
326         transformCases(expression.cases);
327         return expression;
328     }
329
330     @Override
331     public Expression transform(EPlaceholder expression) {
332         expression.expression = expression.expression.accept(this);
333         return expression;
334     }
335
336     @Override
337     public Expression transform(EPreLet expression) {
338         for(LetStatement statement : expression.assignments) {
339             statement.pattern = statement.pattern.accept(this);
340             statement.value = statement.value.accept(this);
341         }
342         expression.in = expression.in.accept(this);
343         return expression;
344     }
345
346     @Override
347     public Expression transform(EPreRuleset expression) {
348         for(RuleStatement rule : expression.statements) {
349             rule.body = rule.body.accept(this);
350             rule.head = rule.head.accept(this);
351         }
352         expression.in = expression.in.accept(this);
353         return expression;
354     }
355
356     @Override
357     public Expression transform(ECoveringBranchPoint expression) {
358         expression.expression = expression.expression.accept(this);
359         return expression;
360     }
361
362     @Override
363     public Expression transform(ERange expression) {
364         expression.from = expression.from.accept(this);
365         expression.to = expression.to.accept(this);
366         return expression;
367     }
368
369     @Override
370     public Expression transform(ERealLiteral expression) {
371         return expression;
372     }
373
374     @Override
375     public Expression transform(ERecord expression) {
376         for(FieldAssignment field : expression.fields)
377             if(field.value != null)
378                 field.value = field.value.accept(this);
379         return expression;
380     }
381
382     @Override
383     public Expression transform(ERuleset expression) {
384         for(ERuleset.DatalogRule rule : expression.rules) {
385             rule.body = rule.body.accept(this);
386             for(int i=0;i<rule.headParameters.length;++i)
387                 rule.headParameters[i] = rule.headParameters[i].accept(this);
388         }
389         expression.in = expression.in.accept(this);
390         return expression;
391     }
392
393     @Override
394     public Expression transform(ESelect expression) {
395         expression.query = expression.query.accept(this);
396         expression.expression = expression.expression.accept(this);
397         return expression;
398     }
399
400     @Override
401     public Expression transform(ESimpleLambda expression) {
402         expression.value = expression.value.accept(this);
403         return expression;
404     }
405
406     @Override
407     public Expression transform(ESimpleLet expression) {
408         expression.value = expression.value.accept(this);
409         expression.in = expression.in.accept(this);
410         return expression;
411     }
412
413     @Override
414     public Expression transform(EStringLiteral expression) {
415         return expression;
416     }
417
418     @Override
419     public Expression transform(ETransformation expression) {
420         expression.seed = expression.seed.accept(this);
421         return expression;
422     }
423
424     @Override
425     public Expression transform(ETypeAnnotation expression) {
426         expression.value = expression.value.accept(this);
427         return expression;
428     }
429
430     @Override
431     public Expression transform(EVar expression) {
432         return expression;
433     }
434
435     @Override
436     public Expression transform(EVariable expression) {
437         return expression;
438     }
439
440     @Override
441     public Expression transform(EWhen expression) {
442         expression.query = expression.query.accept(this);
443         expression.action = expression.action.accept(this);
444         return expression;
445     }
446
447     @Override
448     public Expression transform(GuardedExpressionGroup expression) {
449         for(GuardedExpression ge : expression.expressions) {
450             for(int i=0;i<ge.guards.length;++i)
451                 ge.guards[i] = ge.guards[i].accept(this);
452             ge.value = ge.value.accept(this);
453         }
454         return expression;
455     }
456
457     @Override
458     public ListQualifier transform(ListAssignment qualifier) {
459         qualifier.pattern = qualifier.pattern.accept(this);
460         qualifier.value = qualifier.value.accept(this);
461         return qualifier;
462     }
463
464     @Override
465     public ListQualifier transform(ListGenerator qualifier) {
466         qualifier.pattern = qualifier.pattern.accept(this);
467         qualifier.value = qualifier.value.accept(this);
468         return qualifier;
469     }
470
471     @Override
472     public ListQualifier transform(ListGuard qualifier) {
473         qualifier.condition = qualifier.condition.accept(this);
474         return qualifier;
475     }
476
477     @Override
478     public ListQualifier transform(ListSeq qualifier) {
479         qualifier.a = qualifier.a.accept(this);
480         qualifier.b = qualifier.b.accept(this);
481         return qualifier;
482     }
483
484     @Override
485     public ListQualifier transform(ListThen qualifier) {
486         qualifier.left = qualifier.left.accept(this);
487         qualifier.transformer = qualifier.transformer.accept(this);
488         if(qualifier.by != null)
489             qualifier.by = qualifier.by.accept(this);
490         return qualifier;
491     }
492
493     @Override
494     public Query transform(QAlternative query) {
495         for(int i=0;i<query.queries.length;++i)
496             query.queries[i] = query.queries[i].accept(this);
497         return query;
498     }
499
500     @Override
501     public Query transform(QAtom query) {
502         for(int i=0;i<query.parameters.length;++i)
503             query.parameters[i] = query.parameters[i].accept(this);
504         return query;
505     }
506
507     @Override
508     public Query transform(QConjunction query) {
509         for(int i=0;i<query.queries.length;++i)
510             query.queries[i] = query.queries[i].accept(this);
511         return query;
512     }
513
514     @Override
515     public Query transform(QDisjunction query) {
516         for(int i=0;i<query.queries.length;++i)
517             query.queries[i] = query.queries[i].accept(this);
518         return query;
519     }
520
521     @Override
522     public Query transform(QExists query) {
523         query.query = query.query.accept(this);
524         return query;
525     }
526
527     @Override
528     public Query transform(QIf query) {
529         query.condition = query.condition.accept(this);
530         query.thenQuery = query.thenQuery.accept(this);
531         query.elseQuery = query.elseQuery.accept(this);
532         return query;
533     }
534
535     @Override
536     public Query transform(QMapping query) {
537         for(int i=0;i<query.parameters.length;++i)
538             query.parameters[i] = query.parameters[i].accept(this);
539         return query;
540     }
541
542     @Override
543     public Query transform(QNegation query) {
544         query.query = query.query.accept(this);
545         return query;
546     }
547
548     @Override
549     public Query transform(QPreBinds query) {
550         query.left = query.left.accept(this);
551         query.right = query.right.accept(this);
552         return query;
553     }
554
555     @Override
556     public Query transform(QPreEquals query) {
557         query.left = query.left.accept(this);
558         query.right = query.right.accept(this);
559         return query;
560     }
561
562     @Override
563     public Query transform(QPreExists query) {
564         query.query = query.query.accept(this);
565         return query;
566     }
567
568     @Override
569     public Query transform(QPreGuard query) {
570         query.guard = query.guard.accept(this);
571         return query;
572     }
573
574     @Override
575     public Expression transform(EEquations expression) {
576         for(Equation equation : expression.equations)
577             equation.accept(this);
578         return expression;
579     }
580
581     @Override
582     public void visit(EqBasic equation) {
583         equation.left =  equation.left.accept(this);
584         equation.right = equation.right.accept(this);
585     }
586
587     @Override
588     public void visit(EqGuard equation) {
589         equation.guard =  equation.guard.accept(this);
590     }
591
592     @Override
593     public void visit(CHRStatement statement) {
594         statement.head.accept(this);
595         statement.body.accept(this);
596     }
597
598     @Override
599     public void visit(CHRAstAtom query) {
600         query.expression = query.expression.accept(this);
601     }
602
603     @Override
604     public void visit(CHRAstBinds query) {
605         query.left = query.left.accept(this);
606         query.right = query.right.accept(this);
607     }
608
609     @Override
610     public void visit(CHRAstConjunction query) {
611         for(CHRAstQuery conjunct : query.conjuncts)
612             conjunct.accept(this);
613     }
614
615     @Override
616     public void visit(CHRAstEquals query) {
617         query.left = query.left.accept(this);
618         query.right = query.right.accept(this);
619     }
620
621     @Override
622     public void visit(CHRAstNegation query) {
623         query.subquery.accept(this);
624     }
625
626 }