]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeComparator.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / types / util / TypeComparator.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeComparator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeComparator.java
new file mode 100644 (file)
index 0000000..3895c82
--- /dev/null
@@ -0,0 +1,84 @@
+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();
+        }
+    }
+
+}