1 package org.simantics.scl.compiler.types.kinds;
3 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
4 import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
7 public static final KCon STAR = new KCon("*");
8 public static final KCon EFFECT = new KCon("E");
9 public static final Kind STAR_TO_STAR = new KArrow(STAR, STAR);
10 public static final Kind STAR_TO_STAR_TO_STAR = new KArrow(STAR, STAR_TO_STAR);
12 public static KArrow arrow(Kind domain, Kind range) {
13 return new KArrow(domain, range);
16 public static KMetaVar metaVar() {
17 return new KMetaVar();
20 public static Kind canonical(Kind a) {
21 while(a instanceof KMetaVar) {
22 KMetaVar mv = (KMetaVar)a;
30 public static void unifyWithStar(Kind a) throws KindUnificationException {
34 if(a instanceof KMetaVar)
35 ((KMetaVar)a).ref = STAR;
36 throw new KindUnificationException();
40 * Tries to unify two kinds by linking matching meta-variables.
41 * @throws KindUnificationException if unification fails
43 public static void unify(Kind a, Kind b) throws KindUnificationException {
48 if(a instanceof KMetaVar) {
49 ((KMetaVar)a).setRef(b);
52 if(b instanceof KMetaVar) {
53 ((KMetaVar)b).setRef(a);
56 if(a instanceof KArrow && b instanceof KArrow) {
57 KArrow arrowA = (KArrow)a;
58 KArrow arrowB = (KArrow)b;
59 unify(arrowA.domain, arrowB.domain);
60 unify(arrowA.range, arrowB.range);
63 throw new KindUnificationException();
66 public static boolean equalsCanonical(Kind a, Kind b) {
69 if(!(a instanceof KArrow))
71 if(!(b instanceof KArrow))
73 KArrow arrowA = (KArrow)a;
74 KArrow arrowB = (KArrow)b;
75 return equals(arrowA.domain, arrowB.domain) &&
76 equals(arrowA.range, arrowB.range);
79 public static boolean equals(Kind a, Kind b) {
80 return equalsCanonical(canonical(a), canonical(b));
83 public static Kind rangeOfArrow(Kind kind) {
84 kind = canonical(kind);
85 if(kind instanceof KArrow)
86 return ((KArrow)kind).range;
87 else if(kind instanceof KMetaVar) {
88 Kind domain = Kinds.metaVar();
89 Kind range = Kinds.metaVar();
91 ((KMetaVar)kind).setRef(arrow(domain, range));
92 } catch (KindUnificationException e) {
93 // Should not fail because kind is canonical
99 throw new InternalCompilerError("Assumed arrow kind but encountered " + kind + ".");