]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractCombiner.java
migrated to svn revision 33108
[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.expressions.Variable;
11 import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
12 import org.simantics.scl.compiler.elaboration.query.pre.QPreExists;
13 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
14 import org.simantics.scl.compiler.errors.Locations;
15
16 import gnu.trove.map.hash.TObjectIntHashMap;
17 import gnu.trove.set.hash.THashSet;
18 import gnu.trove.set.hash.TIntHashSet;
19
20 public abstract class QAbstractCombiner extends Query {
21     public Query[] queries;
22     
23     public QAbstractCombiner(Query[] queries) {
24         this.queries = queries;
25     }
26
27     public void collectFreeVariables(THashSet<Variable> vars) {
28         for(Query query : queries)
29             query.collectFreeVariables(vars);
30     }
31     
32     @Override
33     public Query resolve(TranslationContext context) {
34         Query modifiedQuery = handleExistsStatement(context);
35         if(modifiedQuery != null)
36             return modifiedQuery.resolve(context);
37             
38         for(int i=0;i<queries.length;++i)
39             queries[i] = queries[i].resolve(context);
40         return this;
41     }
42     
43     private QPreExists handleExistsStatement(TranslationContext context) {
44         if(queries.length == 0)
45             return null;
46         if(!(queries[0] instanceof QPreGuard))
47             return null;
48         Expression exp = ((QPreGuard)queries[0]).guard;
49         if(!(exp instanceof EApply))
50             return null;
51         EApply apply = (EApply)exp;
52         if(!(apply.getFunction() instanceof EVar))
53             return null;
54         if(!((EVar)apply.getFunction()).name.equals("exists"))
55             return null;
56         
57         queries = Arrays.copyOfRange(queries, 1, queries.length);
58         
59         Expression[] pars = apply.getParameters();
60         String[] variableNames = new String[pars.length];
61         for(int i=0;i<pars.length;++i) {
62             if(pars[i] instanceof EVar)
63                 variableNames[i] = ((EVar)pars[i]).name;
64             else {
65                 context.getErrorLog().log(pars[i].getLocation(), "Exists statement may only contain variables as parameters.");
66                 return null;
67             }
68         }
69         return new QPreExists(variableNames, this);
70     }
71
72     @Override
73     public void checkType(TypingContext context) {
74         for(Query query : queries)
75             query.checkType(context);
76     }
77     
78     @Override
79     public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
80         for(Query query : queries)
81             query.collectRefs(allRefs, refs);
82     }
83     
84     @Override
85     public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
86         for(Query query : queries)
87             query.collectVars(allVars, vars);
88     }
89     
90     @Override
91     public void setLocationDeep(long loc) {
92         if(location == Locations.NO_LOCATION) {
93             location = loc;
94             for(Query query : queries)
95                 query.setLocationDeep(loc);
96         }
97     }
98     
99     @Override
100     public void forVariables(VariableProcedure procedure) {
101         for(Query query : queries)
102             query.forVariables(procedure);
103     }
104 }