1 package org.simantics.scl.compiler.elaboration.query;
3 import gnu.trove.map.hash.TObjectIntHashMap;
4 import gnu.trove.set.hash.THashSet;
5 import gnu.trove.set.hash.TIntHashSet;
7 import java.util.Arrays;
9 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
10 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
11 import org.simantics.scl.compiler.elaboration.expressions.EApply;
12 import org.simantics.scl.compiler.elaboration.expressions.EVar;
13 import org.simantics.scl.compiler.elaboration.expressions.Expression;
14 import org.simantics.scl.compiler.elaboration.expressions.Variable;
15 import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
16 import org.simantics.scl.compiler.elaboration.query.pre.QPreExists;
17 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
18 import org.simantics.scl.compiler.errors.Locations;
19 import org.simantics.scl.compiler.types.Type;
21 public abstract class QAbstractCombiner extends Query {
22 public Query[] queries;
24 public QAbstractCombiner(Query[] queries) {
25 this.queries = queries;
28 public void collectFreeVariables(THashSet<Variable> vars) {
29 for(Query query : queries)
30 query.collectFreeVariables(vars);
34 public Query resolve(TranslationContext context) {
35 Query modifiedQuery = handleExistsStatement(context);
36 if(modifiedQuery != null)
37 return modifiedQuery.resolve(context);
39 for(int i=0;i<queries.length;++i)
40 queries[i] = queries[i].resolve(context);
44 private QPreExists handleExistsStatement(TranslationContext context) {
45 if(queries.length == 0)
47 if(!(queries[0] instanceof QPreGuard))
49 Expression exp = ((QPreGuard)queries[0]).guard;
50 if(!(exp instanceof EApply))
52 EApply apply = (EApply)exp;
53 if(!(apply.getFunction() instanceof EVar))
55 if(!((EVar)apply.getFunction()).name.equals("exists"))
58 queries = Arrays.copyOfRange(queries, 1, queries.length);
60 Expression[] pars = apply.getParameters();
61 String[] variableNames = new String[pars.length];
62 for(int i=0;i<pars.length;++i) {
63 if(pars[i] instanceof EVar)
64 variableNames[i] = ((EVar)pars[i]).name;
66 context.getErrorLog().log(pars[i].getLocation(), "Exists statement may only contain variables as parameters.");
70 return new QPreExists(variableNames, this);
74 public void checkType(TypingContext context) {
75 for(Query query : queries)
76 query.checkType(context);
80 public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
81 for(Query query : queries)
82 query.collectRefs(allRefs, refs);
86 public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
87 for(Query query : queries)
88 query.collectVars(allVars, vars);
92 public void setLocationDeep(long loc) {
93 if(location == Locations.NO_LOCATION) {
95 for(Query query : queries)
96 query.setLocationDeep(loc);
101 public void forVariables(VariableProcedure procedure) {
102 for(Query query : queries)
103 query.forVariables(procedure);