]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractCombiner.java
(refs #7375) Replaced collectVars method by a visitor
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / query / QAbstractCombiner.java
1 package org.simantics.scl.compiler.elaboration.query;
2
3 import java.util.Arrays;
4
5 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
6 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
7 import org.simantics.scl.compiler.elaboration.expressions.EApply;
8 import org.simantics.scl.compiler.elaboration.expressions.EVar;
9 import org.simantics.scl.compiler.elaboration.expressions.Expression;
10 import org.simantics.scl.compiler.elaboration.query.pre.QPreExists;
11 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
12 import org.simantics.scl.compiler.errors.Locations;
13
14 public abstract class QAbstractCombiner extends Query {
15     public Query[] queries;
16     
17     public QAbstractCombiner(Query[] queries) {
18         this.queries = queries;
19     }
20     
21     @Override
22     public Query resolve(TranslationContext context) {
23         Query modifiedQuery = handleExistsStatement(context);
24         if(modifiedQuery != null)
25             return modifiedQuery.resolve(context);
26             
27         for(int i=0;i<queries.length;++i)
28             queries[i] = queries[i].resolve(context);
29         return this;
30     }
31     
32     private QPreExists handleExistsStatement(TranslationContext context) {
33         if(queries.length == 0)
34             return null;
35         if(!(queries[0] instanceof QPreGuard))
36             return null;
37         Expression exp = ((QPreGuard)queries[0]).guard;
38         if(!(exp instanceof EApply))
39             return null;
40         EApply apply = (EApply)exp;
41         if(!(apply.getFunction() instanceof EVar))
42             return null;
43         if(!((EVar)apply.getFunction()).name.equals("exists"))
44             return null;
45         
46         queries = Arrays.copyOfRange(queries, 1, queries.length);
47         
48         Expression[] pars = apply.getParameters();
49         String[] variableNames = new String[pars.length];
50         for(int i=0;i<pars.length;++i) {
51             if(pars[i] instanceof EVar)
52                 variableNames[i] = ((EVar)pars[i]).name;
53             else {
54                 context.getErrorLog().log(pars[i].getLocation(), "Exists statement may only contain variables as parameters.");
55                 return null;
56             }
57         }
58         return new QPreExists(variableNames, this);
59     }
60
61     @Override
62     public void checkType(TypingContext context) {
63         for(Query query : queries)
64             query.checkType(context);
65     }
66     
67     @Override
68     public void setLocationDeep(long loc) {
69         if(location == Locations.NO_LOCATION) {
70             location = loc;
71             for(Query query : queries)
72                 query.setLocationDeep(loc);
73         }
74     }
75 }