]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints2/ConstraintStore.java
migrated to svn revision 33108
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / elaboration / constraints2 / ConstraintStore.java
1 package org.simantics.scl.compiler.internal.elaboration.constraints2;
2
3 import java.util.ArrayList;
4
5 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
6 import org.simantics.scl.compiler.elaboration.modules.TypeClass;
7 import org.simantics.scl.compiler.types.TCon;
8 import org.simantics.scl.compiler.types.TPred;
9 import org.simantics.scl.compiler.types.TVar;
10 import org.simantics.scl.compiler.types.Type;
11 import org.simantics.scl.compiler.types.Types;
12 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
13
14 import gnu.trove.map.hash.THashMap;
15 import gnu.trove.procedure.TObjectProcedure;
16
17 class ConstraintStore {
18
19     private final ConstraintSolver solver;
20     private final TypeClass typeClass;
21     private final THashMap<Type, ArrayList<ConstraintHandle>> constraintsByHead = 
22             new THashMap<Type, ArrayList<ConstraintHandle>>();
23     private final ArrayList<ConstraintHandle> constraintsWithoutHead = 
24             new ArrayList<ConstraintHandle>();
25     
26     public ConstraintStore(ConstraintSolver solver, TCon typeClassCon) {
27         this.solver = solver;
28         this.typeClass = solver.environment.getTypeClass(typeClassCon);
29         if(this.typeClass == null)
30             throw new InternalCompilerError("Didn't find type class " + typeClassCon + ".");
31     }
32
33     private ArrayList<ConstraintHandle> getConstraintListFor(TPred pred) {
34         Type head = head(pred);
35         if(head instanceof TCon || head instanceof TVar) {
36             ArrayList<ConstraintHandle> result = constraintsByHead.get(head);
37             if(result == null) {
38                 result = new ArrayList<ConstraintHandle>(2);
39                 constraintsByHead.put(head, result);
40             }
41             return result;
42         }
43         else
44             return constraintsWithoutHead;
45     }
46     
47     public ConstraintHandle addConstraint(TPred pred, long demandLocation) {
48         // Try to find an existing ConstraintHandle for the predicate
49         ArrayList<ConstraintHandle> handles = getConstraintListFor(pred);
50         for(ConstraintHandle handle : handles)
51             if(equals(pred.parameters, handle.constraint.parameters))
52                 return handle;
53         
54         // Create a new ConstraintHandle
55         ConstraintHandle handle = new ConstraintHandle(pred, demandLocation);
56         handles.add(handle);
57         addSuperDemands(handle);
58         return handle;
59     }
60     
61     private void addSuperDemands(ConstraintHandle handle) {
62         for(int i=0;i<typeClass.context.length;++i) {
63             TPred superPred = (TPred) 
64                     typeClass.context[i].replace(typeClass.parameters, handle.constraint.parameters);
65             ConstraintHandle superHandle = solver.addDemand(superPred, handle.demandLocation);
66             superHandle.setResolution(new ConstraintResolution(
67                     typeClass.superGenerators[i],  handle.constraint.parameters,
68                     new ConstraintHandle[] {handle}, ConstraintResolution.SUPERCLASS_PRIORITY));
69         }
70     }
71
72     private static Type head(TPred pred) {
73         return pred.parameters[0].head();
74     }
75     
76     private static boolean equals(Type[] a, Type[] b) {
77         for(int i=0;i<a.length;++i)
78             if(!Types.equals(a[i], b[i]))
79                 return false;
80         return true;
81     }
82
83     public void print(final TypeUnparsingContext tuc) { 
84         constraintsByHead.forEachValue(new TObjectProcedure<ArrayList<ConstraintHandle>>() {
85             @Override
86             public boolean execute(ArrayList<ConstraintHandle> constraintHandles) {
87                 for(ConstraintHandle constraintHandle : constraintHandles)
88                     System.out.println(constraintHandle.toString(tuc));
89                 return true;
90             }
91         });
92         for(ConstraintHandle constraintHandle : constraintsWithoutHead)
93             System.out.println(constraintHandle.toString(tuc));
94     }
95
96 }