From b2c6aed4003ef264fb48eed9ac9f2d0f6c2d5b13 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Hannu=20Niemist=C3=B6?= Date: Thu, 19 Jan 2017 10:34:54 +0200 Subject: [PATCH] Implemented GraphPropertyRelation with the new CHR implementation This change adds type constraints to SCLRelations, a feature that is needed because GraphPropertyRelation requires Serializable type constraint. There are also minor improvement to the locations of the compilation errors caused by exceptions the compiler throws. refs #6984 Change-Id: I6c1070af3a7129ae21e2cc01a5675412b32b4960 --- .../modeling/scl/GraphPropertyRelation.java | 61 ++++++++++++++----- .../simantics/modeling/scl/GraphRelation.java | 5 +- .../compiler/compilation/CodeGeneration.java | 6 +- .../compiler/elaboration/chr/CHRLiteral.java | 19 ++++++ .../compiler/elaboration/chr/CHRRelation.java | 2 + .../compiler/elaboration/chr/CHRRuleset.java | 1 - .../chr/plan/IterateRelationOp.java | 6 +- .../elaboration/chr/plan/PlanContext.java | 48 +++++++++++++++ .../planning/items/GenericPrePlanItem.java | 2 +- .../chr/relations/CHRConstraint.java | 6 ++ .../chr/relations/ExternalCHRRelation.java | 6 ++ .../chr/relations/SpecialCHRRelation.java | 5 ++ .../chr/relations/UnresolvedCHRRelation.java | 5 ++ .../relations/AbstractRelation.java | 5 +- .../relations/ConcreteRelation.java | 5 +- .../elaboration/relations/SCLRelation.java | 10 ++- .../scl/compiler/errors/ErrorLog.java | 14 ++--- .../simantics/scl/compiler/types/Types.java | 9 +++ 18 files changed, 179 insertions(+), 36 deletions(-) diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java index d9803aedd..a6009426f 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java @@ -15,6 +15,7 @@ import org.simantics.scl.compiler.elaboration.relations.SCLRelation; import org.simantics.scl.compiler.environment.Environment; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; +import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; @@ -26,7 +27,7 @@ public class GraphPropertyRelation implements SCLRelation { Type[] parameterTypes; private static final Type RESOURCE = Types.con("Simantics/DB", "Resource"); - + public GraphPropertyRelation(Resource propertyRelation, Type valueType) { this.propertyRelation = propertyRelation; this.valueType = valueType; @@ -37,7 +38,12 @@ public class GraphPropertyRelation implements SCLRelation { public TVar[] getTypeVariables() { return TVar.EMPTY_ARRAY; } - + + @Override + public TPred[] getTypeConstraints() { + return new TPred[] {Types.pred(Types.SERIALIZABLE, valueType)}; + } + @Override public Type[] getParameterTypes() { return parameterTypes; @@ -53,14 +59,14 @@ public class GraphPropertyRelation implements SCLRelation { default: throw new IllegalArgumentException(); } } - + @Override public int getRequiredVariablesMask() { return BF; } - + private static final Name POSSIBLE_RELATED_VALUE = Name.create("Simantics/DB", "possibleRelatedValue"); - + @Override public void generate(long location, QueryCompilationContext context, Type[] typeParameters, Variable[] parameters, int boundVariables) { @@ -78,8 +84,8 @@ public class GraphPropertyRelation implements SCLRelation { context.condition(new EApply( context.getCompilationContext().getConstant(Names.Builtin_equals, valueType), new Expression[] { - new EVariable(temp), - new EVariable(parameters[1]) + new EVariable(temp), + new EVariable(parameters[1]) } )); context.iterateMaybe(temp, possibleValue); @@ -91,7 +97,7 @@ public class GraphPropertyRelation implements SCLRelation { } private static final Name CLAIM_RELATED_VALUE = Name.create("Simantics/DB", "claimRelatedValue"); - + @Override public Expression generateEnforce(long location, EnforcingContext context, Type[] typeParameters, Variable[] parameters) { @@ -110,15 +116,40 @@ public class GraphPropertyRelation implements SCLRelation { public int getPhase() { return 0; } - + @Override - public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters) { - throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support enforce."); + public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables, + Expression[] expressions, Expression[] typeConstraintEvidenceParameters) { + Environment env = context.context.environment; + switch(boundMask) { + case BF: + context.iterateMaybe(location, w, variables[1], + w.apply(location, + env.getValue(POSSIBLE_RELATED_VALUE).getValue().createSpecialization(valueType), + typeConstraintEvidenceParameters[0].toVal(env, w), + expressions[0].toVal(env, w), + w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE))); + break; + case BB: + context.checkEqualsJust(location, w, expressions[1].toVal(env, w), + w.apply(location, + env.getValue(POSSIBLE_RELATED_VALUE).getValue().createSpecialization(valueType), + typeConstraintEvidenceParameters[0].toVal(env, w), + expressions[0].toVal(env, w), + w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE))); + break; + default: throw new IllegalArgumentException(); + } } - + @Override - public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables, - Expression[] expressions) { - throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support iterate."); + public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters, Expression[] typeConstraintEvidenceParameters) { + Environment env = context.context.environment; + w.apply(location, + env.getValue(CLAIM_RELATED_VALUE).getValue().createSpecialization(valueType), + typeConstraintEvidenceParameters[0].toVal(env, w), + parameters[0].toVal(env, w), + w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE), + parameters[1].toVal(env, w)); } } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java index 625a07384..da08a2a38 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java @@ -138,7 +138,7 @@ public class GraphRelation implements SCLRelation { @Override public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables, - Expression[] expressions) { + Expression[] expressions, Expression[] typeConstraintEvidenceParameters) { Environment env = context.context.environment; switch(boundMask) { case BF: @@ -174,7 +174,8 @@ public class GraphRelation implements SCLRelation { } @Override - public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters) { + public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters, + Expression[] typeConstraintEvidenceParameters) { Environment env = context.context.environment; w.apply(location, env.getValue(CLAIM).getValue(), diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CodeGeneration.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CodeGeneration.java index 52abbc6d8..9c7c77470 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CodeGeneration.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CodeGeneration.java @@ -26,6 +26,7 @@ import org.simantics.scl.compiler.elaboration.modules.TypeClass; import org.simantics.scl.compiler.elaboration.modules.TypeClassInstance; import org.simantics.scl.compiler.elaboration.modules.TypeClassMethod; import org.simantics.scl.compiler.errors.ErrorLog; +import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.references.Val; import org.simantics.scl.compiler.internal.codegen.ssa.SSAModule; @@ -167,7 +168,10 @@ public class CodeGeneration { decomposed.parameters[i].setVal(parameterVals[i]); w.return_(decomposed.body.toVal(compilationContext.environment, w)); } catch(RuntimeException e) { - errorLog.setExceptionPosition(value.getExpression().location); + long location = value.getExpression().location; + if(location == Locations.NO_LOCATION) + location = value.definitionLocation; + errorLog.setExceptionPosition(location); throw e; } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java index be34361c2..b34328a53 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java @@ -29,6 +29,7 @@ public class CHRLiteral extends Symbol { public CHRRelation relation; public Type[] typeParameters; public Expression[] parameters; + public Expression[] typeConstraintEvidenceParameters; public boolean killAfterMatch; public boolean negated; public boolean passive = true; @@ -73,6 +74,9 @@ public class CHRLiteral extends Symbol { public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { for(Expression parameter : parameters) parameter.collectRefs(allRefs, refs); + if(typeConstraintEvidenceParameters != null) + for(Expression parameter : typeConstraintEvidenceParameters) + parameter.collectRefs(allRefs, refs); } public void checkType(TypingContext context) { @@ -80,6 +84,7 @@ public class CHRLiteral extends Symbol { if(parameters.length != 1) throw new InternalCompilerError("Wrong number of parameters for EXECUTE constraint."); parameters[0] = parameters[0].checkIgnoredType(context); + typeConstraintEvidenceParameters = Expression.EMPTY_ARRAY; } else { TVar[] typeVariables = relation.getTypeVariables(); @@ -92,22 +97,33 @@ public class CHRLiteral extends Symbol { else for(int i=0;i allVars, TIntHashSet vars) { for(Expression parameter : parameters) parameter.collectVars(allVars, vars); + if(typeConstraintEvidenceParameters != null) + for(Expression parameter : typeConstraintEvidenceParameters) + parameter.collectVars(allVars, vars); } public void forVariables(VariableProcedure procedure) { for(Expression parameter : parameters) parameter.forVariables(procedure); + if(typeConstraintEvidenceParameters != null) + for(Expression parameter : typeConstraintEvidenceParameters) + parameter.forVariables(procedure); } public void collectFreeVariables(THashSet vars) { for(Expression parameter : parameters) parameter.collectFreeVariables(vars); + if(typeConstraintEvidenceParameters != null) + for(Expression parameter : typeConstraintEvidenceParameters) + parameter.collectFreeVariables(vars); } public void setLocationDeep(long loc) { @@ -121,6 +137,9 @@ public class CHRLiteral extends Symbol { public void simplify(SimplificationContext context) { for(int i=0;i 1) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/CHRConstraint.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/CHRConstraint.java index d3d6bdf90..7a0e27ba2 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/CHRConstraint.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/CHRConstraint.java @@ -22,6 +22,7 @@ import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator; import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor; import org.simantics.scl.compiler.internal.parsing.Symbol; import org.simantics.scl.compiler.types.TCon; +import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; @@ -205,4 +206,9 @@ public class CHRConstraint extends Symbol implements CHRRelation { public boolean isPassive() { return plans.isEmpty(); } + + public TPred[] getTypeConstraints() { + return TPred.EMPTY_ARRAY; + } + } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/ExternalCHRRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/ExternalCHRRelation.java index 10f2317ab..5e4f5868c 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/ExternalCHRRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/ExternalCHRRelation.java @@ -2,6 +2,7 @@ package org.simantics.scl.compiler.elaboration.chr.relations; import org.simantics.scl.compiler.elaboration.chr.CHRRelation; import org.simantics.scl.compiler.elaboration.relations.SCLRelation; +import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; @@ -21,6 +22,11 @@ public class ExternalCHRRelation implements CHRRelation { public Type[] getParameterTypes() { return relation.getParameterTypes(); } + + @Override + public TPred[] getTypeConstraints() { + return relation.getTypeConstraints(); + } @Override public String toString() { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/SpecialCHRRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/SpecialCHRRelation.java index 2cb0d64fd..c5dbe3c41 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/SpecialCHRRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/SpecialCHRRelation.java @@ -1,6 +1,7 @@ package org.simantics.scl.compiler.elaboration.chr.relations; import org.simantics.scl.compiler.elaboration.chr.CHRRelation; +import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; @@ -28,4 +29,8 @@ public enum SpecialCHRRelation implements CHRRelation { public Type[] getParameterTypes() { return parameterTypes; } + + public TPred[] getTypeConstraints() { + return TPred.EMPTY_ARRAY; + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/UnresolvedCHRRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/UnresolvedCHRRelation.java index 479d5d22c..c852062fb 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/UnresolvedCHRRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/UnresolvedCHRRelation.java @@ -3,6 +3,7 @@ package org.simantics.scl.compiler.elaboration.chr.relations; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.elaboration.chr.CHRRelation; import org.simantics.scl.compiler.internal.parsing.Symbol; +import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; @@ -23,4 +24,8 @@ public class UnresolvedCHRRelation extends Symbol implements CHRRelation { public TVar[] getTypeVariables() { throw new InternalCompilerError("Encountered unresolved CHRRelation during type checking."); } + + public TPred[] getTypeConstraints() { + throw new InternalCompilerError("Encountered unresolved CHRRelation during type checking."); + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/AbstractRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/AbstractRelation.java index 54acd32f3..8dc266819 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/AbstractRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/AbstractRelation.java @@ -20,13 +20,14 @@ public abstract class AbstractRelation implements SCLRelation { } @Override - public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters) { + public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters, + Expression[] typeConstraintEvidenceParameters) { throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support enforce."); } @Override public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables, - Expression[] expressions) { + Expression[] expressions, Expression[] typeConstraintEvidenceParameters) { throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support iterate."); } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/ConcreteRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/ConcreteRelation.java index a38df0bcd..96ace3b64 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/ConcreteRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/ConcreteRelation.java @@ -150,13 +150,14 @@ public class ConcreteRelation extends Symbol implements SCLRelation { } @Override - public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters) { + public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters, + Expression[] typeConstraintEvidenceParameters) { throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support enforce."); } @Override public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables, - Expression[] expressions) { + Expression[] expressions, Expression[] typeConstraintEvidenceParameters) { throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support iterate."); } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/SCLRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/SCLRelation.java index 9642762cb..4ac37bbc1 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/SCLRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/SCLRelation.java @@ -6,6 +6,7 @@ import org.simantics.scl.compiler.elaboration.expressions.Variable; import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext; import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; +import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; @@ -30,6 +31,9 @@ public interface SCLRelation { TVar[] getTypeVariables(); Type[] getParameterTypes(); + default TPred[] getTypeConstraints() { + return TPred.EMPTY_ARRAY; + } int getPhase(); double getSelectivity(int boundVariables); @@ -48,10 +52,12 @@ public interface SCLRelation { long location, int boundMask, Variable[] variables, - Expression[] expressions); + Expression[] expressions, + Expression[] typeConstraintEvidenceParameters); void generateEnforce( PlanContext context, CodeWriter w, long location, - Expression[] parameters); + Expression[] parameters, + Expression[] typeConstraintEvidenceParameters); } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/ErrorLog.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/ErrorLog.java index 2287f919b..f2e648b00 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/ErrorLog.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/ErrorLog.java @@ -7,7 +7,7 @@ import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; public class ErrorLog { ArrayList errors = new ArrayList(); - long exceptionPosition; + long exceptionPosition = Locations.NO_LOCATION; public void log(String message) { errors.add(new CompilationError(message)); @@ -22,10 +22,12 @@ public class ErrorLog { } public void log(Exception e) { + long location = Locations.NO_LOCATION; if(e instanceof InternalCompilerError) - log(((InternalCompilerError)e).location, e); - else - log(new CompilationError(e)); + location = ((InternalCompilerError)e).location; + if(location == Locations.NO_LOCATION) + location = exceptionPosition; + log(new CompilationError(location, e)); } public void log(long location, Exception e) { @@ -45,10 +47,6 @@ public class ErrorLog { if(this.exceptionPosition == Locations.NO_LOCATION) this.exceptionPosition = exceptionPosition; } - - public long getExceptionPosition() { - return exceptionPosition; - } public String getErrorsAsString() { StringBuilder b = new StringBuilder(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Types.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Types.java index b20ee9f12..f793754ee 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Types.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Types.java @@ -1015,6 +1015,15 @@ public class Types { return result; } + public static TPred[] replace(TPred[] types, TVar[] from, Type[] to) { + if(types.length == 0) + return TPred.EMPTY_ARRAY; + TPred[] result = new TPred[types.length]; + for(int i=0;i Type[] replace(Type[] types, THashMap map) { if(types.length == 0) return Type.EMPTY_ARRAY; -- 2.43.2