]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints2/ConstraintStore.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / elaboration / constraints2 / ConstraintStore.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints2/ConstraintStore.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints2/ConstraintStore.java
new file mode 100644 (file)
index 0000000..b4f2dcf
--- /dev/null
@@ -0,0 +1,96 @@
+package org.simantics.scl.compiler.internal.elaboration.constraints2;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectProcedure;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.elaboration.modules.TypeClass;
+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;
+import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
+
+class ConstraintStore {
+
+    private final ConstraintSolver solver;
+    private final TypeClass typeClass;
+    private final THashMap<Type, ArrayList<ConstraintHandle>> constraintsByHead = 
+            new THashMap<Type, ArrayList<ConstraintHandle>>();
+    private final ArrayList<ConstraintHandle> constraintsWithoutHead = 
+            new ArrayList<ConstraintHandle>();
+    
+    public ConstraintStore(ConstraintSolver solver, TCon typeClassCon) {
+        this.solver = solver;
+        this.typeClass = solver.environment.getTypeClass(typeClassCon);
+        if(this.typeClass == null)
+            throw new InternalCompilerError("Didn't find type class " + typeClassCon + ".");
+    }
+
+    private ArrayList<ConstraintHandle> getConstraintListFor(TPred pred) {
+        Type head = head(pred);
+        if(head instanceof TCon || head instanceof TVar) {
+            ArrayList<ConstraintHandle> result = constraintsByHead.get(head);
+            if(result == null) {
+                result = new ArrayList<ConstraintHandle>(2);
+                constraintsByHead.put(head, result);
+            }
+            return result;
+        }
+        else
+            return constraintsWithoutHead;
+    }
+    
+    public ConstraintHandle addConstraint(TPred pred, long demandLocation) {
+        // Try to find an existing ConstraintHandle for the predicate
+        ArrayList<ConstraintHandle> handles = getConstraintListFor(pred);
+        for(ConstraintHandle handle : handles)
+            if(equals(pred.parameters, handle.constraint.parameters))
+                return handle;
+        
+        // Create a new ConstraintHandle
+        ConstraintHandle handle = new ConstraintHandle(pred, demandLocation);
+        handles.add(handle);
+        addSuperDemands(handle);
+        return handle;
+    }
+    
+    private void addSuperDemands(ConstraintHandle handle) {
+        for(int i=0;i<typeClass.context.length;++i) {
+            TPred superPred = (TPred) 
+                    typeClass.context[i].replace(typeClass.parameters, handle.constraint.parameters);
+            ConstraintHandle superHandle = solver.addDemand(superPred, handle.demandLocation);
+            superHandle.setResolution(new ConstraintResolution(
+                    typeClass.superGenerators[i],  handle.constraint.parameters,
+                    new ConstraintHandle[] {handle}, ConstraintResolution.SUPERCLASS_PRIORITY));
+        }
+    }
+
+    private static Type head(TPred pred) {
+        return pred.parameters[0].head();
+    }
+    
+    private static boolean equals(Type[] a, Type[] b) {
+        for(int i=0;i<a.length;++i)
+            if(!Types.equals(a[i], b[i]))
+                return false;
+        return true;
+    }
+
+    public void print(final TypeUnparsingContext tuc) { 
+        constraintsByHead.forEachValue(new TObjectProcedure<ArrayList<ConstraintHandle>>() {
+            @Override
+            public boolean execute(ArrayList<ConstraintHandle> constraintHandles) {
+                for(ConstraintHandle constraintHandle : constraintHandles)
+                    System.out.println(constraintHandle.toString(tuc));
+                return true;
+            }
+        });
+        for(ConstraintHandle constraintHandle : constraintsWithoutHead)
+            System.out.println(constraintHandle.toString(tuc));
+    }
+
+}