001: /**************************************************************************/
002: /* N I C E */
003: /* A high-level object-oriented research language */
004: /* (c) Daniel Bonniot 2002 */
005: /* */
006: /* This program is free software; you can redistribute it and/or modify */
007: /* it under the terms of the GNU General Public License as published by */
008: /* the Free Software Foundation; either version 2 of the License, or */
009: /* (at your option) any later version. */
010: /* */
011: /**************************************************************************/package mlsub.typing;
012:
013: import mlsub.typing.lowlevel.*;
014:
015: /**
016: The kind of types qualified by their nullness.
017:
018: @version $Date: 2005/06/18 09:58:39 $
019: @author Daniel Bonniot (bonniot@users.sourceforge.net)
020: */
021:
022: public class NullnessKind implements AtomicKind {
023: public static NullnessKind instance = new NullnessKind();
024:
025: public static void setMaybe(TypeConstructor tc) {
026: maybe = tc;
027: }
028:
029: public static void setSure(TypeConstructor tc) {
030: sure = tc;
031: }
032:
033: public int arity() {
034: return 1;
035: }
036:
037: static TypeConstructor maybe, sure;
038:
039: public Monotype freshMonotype(boolean existential) {
040: TypeConstructor tc = new TypeConstructor(instance);
041: introduce(tc);
042:
043: MonotypeVar raw = new MonotypeVar(existential);
044: Typing.introduce(raw);
045:
046: return new MonotypeConstructor(tc, new MonotypeVar[] { raw });
047: }
048:
049: /**
050: @param base The type variable we create this fresh constructed
051: monotype for.
052: */
053: public Monotype persistentFreshMonotype(MonotypeVar base) {
054: TypeConstructor tc = new TypeConstructor(instance);
055:
056: /* It's important to give the raw variable the same name as the base one,
057: so that for the syntactic type <T> ... !T we don't end up printing !t9.
058: */
059: MonotypeVar raw = new MonotypeVar(base.getName());
060:
061: return new MonotypeConstructor(tc, new MonotypeVar[] { raw });
062: }
063:
064: static void introduce(TypeConstructor tc) {
065: tc.getKind().register(tc);
066: try {
067: Typing.leq(tc, maybe);
068: Typing.leq(sure, tc);
069: } catch (TypingEx ex) {
070: bossa.util.Internal.error("Nullness creation error");
071: }
072: }
073:
074: public void register(Element e) {
075: }
076:
077: public void leq(Element e1, Element e2, boolean initial)
078: throws Unsatisfiable {
079: if (initial)
080: throw new InternalError("initial leq in Nullness");
081: leq(e1, e2);
082: }
083:
084: public void leq(Element e1, Element e2) throws Unsatisfiable {
085: Monotype m1 = (Monotype) e1;
086: Monotype m2 = (Monotype) e2;
087:
088: if (m1.isUnknown()) {
089: m2.setUnknown(false, true);
090: return;
091: }
092:
093: if (m2.isUnknown()) {
094: m1.setUnknown(true, false);
095: return;
096: }
097:
098: MonotypeConstructor mc1 = mc(m1), mc2 = mc(m2);
099:
100: Engine.leq(mc1.getTC(), mc2.getTC());
101: Engine.leq(mc1.getTP()[0], mc2.getTP()[0]);
102: }
103:
104: private MonotypeConstructor mc(Monotype m) {
105: try {
106: return (MonotypeConstructor) m.equivalent();
107: } catch (ClassCastException ex) {
108: throw new InternalError(m
109: + " was expected to be a monotype constructor, "
110: + " it's a " + m.getClass());
111: }
112: }
113:
114: public mlsub.typing.lowlevel.Engine.Constraint getConstraint() {
115: return mlsub.typing.lowlevel.Engine.getConstraint(this );
116: }
117:
118: /****************************************************************
119: * Printing
120: ****************************************************************/
121:
122: public String toString() {
123: return "Nullness kind";
124: }
125: }
|