01: /**************************************************************************/
02: /* B O S S A */
03: /* A simple imperative object-oriented research language */
04: /* (c) Daniel Bonniot 1999 */
05: /* */
06: /* This program is free software; you can redistribute it and/or modify */
07: /* it under the terms of the GNU General Public License as published by */
08: /* the Free Software Foundation; either version 2 of the License, or */
09: /* (at your option) any later version. */
10: /* */
11: /**************************************************************************/package mlsub.typing;
12:
13: /**
14: * Constraint on type constructors.
15: *
16: * @author Daniel Bonniot
17: */
18:
19: public final class TypeConstructorLeqCst extends AtomicConstraint {
20: public TypeConstructorLeqCst(TypeConstructor t1, TypeConstructor t2) {
21: this .t1 = t1;
22: this .t2 = t2;
23:
24: identifyVariances(t1, t2);
25: }
26:
27: /**
28: * Assert that t1 and t2 have the same variance.
29: *
30: * This is not necessary, as it would be discovered later
31: * in the constraint solver.
32: * But it seems good to discover it sooner,
33: * for efficiency reasons
34: * (and for error reporting if we added a check).
35: */
36: private static void identifyVariances(TypeConstructor t1,
37: TypeConstructor t2) {
38: if (t1.variance == null && t2.variance != null)
39: t1.setVariance(t2.variance);
40: else if (t2.variance == null && t1.variance != null)
41: t2.setVariance(t1.variance);
42: }
43:
44: /**
45: * Perform type symbol substitution inside the constraint.
46: *
47: * Does not need to create a new object, but must not
48: * imperatively modify the constraint.
49: *
50: * @param map a map from TypeSymbols to TypeSymbols
51: * @return an atomic constraint with substitution performed
52: */
53: AtomicConstraint substitute(java.util.Map map) {
54: Object tt1, tt2;
55: tt1 = map.get(t1);
56: tt2 = map.get(t2);
57:
58: if (tt1 == null && tt2 == null)
59: return this ;
60:
61: if (tt1 == null)
62: tt1 = t1;
63: else if (tt2 == null)
64: tt2 = t2;
65:
66: return new TypeConstructorLeqCst((TypeConstructor) tt1,
67: (TypeConstructor) tt2);
68: }
69:
70: public void enter() throws TypingEx {
71: Typing.leq(t1, t2);
72: }
73:
74: public String toString() {
75: return t1 + " < " + t2;
76: }
77:
78: private TypeConstructor t1;
79: private TypeConstructor t2;
80:
81: public TypeConstructor t1() {
82: return t1;
83: }
84:
85: public TypeConstructor t2() {
86: return t2;
87: }
88: }
|