001: /**************************************************************************/
002: /* B O S S A */
003: /* A simple imperative object-oriented research language */
004: /* (c) Daniel Bonniot 1999 */
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 java.util.*;
014:
015: import mlsub.typing.lowlevel.*;
016:
017: /**
018: * A monotype, build by application of
019: * a type constructor to type parameters.
020: */
021: public final class MonotypeConstructor extends Monotype {
022: /**
023: * Constructs a monotype by application of the type constructor
024: * to the type parameters.
025: *
026: * @param tc the type constructor
027: * @param parameters the type parameters
028: */
029: public MonotypeConstructor(TypeConstructor tc, Monotype[] parameters)
030: throws BadSizeEx {
031: this .tc = tc;
032: this .parameters = parameters;
033: if (parameters != null && parameters.length == 0)
034: throw new Error("Not optimal");
035:
036: // variance is not known yet for java classes
037: // ill-formedness shall be discovered later, hopefully
038: if (tc.variance != null) {
039: int len = (parameters == null ? 0 : parameters.length);
040: if (tc.arity() != len)
041: throw new BadSizeEx(tc.arity(), len);
042: }
043: }
044:
045: /**
046: * Constructs a monotype by application of the type constructor
047: * to one type parameter.
048: *
049: * @param tc the type constructor
050: * @param parameter the type parameter
051: */
052: public static MonotypeConstructor apply(TypeConstructor tc,
053: Monotype parameter) throws BadSizeEx {
054: return new MonotypeConstructor(tc, new Monotype[] { parameter });
055: }
056:
057: /**
058: Return the head type constructor if this monotype is
059: of a known variance, or null.
060: */
061: public TypeConstructor head() {
062: return tc;
063: }
064:
065: public TypeConstructor getTC() {
066: return tc;
067: }
068:
069: public Monotype[] getTP() {
070: return parameters;
071: }
072:
073: /**
074: Returns true if this monotype is only made of
075: top-level, rigid type constructors
076: */
077: public boolean isRigid() {
078: return tc.isRigid() && Monotype.isRigid(parameters);
079: }
080:
081: /**
082: * Perform type symbol substitution inside the monotype.
083: *
084: * Does not need to create a new object, but must not
085: * imperatively modify the monotype.
086: *
087: * @param map a map from TypeSymbols to TypeSymbols
088: * @return a monotype with substitution performed
089: */
090: Monotype substitute(Map map) {
091: Object newTC = map.get(tc);
092:
093: return new MonotypeConstructor((newTC == null ? tc
094: : (TypeConstructor) newTC), Monotype.substitute(map,
095: parameters));
096: }
097:
098: /****************************************************************
099: * low-level interface
100: ****************************************************************/
101:
102: public int getId() {
103: throw new Error();
104: }
105:
106: public void setId(int value) {
107: throw new Error();
108: }
109:
110: public Kind getKind() {
111: return tc.variance;
112: }
113:
114: public void setKind(Kind value) {
115: if (tc.variance == value)
116: return;
117: else
118: throw new Error("SetKind in " + this + ": " + value
119: + " != " + tc.variance);
120: }
121:
122: public boolean equals(Object o) {
123: if (!(o instanceof MonotypeConstructor))
124: return false;
125: MonotypeConstructor that = (MonotypeConstructor) o;
126:
127: return tc.equals(that.tc)
128: && (parameters == null && that.parameters == null || parameters
129: .equals(that.parameters));
130: }
131:
132: public String toString() {
133: return tc.toString(parameters);
134: }
135:
136: public String toString(boolean isNull, String suffix) {
137: return tc.toString(parameters, isNull, suffix);
138: }
139:
140: public TypeConstructor tc;
141: Monotype[] parameters;
142:
143: /****************************************************************
144: * Simplification
145: ****************************************************************/
146:
147: void tag(int variance) {
148: Engine.tag(tc, variance);
149: if (tc.variance instanceof Variance)
150: ((Variance) tc.variance).tag(parameters, variance);
151: else
152: // Nullness Kind
153: parameters[0].tag(variance);
154: }
155:
156: Monotype canonify() {
157: tc = (TypeConstructor) Engine.canonify(tc);
158:
159: parameters = Monotype.canonify(parameters);
160: return this;
161: }
162: }
|