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.query.pre.QPreExists;
12 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
13 import org.simantics.scl.compiler.errors.Locations;
15 import gnu.trove.map.hash.TObjectIntHashMap;
16 import gnu.trove.set.hash.THashSet;
17 import gnu.trove.set.hash.TIntHashSet;
19 public abstract class QAbstractCombiner extends Query {
20 public Query[] queries;
22 public QAbstractCombiner(Query[] queries) {
23 this.queries = queries;
26 public void collectFreeVariables(THashSet<Variable> vars) {
27 for(Query query : queries)
28 query.collectFreeVariables(vars);
32 public Query resolve(TranslationContext context) {
33 Query modifiedQuery = handleExistsStatement(context);
34 if(modifiedQuery != null)
35 return modifiedQuery.resolve(context);
37 for(int i=0;i<queries.length;++i)
38 queries[i] = queries[i].resolve(context);
42 private QPreExists handleExistsStatement(TranslationContext context) {
43 if(queries.length == 0)
45 if(!(queries[0] instanceof QPreGuard))
47 Expression exp = ((QPreGuard)queries[0]).guard;
48 if(!(exp instanceof EApply))
50 EApply apply = (EApply)exp;
51 if(!(apply.getFunction() instanceof EVar))
53 if(!((EVar)apply.getFunction()).name.equals("exists"))
56 queries = Arrays.copyOfRange(queries, 1, queries.length);
58 Expression[] pars = apply.getParameters();
59 String[] variableNames = new String[pars.length];
60 for(int i=0;i<pars.length;++i) {
61 if(pars[i] instanceof EVar)
62 variableNames[i] = ((EVar)pars[i]).name;
64 context.getErrorLog().log(pars[i].getLocation(), "Exists statement may only contain variables as parameters.");
68 return new QPreExists(variableNames, this);
72 public void checkType(TypingContext context) {
73 for(Query query : queries)
74 query.checkType(context);
78 public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
79 for(Query query : queries)
80 query.collectVars(allVars, vars);
84 public void setLocationDeep(long loc) {
85 if(location == Locations.NO_LOCATION) {
87 for(Query query : queries)
88 query.setLocationDeep(loc);