]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/kinds/Kinds.java
Added missing parts from SVN org.simantics.root project.
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / types / kinds / Kinds.java
1 package org.simantics.scl.compiler.types.kinds;
2
3 import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
4
5 public class Kinds {
6     public static final KCon STAR = new KCon("*");
7     public static final KCon EFFECT = new KCon("E");
8     public static final Kind STAR_TO_STAR = new KArrow(STAR, STAR);
9     public static final Kind STAR_TO_STAR_TO_STAR = new KArrow(STAR, STAR_TO_STAR);
10     
11     public static KArrow arrow(Kind domain, Kind range) {
12         return new KArrow(domain, range);
13     }
14     
15     public static KMetaVar metaVar() {
16         return new KMetaVar();
17     }
18     
19     public static Kind canonical(Kind a) {
20         while(a instanceof KMetaVar) {
21             KMetaVar mv = (KMetaVar)a;
22             if(mv.ref == null)
23                 return a;
24             a = mv.ref;
25         }
26         return a;
27     }
28     
29     public static void unifyWithStar(Kind a) throws KindUnificationException {
30         a = canonical(a);
31         if(a == STAR)
32             return;
33         if(a instanceof KMetaVar)
34             ((KMetaVar)a).ref = STAR;
35         throw new KindUnificationException();
36     }
37     
38     /**
39      * Tries to unify two kinds by linking matching meta-variables.
40      * @throws KindUnificationException  if unification fails
41      */
42     public static void unify(Kind a, Kind b) throws KindUnificationException {
43         a = canonical(a);
44         b = canonical(b);
45         if(a == b)
46             return;
47         if(a instanceof KMetaVar) {
48             ((KMetaVar)a).setRef(b);
49             return;
50         }
51         if(b instanceof KMetaVar) {
52             ((KMetaVar)b).setRef(a);
53             return;
54         }
55         if(a instanceof KArrow && b instanceof KArrow) {
56             KArrow arrowA = (KArrow)a;
57             KArrow arrowB = (KArrow)b;
58             unify(arrowA.domain, arrowB.domain);
59             unify(arrowA.range, arrowB.range);
60             return;
61         }
62         throw new KindUnificationException();
63     }
64
65     public static boolean equalsCanonical(Kind a, Kind b) {
66         if(a == b)
67             return true;
68         if(!(a instanceof KArrow))
69             return false;
70         if(!(b instanceof KArrow))
71             return false;
72         KArrow arrowA = (KArrow)a;
73         KArrow arrowB = (KArrow)b;
74         return equals(arrowA.domain, arrowB.domain) && 
75                 equals(arrowA.range, arrowB.range);
76     }
77
78     public static boolean equals(Kind a, Kind b) {
79         return equalsCanonical(canonical(a), canonical(b));
80     }    
81 }