X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Felaboration%2Fquery%2FQuery.java;fp=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Felaboration%2Fquery%2FQuery.java;h=5154495f5472dcdcb1b2e326673c6e9e3d9f3958;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git 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 index 000000000..5154495f5 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/Query.java @@ -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 vars); + public abstract void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs); + public abstract void collectVars(TObjectIntHashMap 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> NO_DERIVATE = new TIntObjectHashMap>(); + + 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 diffables) throws DerivateException { + throw new DerivateException(location); + } + + public static final QDisjunction EMPTY_QUERY = new QDisjunction(); + + public Query removeRelations(Set 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 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> splitToPhases() { + TIntObjectHashMap> result = new TIntObjectHashMap>(2); + splitToPhases(result); + return result; + } + + public void splitToPhases(TIntObjectHashMap> 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); +}