--- /dev/null
+package org.simantics.scl.compiler.types.util;
+
+import java.util.Comparator;
+
+import org.simantics.scl.compiler.types.TApply;
+import org.simantics.scl.compiler.types.TCon;
+import org.simantics.scl.compiler.types.TFun;
+import org.simantics.scl.compiler.types.TPred;
+import org.simantics.scl.compiler.types.TUnion;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+
+public enum TypeComparator implements Comparator<Type> {
+ INSTANCE;
+
+ @Override
+ public int compare(Type t1, Type t2) {
+ t1 = Types.canonical(t1);
+ t2 = Types.canonical(t2);
+ int id1 = t1.getClassId();
+ int id2 = t2.getClassId();
+ if(id1 < id2)
+ return -1;
+ if(id1 > id2)
+ return 1;
+ int cur;
+ switch(id1) {
+ case Type.APPLY_ID: {
+ TApply p1 = (TApply)t1;
+ TApply p2 = (TApply)t2;
+ cur = compare(p1.function, p2.function);
+ if(cur != 0)
+ return cur;
+ return compare(p1.parameter, p2.parameter);
+ }
+ case Type.CON_ID:
+ return TConComparator.INSTANCE.compare((TCon)t1, (TCon)t2);
+ case Type.FORALL_ID:
+ return 0; // TODO hard to compare
+ case Type.PRED_ID: {
+ TPred p1 = (TPred)t1;
+ TPred p2 = (TPred)t2;
+ cur = TConComparator.INSTANCE.compare(p1.typeClass, p2.typeClass);
+ if(cur != 0)
+ return cur;
+ cur = p1.parameters.length - p2.parameters.length;
+ if(cur != 0)
+ return cur;
+ for(int i=0;i<p1.parameters.length;++i) {
+ cur = compare(p1.parameters[i], p2.parameters[i]);
+ if(cur != 0)
+ return cur;
+ }
+ return 0;
+ }
+ case Type.FUN_ID: {
+ TFun p1 = (TFun)t1;
+ TFun p2 = (TFun)t2;
+ cur = compare(p1.domain, p2.domain);
+ if(cur != 0)
+ return cur;
+ cur = compare(p1.range, p2.range);
+ if(cur != 0)
+ return cur;
+ return compare(p1.effect, p2.effect);
+ }
+ case Type.UNION_ID: {
+ TUnion p1 = (TUnion)t1;
+ TUnion p2 = (TUnion)t2;
+ cur = p1.effects.length - p2.effects.length;
+ if(cur != 0)
+ return cur;
+ return 0; // TODO
+ }
+ case Type.METAVAR_ID:
+ return 0; // cannot compare
+ case Type.VAR_ID:
+ return 0; // cannot compare
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+}