root / trunk / compiler / ooasCompiler / src / org / momut / ooas / ast / types / UlyssesType.java @ 7
1 |
/**
|
---|---|
2 |
*
|
3 |
* OOAS Compiler
|
4 |
*
|
5 |
* Copyright 2015, AIT Austrian Institute of Technology.
|
6 |
* This code is based on the C# Version of the OOAS Compiler, which is
|
7 |
* copyright 2015 by the Institute of Software Technology, Graz University
|
8 |
* of Technology with portions copyright by the AIT Austrian Institute of
|
9 |
* Technology. All rights reserved.
|
10 |
*
|
11 |
* SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
|
12 |
*
|
13 |
* If you modify the file please update the list of contributors below to in-
|
14 |
* clude your name. Please also stick to the coding convention of using TABs
|
15 |
* to do the basic (block-level) indentation and spaces for anything after
|
16 |
* that. (Enable the display of special chars and it should be pretty obvious
|
17 |
* what this means.) Also, remove all trailing whitespace.
|
18 |
*
|
19 |
* Contributors:
|
20 |
* Willibald Krenn (AIT)
|
21 |
* Stephan Zimmerer (AIT)
|
22 |
* Markus Demetz (AIT)
|
23 |
* Christoph Czurda (AIT)
|
24 |
*
|
25 |
*/
|
26 |
|
27 |
|
28 |
package org.momut.ooas.ast.types; |
29 |
|
30 |
import java.util.Iterator; |
31 |
|
32 |
import org.momut.ooas.ast.AstNode; |
33 |
import org.momut.ooas.ast.AstNodeTypeEnum; |
34 |
import org.momut.ooas.ast.IAst; |
35 |
import org.momut.ooas.ast.IAstVisitor; |
36 |
import org.momut.ooas.ast.identifiers.TypeIdentifier; |
37 |
import org.momut.ooas.utils.exceptions.ArgumentException; |
38 |
import org.momut.ooas.utils.exceptions.NotImplementedException; |
39 |
import org.momut.ooas.utils.exceptions.OoasCompilerRuntimeException; |
40 |
|
41 |
public abstract class UlyssesType extends AstNode implements IAst |
42 |
{ |
43 |
private String m_origAnonName; |
44 |
protected TypeKind m_kind;
|
45 |
protected TypeIdentifier m_identifier;
|
46 |
protected int m_hash; |
47 |
// protected long TimeStamp = DateTime.Now.Ticks;
|
48 |
|
49 |
|
50 |
public TypeKind kind() { return m_kind; } |
51 |
|
52 |
public TypeIdentifier identifier() {
|
53 |
synchronized(this) { |
54 |
if (m_identifier == null) |
55 |
SetupAnonymousName(); |
56 |
} |
57 |
return m_identifier;
|
58 |
} |
59 |
|
60 |
public boolean isAnonymousType() { |
61 |
final String anonName = AnonymousName(); |
62 |
if (!m_origAnonName.equals(anonName))
|
63 |
throw new OoasCompilerRuntimeException("Internal Error: Anonymous Name changed from '%s' to '%s'.", m_origAnonName, anonName); |
64 |
return anonName.equals(m_identifier.tokenText());
|
65 |
} |
66 |
|
67 |
protected UlyssesType(TypeKind aKind, TypeIdentifier anIdentifier)
|
68 |
{ |
69 |
m_kind = aKind; |
70 |
m_identifier = anIdentifier; |
71 |
m_hash = aKind.toString().hashCode(); //Enum.GetName(typeof(TypeKind), aKind).GetHashCode();
|
72 |
} |
73 |
|
74 |
@Override
|
75 |
public /*override*/ String toString() |
76 |
{ |
77 |
return identifier().tokenText();
|
78 |
} |
79 |
|
80 |
public /*virtual*/ String AnonymousName() |
81 |
{ |
82 |
throw new NotImplementedException(); |
83 |
} |
84 |
|
85 |
|
86 |
public void SetTypeIdentifier(TypeIdentifier anId) |
87 |
{ |
88 |
m_identifier = anId; |
89 |
} |
90 |
|
91 |
public void SetupAnonymousName() |
92 |
{ |
93 |
if (m_identifier == null) |
94 |
{ |
95 |
final String anonymousName = this.AnonymousName(); |
96 |
m_identifier = new TypeIdentifier(anonymousName, this, null); |
97 |
m_origAnonName = anonymousName; |
98 |
} |
99 |
} |
100 |
|
101 |
|
102 |
@Override
|
103 |
public AstNodeTypeEnum nodeType() { return AstNodeTypeEnum.type; } |
104 |
|
105 |
@Override
|
106 |
public void Accept(IAstVisitor visitor) |
107 |
{ |
108 |
throw new NotImplementedException(); |
109 |
} |
110 |
|
111 |
|
112 |
|
113 |
public boolean IsNumeric() |
114 |
{ |
115 |
final Object o = this; |
116 |
return (m_kind == TypeKind.IntType) ||
|
117 |
(m_kind == TypeKind.FloatType) || |
118 |
(m_kind == TypeKind.EnumeratedType && o instanceof ValuedEnumType);
|
119 |
} |
120 |
|
121 |
public boolean IsQualitative() |
122 |
{ |
123 |
return (m_kind == TypeKind.QrType);
|
124 |
} |
125 |
|
126 |
/**
|
127 |
* returns the number of unique values of the type (2 for bool, etc..)
|
128 |
*/
|
129 |
public int valueCount() { |
130 |
throw new NotImplementedException(); // must be overridden by child |
131 |
} |
132 |
|
133 |
public static String High(UlyssesType atype) |
134 |
{ |
135 |
switch (atype.kind())
|
136 |
{ |
137 |
case BoolType:
|
138 |
return "1"; |
139 |
case EnumeratedType:
|
140 |
return Integer.toString((((EnumType)atype).listOfEnumSymbols().size() - 1)); |
141 |
case IntType:
|
142 |
return Integer.toString(((IntType)atype).rangeHigh()); |
143 |
case FloatType:
|
144 |
return Double.toString(((FloatType)atype).high()); |
145 |
// case TypeKind.QrType:
|
146 |
// return (((QrType)atype).landmarks.Count - 1).ToString();
|
147 |
default:
|
148 |
throw new NotImplementedException(); |
149 |
} |
150 |
} |
151 |
|
152 |
public static String Low(UlyssesType atype) |
153 |
{ |
154 |
switch (atype.kind())
|
155 |
{ |
156 |
case BoolType:
|
157 |
return "0"; |
158 |
case EnumeratedType:
|
159 |
return "0"; |
160 |
case IntType:
|
161 |
return Integer.toString(((IntType)atype).rangeLow()); |
162 |
case FloatType:
|
163 |
return Double.toString(((FloatType)atype).low()); |
164 |
// case TypeKind.QrType:
|
165 |
// return "0";
|
166 |
default:
|
167 |
throw new NotImplementedException(); |
168 |
} |
169 |
} |
170 |
|
171 |
|
172 |
/// <summary>
|
173 |
/// Returns a cover for two types (if possible).
|
174 |
/// note the cover type for two ints, floats, etc. will have max/min values
|
175 |
/// that reflect the maximum of the two operands.
|
176 |
/// </summary>
|
177 |
|
178 |
public static UlyssesType CoverType(UlyssesType type1, UlyssesType type2) |
179 |
{ |
180 |
/*first some sanity checks*/
|
181 |
if (type1 == null) |
182 |
throw new ArgumentException("type1 null"); |
183 |
if (type2 == null) |
184 |
throw new ArgumentException("type2 null"); |
185 |
|
186 |
if (type1.kind() == TypeKind.OpaqueType)
|
187 |
throw new ArgumentException("type1 opaque type"); |
188 |
if (type2.kind() == TypeKind.OpaqueType)
|
189 |
throw new ArgumentException("type2 opaque type"); |
190 |
|
191 |
if (type1 == type2)
|
192 |
return type1;
|
193 |
if (UlyssesType.TypeEqual(type1, type2))
|
194 |
return type1;
|
195 |
|
196 |
final TypeKind tk1 = type1.kind();
|
197 |
final TypeKind tk2 = type2.kind();
|
198 |
|
199 |
|
200 |
|
201 |
if (tk1 != tk2)
|
202 |
{ |
203 |
// the only notion we support here is int->float and valenum -> int
|
204 |
if ((tk1 == TypeKind.IntType || tk2 == TypeKind.IntType)
|
205 |
&& (tk1 == TypeKind.FloatType || tk2 == TypeKind.FloatType)) |
206 |
{ |
207 |
final IntType aInt = tk1 == TypeKind.IntType ? (IntType)type1 : (IntType)type2;
|
208 |
final FloatType aFloat = tk1 == TypeKind.IntType ? (FloatType)type2 : (FloatType)type1;
|
209 |
|
210 |
final double low = aInt.rangeLow() < aFloat.low() ? (double)aInt.rangeLow() : aFloat.low(); |
211 |
final double high = aInt.rangeHigh() < aFloat.high() ? aFloat.high() : (double)aInt.rangeHigh(); |
212 |
final double precision = aFloat.precision() > 1 ? 1.0 : aFloat.precision(); |
213 |
|
214 |
return new FloatType(low, high, precision, null); |
215 |
|
216 |
} |
217 |
else if ((tk1 == TypeKind.IntType || tk2 == TypeKind.IntType) |
218 |
&& (tk1 == TypeKind.EnumeratedType || tk2 == TypeKind.EnumeratedType)) |
219 |
{ |
220 |
final IntType intt1 = tk1 == TypeKind.IntType ? (IntType)type1 : (IntType)type2;
|
221 |
final EnumType anEnum = tk1 == TypeKind.IntType ? (EnumType)type2 : (EnumType)type1;
|
222 |
|
223 |
if (anEnum instanceof ValuedEnumType) |
224 |
{ |
225 |
final IntType intt2 = ((ValuedEnumType)anEnum).getIntType();
|
226 |
final int low = intt1.rangeLow() < intt2.rangeLow() ? intt1.rangeLow() : intt2.rangeLow(); |
227 |
final int high = intt1.rangeHigh() > intt2.rangeHigh() ? intt1.rangeHigh() : intt2.rangeHigh(); |
228 |
return new IntType(low, high, null); |
229 |
} |
230 |
else
|
231 |
return null; |
232 |
} |
233 |
else if (tk1 == TypeKind.Any || tk2 == TypeKind.Any) |
234 |
{ |
235 |
final AnyType freeVar = tk1 == TypeKind.Any ? (AnyType)type1 : (AnyType)type2;
|
236 |
final UlyssesType fixedType = tk1 == TypeKind.Any ? type2 : type1;
|
237 |
final UlyssesType newcover = freeVar.VariableIdentifier().type().kind() == TypeKind.Any
|
238 |
? fixedType : CoverType(fixedType, freeVar.VariableIdentifier().type()); |
239 |
freeVar.VariableIdentifier().SetType(newcover); |
240 |
return newcover;
|
241 |
} |
242 |
else if (tk1 == TypeKind.OoActionSystemType && tk2 == TypeKind.Null) |
243 |
{ |
244 |
return type1;
|
245 |
} |
246 |
else if (tk2 == TypeKind.OoActionSystemType && tk1 == TypeKind.Null) |
247 |
{ |
248 |
return type2;
|
249 |
} |
250 |
|
251 |
else
|
252 |
return null; |
253 |
} |
254 |
else
|
255 |
{ |
256 |
switch (tk1)
|
257 |
{ |
258 |
case Any:
|
259 |
return type1;
|
260 |
|
261 |
case IntType:
|
262 |
final IntType intt1 = (IntType)type1;
|
263 |
final IntType intt2 = (IntType)type2;
|
264 |
final int low = intt1.rangeLow() < intt2.rangeLow() ? intt1.rangeLow() : intt2.rangeLow(); |
265 |
final int high = intt1.rangeHigh() > intt2.rangeHigh() ? intt1.rangeHigh() : intt2.rangeHigh(); |
266 |
return new IntType(low, high, null); |
267 |
case BoolType:
|
268 |
return type1;
|
269 |
case FloatType:
|
270 |
final FloatType floatt1 = (FloatType)type1;
|
271 |
final FloatType floatt2 = (FloatType)type2;
|
272 |
final double flow = floatt1.low() < floatt2.low() ? floatt1.low() : floatt2.low(); |
273 |
final double fhigh = floatt1.high() > floatt2.high() ? floatt1.high() : floatt2.high(); |
274 |
final double fprec = floatt1.precision() < floatt2.precision() ? floatt1.precision() : floatt2.precision(); |
275 |
return new FloatType(flow, fhigh, fprec, null); |
276 |
case EnumeratedType:
|
277 |
return null; |
278 |
case ListType:
|
279 |
final ListType listt1 = (ListType)type1;
|
280 |
final ListType listt2 = (ListType)type2;
|
281 |
int maxelems = listt1.maxNumberOfElements() > listt2.maxNumberOfElements() ?
|
282 |
listt1.maxNumberOfElements() : listt2.maxNumberOfElements(); |
283 |
// empty lists lack type, so take the other one
|
284 |
if ((listt1.innerType().kind() == TypeKind.Null) && (listt2.innerType().kind() != TypeKind.Null))
|
285 |
return listt2;
|
286 |
else if ((listt2.innerType().kind() == TypeKind.Null) && (listt1.innerType().kind() != TypeKind.Null)) |
287 |
return listt1;
|
288 |
else if (listt1.innerType().kind() == TypeKind.Null && listt2.innerType().kind() == TypeKind.Null) |
289 |
return listt1;
|
290 |
else
|
291 |
{ |
292 |
final UlyssesType subtype = UlyssesType.CoverType(listt1.innerType(), listt2.innerType());
|
293 |
if (subtype != null) |
294 |
return new ListType(subtype, maxelems, null); |
295 |
else
|
296 |
return null; |
297 |
} |
298 |
case MapType:
|
299 |
final MapType mapt1 = (MapType)type1;
|
300 |
final MapType mapt2 = (MapType)type2;
|
301 |
// empty maps lack type, so take the other one.
|
302 |
if ((mapt1.fromType().kind() == TypeKind.Null && mapt1.toType().kind() == TypeKind.Null)
|
303 |
&& (mapt2.fromType().kind() != TypeKind.Null && mapt2.toType().kind() != TypeKind.Null)) |
304 |
return mapt2;
|
305 |
else if ((mapt2.fromType().kind() == TypeKind.Null && mapt2.toType().kind() == TypeKind.Null) |
306 |
&& (mapt1.fromType().kind() != TypeKind.Null && mapt1.toType().kind() != TypeKind.Null)) |
307 |
return mapt1;
|
308 |
else if ((mapt2.fromType().kind() == TypeKind.Null && mapt2.toType().kind() == TypeKind.Null) |
309 |
&& (mapt1.fromType().kind() == TypeKind.Null && mapt1.toType().kind() == TypeKind.Null)) |
310 |
return mapt1;
|
311 |
else
|
312 |
{ |
313 |
final UlyssesType sub1 = UlyssesType.CoverType(mapt1.fromType(), mapt2.fromType());
|
314 |
final UlyssesType sub2 = UlyssesType.CoverType(mapt2.toType(), mapt2.toType());
|
315 |
maxelems = mapt1.maxNumberOfElements() > mapt2.maxNumberOfElements() ? |
316 |
mapt1.maxNumberOfElements() : mapt2.maxNumberOfElements(); |
317 |
if (sub1 != null && sub2 != null) |
318 |
return new MapType(sub1, sub2, maxelems, null); |
319 |
else
|
320 |
return null; |
321 |
} |
322 |
case QrType:
|
323 |
return null; /*if refs are equal, we do not reach this statement! see above..*/ |
324 |
case TupleType:
|
325 |
final TupleType tuplet1 = (TupleType)type1;
|
326 |
final TupleType tuplet2 = (TupleType)type2;
|
327 |
final TupleType result = new TupleType(null); |
328 |
final Iterator<UlyssesType> innert1 = tuplet1.innerTypes().iterator(); |
329 |
final Iterator<UlyssesType> innert2 = tuplet2.innerTypes().iterator(); |
330 |
while (innert1.hasNext())
|
331 |
{ |
332 |
final UlyssesType newinner = UlyssesType.CoverType(innert1.next(), innert2.next());
|
333 |
if (newinner == null) |
334 |
return null; |
335 |
result.AddType(newinner); |
336 |
} |
337 |
return result;
|
338 |
case OoActionSystemType:
|
339 |
if (type1.kind() == TypeKind.Null && type2.kind() != TypeKind.Null)
|
340 |
return type2;
|
341 |
else if (type2.kind() == TypeKind.Null && type1.kind() != TypeKind.Null) |
342 |
return type1;
|
343 |
else if (type1.kind() == TypeKind.Null && type2.kind() == TypeKind.Null) |
344 |
return type2;
|
345 |
else if (type1 == type2) // ref equals! |
346 |
return type1;
|
347 |
else
|
348 |
return ClassBaseType((OoActionSystemType)type1, (OoActionSystemType)type2);
|
349 |
case OpaqueType:
|
350 |
assert(false); |
351 |
return null; |
352 |
default:
|
353 |
throw new NotImplementedException(); |
354 |
} |
355 |
} |
356 |
} |
357 |
|
358 |
private static UlyssesType ClassBaseType(OoActionSystemType type1, OoActionSystemType type2) |
359 |
{ |
360 |
// this is rather inefficient.. should be done differently
|
361 |
final OoActionSystemType typea = type1;
|
362 |
final OoActionSystemType typeb = type2;
|
363 |
OoActionSystemType basea = type1; |
364 |
OoActionSystemType baseb = type2; |
365 |
while (basea != null) |
366 |
{ |
367 |
if (basea == typeb) // ref equals |
368 |
return basea;
|
369 |
basea = basea.baseType(); |
370 |
} |
371 |
while (baseb != null) |
372 |
{ |
373 |
if (baseb == typea) // ref equals |
374 |
return baseb;
|
375 |
baseb = baseb.baseType(); |
376 |
} |
377 |
return null; |
378 |
} |
379 |
|
380 |
public static boolean FirstTypeLessRange(UlyssesType type1, UlyssesType type2) |
381 |
{ |
382 |
final TypeKind tk1 = type1.kind();
|
383 |
final TypeKind tk2 = type2.kind();
|
384 |
|
385 |
if (tk1 != tk2)
|
386 |
throw new ArgumentException("Types need to be equal"); |
387 |
|
388 |
switch (tk1)
|
389 |
{ |
390 |
case Any:
|
391 |
return false; |
392 |
case IntType:
|
393 |
final IntType Int1 = (IntType)type1;
|
394 |
final IntType Int2 = (IntType)type2;
|
395 |
return Int1.rangeLow() > Int2.rangeLow() ||
|
396 |
Int1.rangeHigh() < Int2.rangeHigh(); |
397 |
case BoolType:
|
398 |
return false; |
399 |
case FloatType:
|
400 |
final FloatType Float1 = (FloatType)type1;
|
401 |
final FloatType Float2 = (FloatType)type2;
|
402 |
return Float1.low() > Float2.low()
|
403 |
|| Float1.high() < Float2.high() |
404 |
|| Float1.precision() > Float2.precision(); |
405 |
case EnumeratedType:
|
406 |
return false; |
407 |
case ListType:
|
408 |
final ListType listt1 = (ListType)type1;
|
409 |
final ListType listt2 = (ListType)type2;
|
410 |
return (listt1.maxNumberOfElements() < listt2.maxNumberOfElements()) ||
|
411 |
UlyssesType.FirstTypeLessRange(listt1.innerType(), listt2.innerType()); |
412 |
case MapType:
|
413 |
final MapType mapt1 = (MapType)type1;
|
414 |
final MapType mapt2 = (MapType)type2;
|
415 |
return (mapt1.maxNumberOfElements() < mapt2.maxNumberOfElements()) ||
|
416 |
UlyssesType.FirstTypeLessRange(mapt1.fromType(), mapt2.fromType()) || |
417 |
UlyssesType.FirstTypeLessRange(mapt1.toType(), mapt2.toType()); |
418 |
case QrType:
|
419 |
return false; |
420 |
case TupleType:
|
421 |
final TupleType tuplet1 = (TupleType)type1;
|
422 |
final TupleType tuplet2 = (TupleType)type2;
|
423 |
if (tuplet1.innerTypes().size() != tuplet2.innerTypes().size())
|
424 |
return false; |
425 |
final Iterator<UlyssesType> innert1 = tuplet1.innerTypes().iterator(); |
426 |
final Iterator<UlyssesType> innert2 = tuplet2.innerTypes().iterator(); |
427 |
while (innert1.hasNext())
|
428 |
{ |
429 |
if (UlyssesType.FirstTypeLessRange(innert1.next(), innert2.next()))
|
430 |
return true; |
431 |
} |
432 |
return false; |
433 |
case OoActionSystemType:
|
434 |
return false; |
435 |
case OpaqueType:
|
436 |
assert(false); |
437 |
return false; |
438 |
default:
|
439 |
throw new NotImplementedException(); |
440 |
} |
441 |
} |
442 |
|
443 |
public static boolean TypeEqualByKind(UlyssesType type1, UlyssesType type2) |
444 |
{ |
445 |
if ((type1 == null) || (type2 == null)) |
446 |
return false; |
447 |
|
448 |
final TypeKind tk1 = type1.kind();
|
449 |
final TypeKind tk2 = type2.kind();
|
450 |
|
451 |
// if of different kind, then return false..
|
452 |
if (tk1 != tk2)
|
453 |
return false; |
454 |
|
455 |
// if same kind, make a rigorous check
|
456 |
switch (tk1)
|
457 |
{ |
458 |
case Any:
|
459 |
return true; |
460 |
|
461 |
case IntType:
|
462 |
case BoolType:
|
463 |
case FloatType:
|
464 |
return true; |
465 |
case EnumeratedType:
|
466 |
return type1 == type2; // ref equals |
467 |
case ListType:
|
468 |
final ListType listt1 = (ListType)type1;
|
469 |
final ListType listt2 = (ListType)type2;
|
470 |
return UlyssesType.TypeEqualByKind(listt1.innerType(), listt2.innerType());
|
471 |
case MapType:
|
472 |
final MapType mapt1 = (MapType)type1;
|
473 |
final MapType mapt2 = (MapType)type2;
|
474 |
return UlyssesType.TypeEqualByKind(mapt1.fromType(), mapt2.fromType()) &&
|
475 |
UlyssesType.TypeEqualByKind(mapt1.toType(), mapt2.toType()); |
476 |
case QrType:
|
477 |
final QrType qr1 = (QrType)type1;
|
478 |
final QrType qr2 = (QrType)type2;
|
479 |
return qr1 == qr2; // ref equals |
480 |
case TupleType:
|
481 |
final TupleType tuplet1 = (TupleType)type1;
|
482 |
final TupleType tuplet2 = (TupleType)type2;
|
483 |
if (tuplet1.innerTypes().size() != tuplet2.innerTypes().size())
|
484 |
return false; |
485 |
final Iterator<UlyssesType> innert1 = tuplet1.innerTypes().iterator(); |
486 |
final Iterator<UlyssesType> innert2 = tuplet2.innerTypes().iterator(); |
487 |
while (innert1.hasNext())
|
488 |
{ |
489 |
if (!UlyssesType.TypeEqualByKind(innert1.next(), innert2.next()))
|
490 |
return false; |
491 |
} |
492 |
return true; |
493 |
case OoActionSystemType:
|
494 |
return type1 == type2; // ref equ. |
495 |
case OpaqueType:
|
496 |
assert(false); |
497 |
return false; |
498 |
default:
|
499 |
throw new NotImplementedException(); |
500 |
} |
501 |
} |
502 |
|
503 |
|
504 |
public static boolean TypeEqual(UlyssesType type1, UlyssesType type2) |
505 |
{ |
506 |
// this will also work with opaque types...
|
507 |
while (type1 instanceof OpaqueType) |
508 |
type1 = ((OpaqueType)type1).resolvedType(); |
509 |
while (type2 instanceof OpaqueType) |
510 |
type2 = ((OpaqueType)type2).resolvedType(); |
511 |
|
512 |
if ((type1 == null) || (type2 == null)) |
513 |
return false; |
514 |
|
515 |
final TypeKind tk1 = type1.kind();
|
516 |
final TypeKind tk2 = type2.kind();
|
517 |
|
518 |
// if of different kind, then return false..
|
519 |
if (tk1 != tk2)
|
520 |
return false; |
521 |
|
522 |
// if same kind, make a rigorous check
|
523 |
switch (tk1)
|
524 |
{ |
525 |
case IntType:
|
526 |
final IntType intt1 = (IntType)type1;
|
527 |
final IntType intt2 = (IntType)type2;
|
528 |
return intt1.rangeLow() == intt2.rangeLow() &&
|
529 |
intt1.rangeHigh() == intt2.rangeHigh(); |
530 |
case BoolType:
|
531 |
return true; |
532 |
case FloatType:
|
533 |
final FloatType floatt1 = (FloatType)type1;
|
534 |
final FloatType floatt2 = (FloatType)type2;
|
535 |
return floatt1.low() == floatt2.low() &&
|
536 |
floatt1.high() == floatt2.high() && |
537 |
floatt1.precision() == floatt2.precision(); |
538 |
case EnumeratedType:
|
539 |
return type1 == type2; // ref equ |
540 |
case ListType:
|
541 |
final ListType listt1 = (ListType)type1;
|
542 |
final ListType listt2 = (ListType)type2;
|
543 |
// an empty list can be of any type..
|
544 |
/*if ((listt1.innerType.kind == TypeKind.Null) || (listt2.innerType.kind == TypeKind.Null))
|
545 |
return true;
|
546 |
else*/
|
547 |
return UlyssesType.TypeEqual(listt1.innerType(), listt2.innerType()) &&
|
548 |
listt1.maxNumberOfElements() == listt2.maxNumberOfElements(); // need this because of covertype
|
549 |
case MapType:
|
550 |
final MapType mapt1 = (MapType)type1;
|
551 |
final MapType mapt2 = (MapType)type2;
|
552 |
return UlyssesType.TypeEqual(mapt1.fromType(), mapt2.fromType()) &&
|
553 |
UlyssesType.TypeEqual(mapt1.toType(), mapt2.toType()) && |
554 |
mapt1.maxNumberOfElements() == mapt2.maxNumberOfElements(); // need this because of covertype
|
555 |
case QrType:
|
556 |
final QrType qr1 = (QrType)type1;
|
557 |
final QrType qr2 = (QrType)type2;
|
558 |
return qr1 == qr2; // ref equ. |
559 |
case TupleType:
|
560 |
final TupleType tuplet1 = (TupleType)type1;
|
561 |
final TupleType tuplet2 = (TupleType)type2;
|
562 |
if (tuplet1.innerTypes().size() != tuplet2.innerTypes().size())
|
563 |
return false; |
564 |
final Iterator<UlyssesType> innert1 = tuplet1.innerTypes().iterator(); |
565 |
final Iterator<UlyssesType> innert2 = tuplet2.innerTypes().iterator(); |
566 |
while (innert1.hasNext())
|
567 |
{ |
568 |
if (!UlyssesType.TypeEqual(innert1.next(), innert2.next()))
|
569 |
return false; |
570 |
} |
571 |
return true; |
572 |
case OoActionSystemType:
|
573 |
return type1 == type2; // ref equ. // || Covariance((OoActionSystemType)type1, (OoActionSystemType)type2); |
574 |
case OpaqueType:
|
575 |
assert(false); |
576 |
return false; |
577 |
case Null:
|
578 |
case Any:
|
579 |
return true; |
580 |
default:
|
581 |
throw new NotImplementedException(); |
582 |
} |
583 |
} |
584 |
|
585 |
/// <summary>
|
586 |
/// checks if type 2 is a desc. of type 1
|
587 |
/// </summary>
|
588 |
public static boolean Covariance(OoActionSystemType ooActionSystemType, OoActionSystemType ooActionSystemType_2) |
589 |
{ |
590 |
// check if type 2 is a desc. of type 1
|
591 |
while (ooActionSystemType != ooActionSystemType_2 && ooActionSystemType_2.baseType() != null) // ref equ. |
592 |
ooActionSystemType_2 = ooActionSystemType_2.baseType(); |
593 |
|
594 |
return ooActionSystemType == ooActionSystemType_2; // ref equ. |
595 |
} |
596 |
} |