]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractCombiner.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / query / QAbstractCombiner.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractCombiner.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractCombiner.java
new file mode 100644 (file)
index 0000000..0fc36b6
--- /dev/null
@@ -0,0 +1,105 @@
+package org.simantics.scl.compiler.elaboration.query;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+import java.util.Arrays;
+
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
+import org.simantics.scl.compiler.elaboration.expressions.EApply;
+import org.simantics.scl.compiler.elaboration.expressions.EVar;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
+import org.simantics.scl.compiler.elaboration.query.pre.QPreExists;
+import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.types.Type;
+
+public abstract class QAbstractCombiner extends Query {
+    public Query[] queries;
+    
+    public QAbstractCombiner(Query[] queries) {
+        this.queries = queries;
+    }
+
+    public void collectFreeVariables(THashSet<Variable> vars) {
+        for(Query query : queries)
+            query.collectFreeVariables(vars);
+    }
+    
+    @Override
+    public Query resolve(TranslationContext context) {
+        Query modifiedQuery = handleExistsStatement(context);
+        if(modifiedQuery != null)
+            return modifiedQuery.resolve(context);
+            
+        for(int i=0;i<queries.length;++i)
+            queries[i] = queries[i].resolve(context);
+        return this;
+    }
+    
+    private QPreExists handleExistsStatement(TranslationContext context) {
+        if(queries.length == 0)
+            return null;
+        if(!(queries[0] instanceof QPreGuard))
+            return null;
+        Expression exp = ((QPreGuard)queries[0]).guard;
+        if(!(exp instanceof EApply))
+            return null;
+        EApply apply = (EApply)exp;
+        if(!(apply.getFunction() instanceof EVar))
+            return null;
+        if(!((EVar)apply.getFunction()).name.equals("exists"))
+            return null;
+        
+        queries = Arrays.copyOfRange(queries, 1, queries.length);
+        
+        Expression[] pars = apply.getParameters();
+        String[] variableNames = new String[pars.length];
+        for(int i=0;i<pars.length;++i) {
+            if(pars[i] instanceof EVar)
+                variableNames[i] = ((EVar)pars[i]).name;
+            else {
+                context.getErrorLog().log(pars[i].getLocation(), "Exists statement may only contain variables as parameters.");
+                return null;
+            }
+        }
+        return new QPreExists(variableNames, this);
+    }
+
+    @Override
+    public void checkType(TypingContext context) {
+        for(Query query : queries)
+            query.checkType(context);
+    }
+    
+    @Override
+    public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
+        for(Query query : queries)
+            query.collectRefs(allRefs, refs);
+    }
+    
+    @Override
+    public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
+        for(Query query : queries)
+            query.collectVars(allVars, vars);
+    }
+    
+    @Override
+    public void setLocationDeep(long loc) {
+        if(location == Locations.NO_LOCATION) {
+            location = loc;
+            for(Query query : queries)
+                query.setLocationDeep(loc);
+        }
+    }
+    
+    @Override
+    public void forVariables(VariableProcedure procedure) {
+        for(Query query : queries)
+            query.forVariables(procedure);
+    }
+}