]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java
(refs #7250) Support for record syntax for CHR relations
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / chr / CHRLiteral.java
index b34328a53ebb494d0586d331b712b9c361bcb6ab..7b4a5bc26b1c7afb59addb97fa91d93985d7cc39 100644 (file)
@@ -7,11 +7,14 @@ 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;
@@ -29,6 +32,7 @@ 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;
@@ -55,6 +59,10 @@ public class CHRLiteral extends Symbol {
                 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);
@@ -67,8 +75,33 @@ public class CHRLiteral extends Symbol {
                 }
             }
         }
-        for(int i=0;i<parameters.length;++i)
-            parameters[i] = parameters[i].resolve(context);
+        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) {