1 package org.simantics.scl.compiler.internal.elaboration.constraints2;
3 import gnu.trove.map.hash.THashMap;
4 import gnu.trove.procedure.TObjectProcedure;
6 import java.util.ArrayList;
8 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
9 import org.simantics.scl.compiler.elaboration.modules.TypeClass;
10 import org.simantics.scl.compiler.types.TCon;
11 import org.simantics.scl.compiler.types.TPred;
12 import org.simantics.scl.compiler.types.TVar;
13 import org.simantics.scl.compiler.types.Type;
14 import org.simantics.scl.compiler.types.Types;
15 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
17 class ConstraintStore {
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>();
26 public ConstraintStore(ConstraintSolver solver, TCon typeClassCon) {
28 this.typeClass = solver.environment.getTypeClass(typeClassCon);
29 if(this.typeClass == null)
30 throw new InternalCompilerError("Didn't find type class " + typeClassCon + ".");
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);
38 result = new ArrayList<ConstraintHandle>(2);
39 constraintsByHead.put(head, result);
44 return constraintsWithoutHead;
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))
54 // Create a new ConstraintHandle
55 ConstraintHandle handle = new ConstraintHandle(pred, demandLocation);
57 addSuperDemands(handle);
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));
72 private static Type head(TPred pred) {
73 return pred.parameters[0].head();
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]))
83 public void print(final TypeUnparsingContext tuc) {
84 constraintsByHead.forEachValue(new TObjectProcedure<ArrayList<ConstraintHandle>>() {
86 public boolean execute(ArrayList<ConstraintHandle> constraintHandles) {
87 for(ConstraintHandle constraintHandle : constraintHandles)
88 System.out.println(constraintHandle.toString(tuc));
92 for(ConstraintHandle constraintHandle : constraintsWithoutHead)
93 System.out.println(constraintHandle.toString(tuc));