]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRQuery.java
Warn for existential variables in head pattern referred only once
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / chr / CHRQuery.java
index c7ac33d889f208dade23dee4d78daee3d500b963..6b01d99531f9d30db25fe0277e0f98d435632729 100644 (file)
@@ -1,15 +1,20 @@
 package org.simantics.scl.compiler.elaboration.chr;
 
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.elaboration.chr.plan.PostCommitOp;
 import org.simantics.scl.compiler.elaboration.chr.plan.PreCommitOp;
 import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;
 import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.expressions.ExpressionVisitor;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
 import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.ForVariablesUsesVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.StandardExpressionVisitor;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.parsing.Symbol;
 
@@ -19,8 +24,9 @@ import gnu.trove.set.hash.TIntHashSet;
 public class CHRQuery extends Symbol {
     public CHRLiteral[] literals;
 
-    public CHRQuery(CHRLiteral[] literals) {
+    public CHRQuery(long location, CHRLiteral[] literals) {
         this.literals = literals;
+        this.location = location;
     }
 
     public void resolve(TranslationContext context) {
@@ -47,17 +53,21 @@ public class CHRQuery extends Symbol {
     }
     
     public boolean createQueryPlan(QueryPlanningContext context, Expression inputFact, int activeLiteralId, CHRConstraint initConstraint) {
-        for(int i=0;i<literals.length;++i) {
-            CHRLiteral literal = literals[i];
-            if(i == activeLiteralId)
-                context.activate(literal, inputFact, i);
-            else
-                context.add(literal, i);
+        try {
+            for(int i=0;i<literals.length;++i) {
+                CHRLiteral literal = literals[i];
+                if(i == activeLiteralId)
+                    context.activate(literal, inputFact, i);
+                else
+                    context.add(literal, i);
+            }
+            if(activeLiteralId == -1 && inputFact != null) {
+                context.addInitFact(initConstraint, inputFact);
+            }  
+            return context.createQueryPlan();
+        } catch(Exception e) {
+            throw InternalCompilerError.injectLocation(location, e);
         }
-        if(activeLiteralId == -1 && inputFact != null) {
-            context.addInitFact(initConstraint, inputFact);
-        }      
-        return context.createQueryPlan();
     }
     
     public void simplify(SimplificationContext context) {
@@ -78,4 +88,23 @@ public class CHRQuery extends Symbol {
         visitor.visit(this);
         return b.toString();
     }
+
+    public CHRQuery replace(ReplaceContext context) {
+        CHRLiteral[] newLiterals = new CHRLiteral[literals.length];
+        for(int i=0;i<literals.length;++i)
+            newLiterals[i] = literals[i].replace(context);
+        return new CHRQuery(location, newLiterals);
+    }
+    
+    public void accept(ExpressionVisitor visitor) {
+        for(CHRLiteral literal : literals) {
+            if(literal == null || literal.parameters == null)
+                continue; // FIXME why this happens?
+            for(Expression parameter : literal.parameters) {
+                if(parameter == null)
+                    continue; // FIXME why this happens?
+                parameter.accept(visitor);
+            }
+        }
+    }
 }