]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/Query.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / query / Query.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/Query.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/Query.java
new file mode 100644 (file)
index 0000000..5154495
--- /dev/null
@@ -0,0 +1,159 @@
+package org.simantics.scl.compiler.elaboration.query;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.map.hash.TIntObjectHashMap;
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+import java.util.ArrayList;
+import java.util.Set;
+
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
+import org.simantics.scl.compiler.elaboration.expressions.EError;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer;
+import org.simantics.scl.compiler.elaboration.expressions.StandardExpressionVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
+import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
+import org.simantics.scl.compiler.elaboration.query.compilation.ConstraintCollectionContext;
+import org.simantics.scl.compiler.elaboration.query.compilation.DerivateException;
+import org.simantics.scl.compiler.elaboration.query.compilation.DynamicProgrammingOrdering;
+import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;
+import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
+import org.simantics.scl.compiler.elaboration.query.compilation.QueryConstraint;
+import org.simantics.scl.compiler.elaboration.query.compilation.UnsolvableQueryException;
+import org.simantics.scl.compiler.elaboration.relations.CompositeRelation;
+import org.simantics.scl.compiler.elaboration.relations.LocalRelation;
+import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
+import org.simantics.scl.compiler.internal.parsing.Symbol;
+
+public abstract class Query extends Symbol {
+    public static final Query[] EMPTY_ARRAY = new Query[0];
+    
+    public abstract void collectFreeVariables(THashSet<Variable> vars);
+    public abstract void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs);
+    public abstract void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars);
+    public abstract void checkType(TypingContext context);
+    
+    public Query resolve(TranslationContext context) {
+        throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support resolve.");
+    }
+    
+    public Expression generateEnforce(EnforcingContext context) {
+        context.getErrorLog().log(location, getClass().getSimpleName() + " does not support enforcing.");
+        return new EError(location);
+    }
+    
+    public abstract void collectConstraints(ConstraintCollectionContext context) throws UnsolvableQueryException;
+    
+    protected QueryConstraint[] getOrderedConstraints(QueryCompilationContext context) throws UnsolvableQueryException {
+        ConstraintCollectionContext collectionContext = new ConstraintCollectionContext(context);
+        collectConstraints(collectionContext);
+        QueryConstraint[] constraints = collectionContext.getConstraints();
+        DynamicProgrammingOrdering.order(collectionContext, constraints, 0L);
+        return constraints;
+    }
+    
+    protected void applyConstraints(QueryCompilationContext context, QueryConstraint[] constraints) {
+        for(int i=constraints.length-1;i>=0;--i)
+            constraints[i].generateAndUpdateCost(context);
+    }
+    
+    public void generate(QueryCompilationContext context) throws UnsolvableQueryException {
+        applyConstraints(context, getOrderedConstraints(context));
+    }
+    
+    protected static final TIntObjectHashMap<ArrayList<Query>> NO_DERIVATE = new TIntObjectHashMap<ArrayList<Query>>();
+    
+    public static class Diffable {
+        public int id;
+        SCLRelation relation;
+        public Variable[] parameters;
+        public Diffable(int id, SCLRelation relation, Variable[] parameters) {
+            this.id = id;
+            this.relation = relation;
+            this.parameters = parameters;
+        }
+    }
+    
+    public static class Diff {
+        public int id;
+        public Query query;
+        
+        public Diff(int id, Query query) {
+            this.id = id;
+            this.query = query;
+        }
+    }
+    
+    public static final Diff[] NO_DIFF = new Diff[0];
+    
+    public Diff[] derivate(THashMap<LocalRelation, Diffable> diffables) throws DerivateException {
+        throw new DerivateException(location);
+    }
+    
+    public static final QDisjunction EMPTY_QUERY = new QDisjunction();
+    
+    public Query removeRelations(Set<SCLRelation> relations) {
+        throw new UnsupportedOperationException();
+    }
+    
+    public Query copy() {
+        return replace(new ReplaceContext(null));
+    }
+    
+    public Query copy(TypingContext context) {
+        return replace(new ReplaceContext(context));
+    }
+    
+    public abstract Query replace(ReplaceContext context);
+
+    public abstract void setLocationDeep(long loc);
+
+    public abstract void accept(QueryVisitor visitor);
+
+    public void collectRelationRefs(
+            final TObjectIntHashMap<SCLRelation> allRefs, final TIntHashSet refs) {
+        accept(new StandardExpressionVisitor() {
+            @Override
+            public void visit(QAtom query) {
+                visit(query.relation);
+            }
+            private void visit(SCLRelation relation) {
+                int id = allRefs.get(relation);
+                if(id >= 0)
+                    refs.add(id);
+                else if(relation instanceof CompositeRelation)
+                    for(SCLRelation subrelation : ((CompositeRelation)relation).getSubrelations())
+                        visit(subrelation);
+            }
+        });
+    }
+    
+    public abstract void forVariables(VariableProcedure procedure);
+    
+    public TIntObjectHashMap<ArrayList<Query>> splitToPhases() {
+        TIntObjectHashMap<ArrayList<Query>> result = new TIntObjectHashMap<ArrayList<Query>>(2);
+        splitToPhases(result);
+        return result;
+    }
+
+    public void splitToPhases(TIntObjectHashMap<ArrayList<Query>> result) {
+        throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support splitToPhases.");
+    }
+    
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder();
+        ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);
+        accept(visitor);
+        return b.toString();
+    }
+    
+    public abstract Query accept(QueryTransformer transformer);
+}