(refs #7371) Support expression cloning for ECHRSelect 84/784/2
authorHannu Niemistö <hannu.niemisto@semantum.fi>
Mon, 31 Jul 2017 15:12:18 +0000 (18:12 +0300)
committerHannu Niemistö <hannu.niemisto@semantum.fi>
Tue, 1 Aug 2017 08:52:40 +0000 (11:52 +0300)
Change-Id: Ie4ea77e03eccc3f59b7c0e27e0528527826df9e4

bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRQuery.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AccessFactOp.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/ReplaceContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRSelect.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/records/FieldAssignment.java

index eb0f48b20414aa35baa74b4bd0fe743f35a7ba8a..e0921dc106fa67f50944ef6ebd9c14c3080972bf 100644 (file)
@@ -5,6 +5,7 @@ import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
 import org.simantics.scl.compiler.elaboration.chr.relations.ExternalCHRRelation;
 import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;
 import org.simantics.scl.compiler.elaboration.chr.relations.UnresolvedCHRRelation;
+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.TranslationContext.ExistentialFrame;
@@ -36,11 +37,11 @@ public class CHRLiteral extends Symbol {
     public boolean negated;
     public boolean passive = true;
     
-    public CHRLiteral(long location, CHRRelation relation, Expression[] parameters, boolean remove, boolean negated) {
+    public CHRLiteral(long location, CHRRelation relation, Expression[] parameters, boolean killAfterMatch, boolean negated) {
         this.location = location;
         this.relation = relation;
         this.parameters = parameters;
-        this.killAfterMatch = remove;
+        this.killAfterMatch = killAfterMatch;
         this.negated = negated;
     }
 
@@ -169,4 +170,15 @@ public class CHRLiteral extends Symbol {
         visitor.visit(this);
         return b.toString();
     }
+
+    public CHRLiteral replace(ReplaceContext context) {
+        CHRLiteral copy = new CHRLiteral(location, relation, context.replace(parameters), killAfterMatch, negated);
+        for(int i=0;i<parameters.length;++i)
+            copy.parameters[i] = copy.parameters[i].replace(context);
+        copy.passive = passive;
+        copy.typeConstraintEvidenceParameters = context.replace(typeConstraintEvidenceParameters);
+        copy.typeParameters = context.replace(typeParameters);
+        copy.fields = context.replace(fields);
+        return copy;
+    }
 }
index c7ac33d889f208dade23dee4d78daee3d500b963..2d97ab51819e4d271cea111e42050878da58c6a2 100644 (file)
@@ -4,6 +4,7 @@ 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;
@@ -78,4 +79,11 @@ 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(newLiterals);
+    }
 }
index 4874c14fe57f4c71533045e8484549f3a11f98cd..ab37d253a50dbcfdf709553a13230f9f1f89fe54 100644 (file)
@@ -47,5 +47,4 @@ public class AccessFactOp extends PlanOp {
         if(end != null)
             end.return_(BooleanConstant.FALSE);
     }
-
 }
index 1bb40c5faa2acb72e3fa0e8f1856767d811c226e..b526cb3f0950d647cc8002661766abe982be87a7 100644 (file)
@@ -3,8 +3,10 @@ package org.simantics.scl.compiler.elaboration.contexts;
 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
 import org.simantics.scl.compiler.types.TVar;
 import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
 
 import gnu.trove.map.hash.THashMap;
 
@@ -37,4 +39,28 @@ public class ReplaceContext {
     public ReplaceContext(TypingContext typingContext) {
         this(new THashMap<TVar, Type>(), new THashMap<Variable, Expression>(), typingContext);
     }
+    
+    public Expression[] replace(Expression[] expressions) {
+        if(expressions == null)
+            return null;
+        Expression[] result = new Expression[expressions.length];
+        for(int i=0;i<expressions.length;++i)
+            result[i] = expressions[i].replace(this);
+        return result;
+    }
+
+    public Type[] replace(Type[] types) {
+        if(types == null)
+            return null;
+        return Types.replace(types, tvarMap);
+    }
+
+    public FieldAssignment[] replace(FieldAssignment[] fields) {
+        if(fields == null)
+            return null;
+        FieldAssignment[] result = new FieldAssignment[fields.length];
+        for(int i=0;i<fields.length;++i)
+            result[i] = fields[i].replace(this);
+        return result;
+    }
 }
index bf3b818f56c01c844b078705751ca1f3d20fd873..db651684f0ee124252abc9adb73721ce05d094be 100644 (file)
@@ -2,6 +2,7 @@ package org.simantics.scl.compiler.elaboration.expressions;
 
 import java.util.ArrayList;
 
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.common.names.Names;
 import org.simantics.scl.compiler.compilation.CompilationContext;
 import org.simantics.scl.compiler.constants.NoRepConstant;
@@ -11,6 +12,7 @@ import org.simantics.scl.compiler.elaboration.chr.plan.PlanContext;
 import org.simantics.scl.compiler.elaboration.chr.plan.PlanOp;
 import org.simantics.scl.compiler.elaboration.chr.plan.PlanRealizer;
 import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;
+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;
@@ -51,17 +53,16 @@ public class ECHRSelect extends Expression {
     public Expression simplify(SimplificationContext simplificationContext) {
         this.expression = expression.simplify(simplificationContext);
         query.simplify(simplificationContext);
-        
-        CompilationContext compilationContext = simplificationContext.getCompilationContext();
-        QueryPlanningContext context = new QueryPlanningContext(compilationContext, existentialVariables);
-        if(query.createQueryPlan(context, null, -1, null))
-            planOps = context.getPlanOps();
 
         return this;
     }
     
     @Override
     public IVal toVal(CompilationContext context, CodeWriter w) {
+        QueryPlanningContext queryContext = new QueryPlanningContext(context, existentialVariables);
+        if(query.createQueryPlan(queryContext, null, -1, null))
+            planOps = queryContext.getPlanOps();
+        
         IVal list = w.apply(location, context.getValue(Names.MList_create).getValue(), NoRepConstant.UNIT);
         planOps.add(new PlanOp(location) {
             @Override
@@ -103,4 +104,25 @@ public class ECHRSelect extends Expression {
     public Expression accept(ExpressionTransformer transformer) {
         return transformer.transform(this);
     }
+    
+    @Override
+    public Expression replace(ReplaceContext context) {
+        Variable[] newExistentialVariables = new Variable[existentialVariables.length];
+        for(int i=0;i<existentialVariables.length;++i) {
+            Variable newVariable = existentialVariables[i].copy();
+            context.varMap.put(existentialVariables[i], new EVariable(newVariable));
+            newExistentialVariables[i] = newVariable;
+        }
+        ECHRSelect copy = new ECHRSelect(expression.replace(context), query.replace(context));
+        copy.existentialVariables = newExistentialVariables;
+        copy.currentRuleset = currentRuleset;
+        copy.planOps = planOps;
+        if(planOps != null) {
+            copy.planOps = new ArrayList<PlanOp>(planOps.size());
+            throw new InternalCompilerError(location, "Copying of ECHRSelect is not supported.");
+            //for(PlanOp op : planOps)
+            //    copy.planOps.add(op.replace(context));
+        }
+        return copy;
+    }
 }
index 427acbd19b9dbbdd082df33f7c8ca97b0792d3ed..3a2f845fe88191cb594022c5e0c49f60197b1db5 100644 (file)
@@ -61,10 +61,10 @@ public abstract class Expression extends Symbol implements Typed {
             try {
                 updateType();
             } catch (MatchException e) {
-                throw new InternalCompilerError(e);
+                throw new InternalCompilerError(location, e);
             }
             if(type == null)
-                throw new InternalCompilerError(getClass().getSimpleName() + 
+                throw new InternalCompilerError(location, getClass().getSimpleName() + 
                         ".updateType couldn't compute its type.");
         }
         return type;
@@ -242,7 +242,7 @@ public abstract class Expression extends Symbol implements Typed {
 
     public void getParameters(TranslationContext translationContext,
             ArrayList<Expression> parameters) {
-        throw new InternalCompilerError("Class " + getClass().getSimpleName() + " does not support getParameters.");        
+        throw new InternalCompilerError(location, "Class " + getClass().getSimpleName() + " does not support getParameters.");        
     }
 
     public Expression resolveAsPattern(TranslationContext context) {
@@ -252,7 +252,7 @@ public abstract class Expression extends Symbol implements Typed {
     
     public Expression checkTypeAsPattern(TypingContext context, Type requiredType) {
         if(context.isInPattern())
-            throw new InternalCompilerError("Already in a pattern.");
+            throw new InternalCompilerError(location, "Already in a pattern.");
         context.setInPattern(true);
         Expression expression = checkType(context, requiredType);
         context.setInPattern(false);
@@ -282,7 +282,7 @@ public abstract class Expression extends Symbol implements Typed {
     }
 
     public Expression replace(ReplaceContext context) {
-        throw new InternalCompilerError(getClass().getSimpleName() + " does not support replace.");
+        throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support replace.");
     }
     
     public static Expression[] replace(ReplaceContext context, Expression[] expressions) {
index a26cd857b111af631ea267cbcbc813fcadc7d57b..af84130f8f6cb8d2310fcc27c40655c1f2c7d60a 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.elaboration.expressions.records;
 
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.internal.parsing.Symbol;
 
@@ -11,4 +12,8 @@ public class FieldAssignment extends Symbol {
         this.name = name;
         this.value = value;
     }
+
+    public FieldAssignment replace(ReplaceContext context) {
+        return new FieldAssignment(name, value == null ? null : value.replace(context));
+    }
 }