]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java
Merge "Resolve some dependency problems with SDK features"
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / chr / CHRLiteral.java
index 597ee9d9c9dda82f7ab4fbedb31b751d5d3c00a7..7b4a5bc26b1c7afb59addb97fa91d93985d7cc39 100644 (file)
-package org.simantics.scl.compiler.elaboration.chr;\r
-\r
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
-import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;\r
-import org.simantics.scl.compiler.elaboration.chr.relations.ExternalCHRRelation;\r
-import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;\r
-import org.simantics.scl.compiler.elaboration.chr.relations.UnresolvedCHRRelation;\r
-import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
-import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
-import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;\r
-import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;\r
-import org.simantics.scl.compiler.elaboration.relations.SCLRelation;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-import org.simantics.scl.compiler.internal.parsing.Symbol;\r
-import org.simantics.scl.compiler.types.TVar;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.kinds.Kinds;\r
-\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class CHRLiteral extends Symbol {\r
-    \r
-    public CHRRelation relation;\r
-    public Type[] typeParameters;\r
-    public Expression[] parameters;\r
-    public boolean killAfterMatch;\r
-    public boolean negated;\r
-    public boolean passive = true;\r
-    \r
-    public CHRLiteral(long location, CHRRelation relation, Expression[] parameters, boolean remove, boolean negated) {\r
-        this.location = location;\r
-        this.relation = relation;\r
-        this.parameters = parameters;\r
-        this.killAfterMatch = remove;\r
-        this.negated = negated;\r
-    }\r
-\r
-    public void resolve(TranslationContext context) {\r
-        if(relation instanceof UnresolvedCHRRelation) {\r
-            UnresolvedCHRRelation unresolved = (UnresolvedCHRRelation)relation;\r
-            CHRConstraint constraint = context.resolveCHRConstraint(unresolved.name);\r
-            if(constraint != null) {\r
-                relation = constraint;\r
-                passive = false;\r
-            }\r
-            else {\r
-                SCLRelation sclRelation = context.resolveRelation(unresolved.location, unresolved.name);\r
-                if(sclRelation != null)\r
-                    relation = new ExternalCHRRelation(sclRelation);\r
-                else {\r
-                    Type[] parameterTypes = new Type[parameters.length];\r
-                    for(int i=0;i<parameterTypes.length;++i)\r
-                        parameterTypes[i] = Types.metaVar(Kinds.STAR);\r
-                    constraint = new CHRConstraint(location, unresolved.name, parameterTypes);\r
-                    constraint.implicitlyDeclared = true;\r
-                    context.newCHRConstraint(constraint.name, constraint);\r
-                    relation = constraint;\r
-                    passive = false;\r
-                    //context.getErrorLog().log(unresolved.location, "Couldn't resolve constraint " + unresolved.name + ".");\r
-                }\r
-            }\r
-        }\r
-        for(int i=0;i<parameters.length;++i)\r
-            parameters[i] = parameters[i].resolve(context);\r
-    }\r
-\r
-    public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
-        for(Expression parameter : parameters)\r
-            parameter.collectRefs(allRefs, refs);\r
-    }\r
-\r
-    public void checkType(TypingContext context) {\r
-        if(relation == SpecialCHRRelation.EXECUTE) {\r
-            if(parameters.length != 1)\r
-                throw new InternalCompilerError("Wrong number of parameters for EXECUTE constraint.");\r
-            parameters[0] = parameters[0].checkIgnoredType(context);\r
-        }\r
-        else {\r
-            TVar[] typeVariables = relation.getTypeVariables();\r
-            typeParameters = typeVariables.length == 0 ? Type.EMPTY_ARRAY : new Type[typeVariables.length];\r
-            for(int i=0;i<typeVariables.length;++i)\r
-                typeParameters[i] = Types.metaVar(typeVariables[i].getKind());\r
-            Type[] parameterTypes = Types.replace(relation.getParameterTypes(), typeVariables, typeParameters);\r
-            if(parameterTypes.length != parameters.length)\r
-                context.getErrorLog().log(location, "Constraint is applied with wrong number of parameters");\r
-            else\r
-                for(int i=0;i<parameters.length;++i)\r
-                    parameters[i] = parameters[i].checkType(context, parameterTypes[i]);\r
-        }\r
-    }\r
-\r
-    public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {\r
-        for(Expression parameter : parameters)\r
-            parameter.collectVars(allVars, vars);\r
-    }\r
-\r
-    public void forVariables(VariableProcedure procedure) {\r
-        for(Expression parameter : parameters)\r
-            parameter.forVariables(procedure);\r
-    }\r
-\r
-    public void collectFreeVariables(THashSet<Variable> vars) {\r
-        for(Expression parameter : parameters)\r
-            parameter.collectFreeVariables(vars);\r
-    }\r
-\r
-    public void setLocationDeep(long loc) {\r
-        if(location == Locations.NO_LOCATION) {\r
-            this.location = loc;\r
-            for(Expression parameter : parameters)\r
-                parameter.setLocationDeep(loc);\r
-        }\r
-    }\r
-    \r
-    public void simplify(SimplificationContext context) {\r
-        for(int i=0;i<parameters.length;++i)\r
-            parameters[i] = parameters[i].simplify(context);\r
-    }\r
-    \r
-    public String toString() {\r
-        StringBuilder b = new StringBuilder();\r
-        ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);\r
-        visitor.visit(this);\r
-        return b.toString();\r
-    }\r
-\r
-    public void collectQueryEffects(THashSet<Type> effects) {\r
-    }\r
-\r
-    public void collectEnforceEffects(THashSet<Type> effects) {\r
-    }\r
-}\r
+package org.simantics.scl.compiler.elaboration.chr;
+
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+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.SimplificationContext;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext.ExistentialFrame;
+import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
+import org.simantics.scl.compiler.elaboration.expressions.ERecord;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+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.expressions.records.FieldAssignment;
+import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.internal.parsing.Symbol;
+import org.simantics.scl.compiler.types.TVar;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class CHRLiteral extends Symbol {
+    
+    public CHRRelation relation;
+    public Type[] typeParameters;
+    public Expression[] parameters;
+    public FieldAssignment[] fields; // optional
+    public Expression[] typeConstraintEvidenceParameters;
+    public boolean killAfterMatch;
+    public boolean negated;
+    public boolean passive = true;
+    
+    public CHRLiteral(long location, CHRRelation relation, Expression[] parameters, boolean remove, boolean negated) {
+        this.location = location;
+        this.relation = relation;
+        this.parameters = parameters;
+        this.killAfterMatch = remove;
+        this.negated = negated;
+    }
+
+    public void resolve(TranslationContext context) {
+        if(relation instanceof UnresolvedCHRRelation) {
+            UnresolvedCHRRelation unresolved = (UnresolvedCHRRelation)relation;
+            CHRConstraint constraint = context.resolveCHRConstraint(unresolved.name);
+            if(constraint != null) {
+                relation = constraint;
+                passive = false;
+            }
+            else {
+                SCLRelation sclRelation = context.resolveRelation(unresolved.location, unresolved.name);
+                if(sclRelation != null)
+                    relation = new ExternalCHRRelation(sclRelation);
+                else {
+                    if(parameters == null) {
+                        context.getErrorLog().log(location, "Relation must be declared if record syntax is used.");
+                        return;
+                    }
+                    Type[] parameterTypes = new Type[parameters.length];
+                    for(int i=0;i<parameterTypes.length;++i)
+                        parameterTypes[i] = Types.metaVar(Kinds.STAR);
+                    constraint = new CHRConstraint(location, unresolved.name, parameterTypes);
+                    constraint.implicitlyDeclared = true;
+                    context.newCHRConstraint(constraint.name, constraint);
+                    relation = constraint;
+                    passive = false;
+                    //context.getErrorLog().log(unresolved.location, "Couldn't resolve constraint " + unresolved.name + ".");
+                }
+            }
+        }
+        if(parameters == null && fields != null) {
+            String[] fieldNames = relation.getFieldNames();
+            if(fieldNames == null) {
+                context.getErrorLog().log(location, "Relation " + relation + " does not define field names.");
+                return;
+            }
+            parameters = ERecord.translateFieldsToFunctionParameters(context, fields, fieldNames);
+            if(parameters == null)
+                return;
+            for(int i=0;i<parameters.length;++i) {
+                Expression parameter = parameters[i];
+                if(parameter == null) {
+                    ExistentialFrame frame = context.getCurrentExistentialFrame();
+                    if(frame == null || frame.disallowNewExistentials)
+                        context.getErrorLog().log(location, "Field " + fieldNames[i] + " not defined.");
+                    else
+                        parameters[i] = frame.createBlank(location);
+                }
+                else
+                    parameters[i] = parameters[i].resolve(context);
+            }
+            fields = null;
+        }
+        else {
+            for(int i=0;i<parameters.length;++i)
+                parameters[i] = parameters[i].resolve(context);
+        }
+    }
+
+    public void collectRefs(TObjectIntHashMap<Object> 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) {
+        if(relation == SpecialCHRRelation.EXECUTE) {
+            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();
+            typeParameters = typeVariables.length == 0 ? Type.EMPTY_ARRAY : new Type[typeVariables.length];
+            for(int i=0;i<typeVariables.length;++i)
+                typeParameters[i] = Types.metaVar(typeVariables[i].getKind());
+            Type[] parameterTypes = Types.replace(relation.getParameterTypes(), typeVariables, typeParameters);
+            if(parameterTypes.length != parameters.length)
+                context.getErrorLog().log(location, "Constraint is applied with wrong number of parameters");
+            else
+                for(int i=0;i<parameters.length;++i)
+                    parameters[i] = parameters[i].checkType(context, parameterTypes[i]);
+            
+            typeConstraintEvidenceParameters = context.addConstraints(Types.replace(relation.getTypeConstraints(), typeVariables, typeParameters));
+        }
+    }
+
+    public void collectVars(TObjectIntHashMap<Variable> 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<Variable> vars) {
+        for(Expression parameter : parameters)
+            parameter.collectFreeVariables(vars);
+        if(typeConstraintEvidenceParameters != null)
+            for(Expression parameter : typeConstraintEvidenceParameters)
+                parameter.collectFreeVariables(vars);
+    }
+
+    public void setLocationDeep(long loc) {
+        if(location == Locations.NO_LOCATION) {
+            this.location = loc;
+            for(Expression parameter : parameters)
+                parameter.setLocationDeep(loc);
+        }
+    }
+    
+    public void simplify(SimplificationContext context) {
+        for(int i=0;i<parameters.length;++i)
+            parameters[i] = parameters[i].simplify(context);
+        if(typeConstraintEvidenceParameters != null)
+            for(int i=0;i<typeConstraintEvidenceParameters.length;++i)
+                typeConstraintEvidenceParameters[i] = typeConstraintEvidenceParameters[i].simplify(context);
+    }
+    
+    public String toString() {
+        StringBuilder b = new StringBuilder();
+        ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);
+        visitor.visit(this);
+        return b.toString();
+    }
+
+    public void collectQueryEffects(THashSet<Type> effects) {
+    }
+
+    public void collectEnforceEffects(THashSet<Type> effects) {
+    }
+}