]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java
Merged changes from feature/scl to master.
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / contexts / TranslationContext.java
index b5f9f93e942cb17bcf21c411d7e37702244bd415..41f807592b7ad1de8c0b28d20183a3d4c80a3948 100644 (file)
@@ -4,8 +4,11 @@ import java.util.ArrayList;
 import java.util.Arrays;
 
 import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Names;
 import org.simantics.scl.compiler.common.precedence.Associativity;
 import org.simantics.scl.compiler.common.precedence.Precedence;
+import org.simantics.scl.compiler.compilation.CompilationContext;
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
 import org.simantics.scl.compiler.elaboration.expressions.Case;
 import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous;
 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
@@ -24,12 +27,10 @@ import org.simantics.scl.compiler.elaboration.modules.SCLValue;
 import org.simantics.scl.compiler.elaboration.query.pre.PreQuery;
 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
 import org.simantics.scl.compiler.environment.AmbiguousNameException;
-import org.simantics.scl.compiler.environment.Environment;
 import org.simantics.scl.compiler.environment.Environments;
 import org.simantics.scl.compiler.environment.LocalEnvironment;
 import org.simantics.scl.compiler.environment.Namespace;
 import org.simantics.scl.compiler.environment.filter.AcceptAllNamespaceFilter;
-import org.simantics.scl.compiler.errors.ErrorLog;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
@@ -58,6 +59,10 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
     TIntArrayList relationFrames = new TIntArrayList();
     ArrayList<RelationEntry> relationEntries = new ArrayList<RelationEntry>();
     
+    THashMap<String, CHRConstraint> chrConstraints = new THashMap<String, CHRConstraint>();
+    TIntArrayList chrConstraintFrames = new TIntArrayList();
+    ArrayList<CHRConstraintEntry> chrConstraintEntries = new ArrayList<CHRConstraintEntry>();
+    
     static class Entry {
         String name;
         Variable variable;
@@ -76,14 +81,23 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
         }
     }
     
-    public TranslationContext(ErrorLog errorLog, 
-            Environment environment, LocalEnvironment localEnvironment) {
-        super(errorLog, environment);
+    static class CHRConstraintEntry {
+        String name;
+        CHRConstraint constraint;
+        public CHRConstraintEntry(String name, CHRConstraint constraint) {
+            this.name = name;
+            this.constraint = constraint;
+        }
+    }
+    
+    public TranslationContext(CompilationContext compilationContext, LocalEnvironment localEnvironment) {
+        super(compilationContext);
         this.localEnvironment = localEnvironment;
     }
     
     public static boolean isConstructorName(String name) {
-        char firstChar = name.charAt(0);
+        int p = name.lastIndexOf('.');
+        char firstChar = name.charAt(p<0 ? 0 : p+1);
         return Character.isUpperCase(firstChar);
     }
     
@@ -338,6 +352,26 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
         }
     }
     
+    public void pushCHRConstraintFrame() {
+        chrConstraintFrames.add(chrConstraintEntries.size());
+    }
+    
+    public void popCHRConstraintFrame(ArrayList<CHRConstraint> constraints) {
+        int frame = chrConstraintFrames.removeAt(chrConstraintFrames.size()-1);
+        int i = chrConstraintEntries.size();
+        while(i > frame) {
+            --i;
+            CHRConstraintEntry entry = chrConstraintEntries.remove(i);
+            CHRConstraint newConstraint;
+            if(entry.constraint == null)
+                newConstraint = chrConstraints.remove(entry.name);
+            else
+                newConstraint = chrConstraints.put(entry.name, entry.constraint);
+            if(newConstraint.implicitlyDeclared)
+                constraints.add(newConstraint);
+        }
+    }
+    
     public void pushExistentialFrame() {
         pushFrame();
         existentialFrames.add(new THashSet<String>());
@@ -372,6 +406,11 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
         SCLRelation oldRelation = relations.put(name, relation);
         relationEntries.add(new RelationEntry(name, oldRelation));
     }
+    
+    public void newCHRConstraint(String name, CHRConstraint constraint) {
+        CHRConstraint oldConstraint = chrConstraints.put(name, constraint);
+        chrConstraintEntries.add(new CHRConstraintEntry(name, oldConstraint));
+    }
             
     public Precedence getPrecedence(Name op) {
         Precedence prec = environment.getValue(op).getPrecedence();
@@ -382,55 +421,55 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
     }
 
     private SCLValue resolveValueIn(long location, Namespace namespace, final String name) throws AmbiguousNameException {
-            SCLValue value = namespace.getValue(name);
-            if(value == null) {
-                StringBuilder message = new StringBuilder();
-                message.append("Couldn't resolve variable ").append(name).append(".");
-                
-                final THashSet<String> candidateNames = new THashSet<String>(4);
-                namespace.findValuesForPrefix("", AcceptAllNamespaceFilter.INSTANCE,
-                        new TObjectProcedure<SCLValue>() {
-                            @Override
-                            public boolean execute(SCLValue value) {
-                                if(value == null) {
-                                    new Exception().printStackTrace();
-                                    return true;
-                                }
-                                String valueName = value.getName().name;
-                                if(name.equalsIgnoreCase(valueName))
-                                    candidateNames.add(valueName);
-                                return true;
-                            }
-                        });
-                if(localEnvironment != null)
-                    localEnvironment.forNames(new TObjectProcedure<String>() {
-                        @Override
-                        public boolean execute(String valueName) {
-                            if(name.equalsIgnoreCase(valueName))
-                                candidateNames.add(valueName);
-                            return true;
-                        }
-                    });
-                    
-                if(candidateNames.size() > 0) {
-                    message.append(" Did you mean ");
-                    String[] ns = candidateNames.toArray(new String[candidateNames.size()]);
-                    Arrays.sort(ns);
-                    for(int i=0;i<ns.length;++i) {
-                        if(i > 0) {
-                            message.append(", ");
-                            if(i == ns.length-1)
-                                message.append("or ");
-                        }
-                        message.append(ns[i]);
+        SCLValue value = namespace.getValue(name);
+        if(value == null) {
+            StringBuilder message = new StringBuilder();
+            message.append("Couldn't resolve variable ").append(name).append(".");
+
+            final THashSet<String> candidateNames = new THashSet<String>(4);
+            namespace.findValuesForPrefix("", AcceptAllNamespaceFilter.INSTANCE,
+                    new TObjectProcedure<SCLValue>() {
+                @Override
+                public boolean execute(SCLValue value) {
+                    if(value == null) {
+                        new Exception().printStackTrace();
+                        return true;
                     }
-                    message.append('?');
+                    String valueName = value.getName().name;
+                    if(name.equalsIgnoreCase(valueName))
+                        candidateNames.add(valueName);
+                    return true;
                 }
-                
-                errorLog.log(location, message.toString());
-                return null;
+            });
+            if(localEnvironment != null)
+                localEnvironment.forNames(new TObjectProcedure<String>() {
+                    @Override
+                    public boolean execute(String valueName) {
+                        if(name.equalsIgnoreCase(valueName))
+                            candidateNames.add(valueName);
+                        return true;
+                    }
+                });
+
+            if(candidateNames.size() > 0) {
+                message.append(" Did you mean ");
+                String[] ns = candidateNames.toArray(new String[candidateNames.size()]);
+                Arrays.sort(ns);
+                for(int i=0;i<ns.length;++i) {
+                    if(i > 0) {
+                        message.append(", ");
+                        if(i == ns.length-1)
+                            message.append("or ");
+                    }
+                    message.append(ns[i]);
+                }
+                message.append('?');
             }
-            return value;
+
+            errorLog.log(location, message.toString());
+            return null;
+        }
+        return value;
     }
     
     public Case translateCase(Expression lhs, Expression rhs) {        
@@ -496,11 +535,9 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
                 cases);
     }
     
-    private static final Name BIND = Name.create("Prelude", ">>=");
-    
     public SCLValue getBindFunction() {
         if(bindFunction == null) {
-            bindFunction = getEnvironment().getValue(BIND);
+            bindFunction = getEnvironment().getValue(Names.Prelude_bind);
         }
         return bindFunction;
     }
@@ -522,6 +559,10 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
             return null;
         }
     }
+    
+    public CHRConstraint resolveCHRConstraint(String name) {
+        return chrConstraints.get(name);
+    }
 
     @Override
     public SCLValue getValue(Name name) {