1 package org.simantics.scl.compiler.elaboration.query;
3 import java.util.Arrays;
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;
16 import gnu.trove.map.hash.TObjectIntHashMap;
17 import gnu.trove.set.hash.THashSet;
18 import gnu.trove.set.hash.TIntHashSet;
20 public abstract class QAbstractCombiner extends Query {
21 public Query[] queries;
23 public QAbstractCombiner(Query[] queries) {
24 this.queries = queries;
27 public void collectFreeVariables(THashSet<Variable> vars) {
28 for(Query query : queries)
29 query.collectFreeVariables(vars);
33 public Query resolve(TranslationContext context) {
34 Query modifiedQuery = handleExistsStatement(context);
35 if(modifiedQuery != null)
36 return modifiedQuery.resolve(context);
38 for(int i=0;i<queries.length;++i)
39 queries[i] = queries[i].resolve(context);
43 private QPreExists handleExistsStatement(TranslationContext context) {
44 if(queries.length == 0)
46 if(!(queries[0] instanceof QPreGuard))
48 Expression exp = ((QPreGuard)queries[0]).guard;
49 if(!(exp instanceof EApply))
51 EApply apply = (EApply)exp;
52 if(!(apply.getFunction() instanceof EVar))
54 if(!((EVar)apply.getFunction()).name.equals("exists"))
57 queries = Arrays.copyOfRange(queries, 1, queries.length);
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;
65 context.getErrorLog().log(pars[i].getLocation(), "Exists statement may only contain variables as parameters.");
69 return new QPreExists(variableNames, this);
73 public void checkType(TypingContext context) {
74 for(Query query : queries)
75 query.checkType(context);
79 public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
80 for(Query query : queries)
81 query.collectRefs(allRefs, refs);
85 public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
86 for(Query query : queries)
87 query.collectVars(allVars, vars);
91 public void setLocationDeep(long loc) {
92 if(location == Locations.NO_LOCATION) {
94 for(Query query : queries)
95 query.setLocationDeep(loc);
100 public void forVariables(VariableProcedure procedure) {
101 for(Query query : queries)
102 query.forVariables(procedure);