Project

General

Profile

root / branches / compiler / cSharp / ooasCompiler / src / parser / ooaTypes.cs @ 3

1
/**
2
  *
3
  *                      OOAS Compiler (Deprecated)
4
  *
5
  * Copyright 2015, Institute for Software Technology, Graz University of
6
  * Technology. Portions are copyright 2015 by the AIT Austrian Institute
7
  * of Technology. All rights reserved.
8
  *
9
  * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
10
  *
11
  * Please notice that this version of the OOAS compiler is considered de-
12
  * precated. Only the Java version is maintained.
13
  *
14
  * Contributors:
15
  *               Willibald Krenn (TU Graz/AIT)
16
  *               Stefan Tiran (TU Graz/AIT)
17
  */
18

    
19
using System;
20
using System.Collections.Generic;
21
using System.Text;
22
using System.Globalization;
23
using TUG.Mogentes.Codegen;
24

    
25
namespace TUG.Mogentes
26
{
27

    
28
    public enum TypeKind
29
    {
30
        IntType,
31
        BoolType,
32
        FloatType,
33
        EnumeratedType,
34
        ListType,
35
        MapType,
36
        QrType,
37
        TupleType,
38
        FunctionType,
39
        OoActionSystemType,
40
        OpaqueType,
41
        Null, Any
42
    }
43

    
44
    public abstract class UlyssesType : UlyssesBasicClass, IAst
45
    {
46
        protected TypeKind m_kind;
47
        protected TypeIdentifier m_identifier;
48
        protected int m_hash;
49
        protected long TimeStamp = DateTime.Now.Ticks;
50

    
51

    
52
        public TypeKind kind { get { return m_kind; } }
53
        public TypeIdentifier identifier { get { lock (this) { if (m_identifier == null)  SetupAnonymousName(); } return m_identifier; } }
54
        public bool isAnonymousType { get { return AnonymousName() == m_identifier.tokenText; } }
55

    
56
        protected UlyssesType(TypeKind aKind, TypeIdentifier anIdentifier)
57
            : base()
58
        {
59
            m_kind = aKind;
60
            m_identifier = anIdentifier;
61
            m_hash = Enum.GetName(typeof(TypeKind), aKind).GetHashCode();
62
        }
63

    
64
        public override string ToString()
65
        {
66
            return identifier.tokenText;
67
        }
68

    
69
        public virtual string AnonymousName()
70
        {
71
            throw new NotImplementedException();
72
        }
73

    
74

    
75
        public void SetTypeIdentifier(TypeIdentifier anId)
76
        {
77
            m_identifier = anId;
78
        }
79

    
80
        public void SetupAnonymousName()
81
        {
82
            if (m_identifier == null)
83
            {
84
                string anonymousName = this.AnonymousName();
85
                m_identifier = new TypeIdentifier(anonymousName, this, null);
86
            }
87
        }
88

    
89

    
90
        #region IAst Member
91
        public AstNodeTypeEnum nodeType { get { return AstNodeTypeEnum.type; } }
92

    
93
        public virtual void Accept(IAstVisitor visitor)
94
        {
95
            throw new NotImplementedException();
96
        }
97

    
98
        #endregion
99

    
100

    
101
        public bool IsNumeric()
102
        {
103
            return (m_kind == TypeKind.IntType) ||
104
                   (m_kind == TypeKind.FloatType) ||
105
                   (m_kind == TypeKind.EnumeratedType && this is ValuedEnumType);
106
        }
107

    
108
        public bool IsQualitative()
109
        {
110
            return (m_kind == TypeKind.QrType);
111
        }
112

    
113

    
114

    
115
        public static string High(UlyssesType atype)
116
        {
117
            switch (atype.kind)
118
            {
119
                case TypeKind.BoolType:
120
                    return "1";
121
                case TypeKind.EnumeratedType:
122
                    return (((EnumType)atype).listOfEnumSymbols.Count - 1).ToString();
123
                case TypeKind.IntType:
124
                    return ((IntType)atype).rangeHigh.ToString();
125
                case TypeKind.FloatType:
126
                    return ((FloatType)atype).high.ToString();
127
                //                case TypeKind.QrType:
128
                //                    return (((QrType)atype).landmarks.Count - 1).ToString();
129
                default:
130
                    throw new NotImplementedException();
131
            }
132
        }
133

    
134
        public static string Low(UlyssesType atype)
135
        {
136
            switch (atype.kind)
137
            {
138
                case TypeKind.BoolType:
139
                    return "0";
140
                case TypeKind.EnumeratedType:
141
                    return "0";
142
                case TypeKind.IntType:
143
                    return ((IntType)atype).rangeLow.ToString();
144
                case TypeKind.FloatType:
145
                    return ((FloatType)atype).low.ToString();
146
                //                case TypeKind.QrType:
147
                //                    return "0";
148
                default:
149
                    throw new NotImplementedException();
150
            }
151
        }
152

    
153

    
154
        /// <summary>
155
        ///  Returns a cover for two types (if possible).
156
        ///  note the cover type for two ints, floats, etc. will have max/min values
157
        ///  that reflect the maximum of the two operands. 
158
        /// </summary>
159

    
160
        public static UlyssesType CoverType(UlyssesType type1, UlyssesType type2)
161
        {
162
            /*first some sanity checks*/
163
            if (type1 == null)
164
                throw new ArgumentException("type1 null");
165
            if (type2 == null)
166
                throw new ArgumentException("type2 null");
167

    
168
            if (type1.kind == TypeKind.OpaqueType)
169
                throw new ArgumentException("type1 opaque type");
170
            if (type2.kind == TypeKind.OpaqueType)
171
                throw new ArgumentException("type2 opaque type");
172

    
173
            if (ReferenceEquals(type1, type2))
174
                return type1;
175
            if (UlyssesType.TypeEqual(type1, type2))
176
                return type1;
177

    
178
            TypeKind tk1 = type1.kind;
179
            TypeKind tk2 = type2.kind;
180

    
181

    
182

    
183
            if (tk1 != tk2)
184
            {
185
                // the only notion we support here is int->float and valenum -> int
186
                if ((tk1 == TypeKind.IntType || tk2 == TypeKind.IntType)
187
                    && (tk1 == TypeKind.FloatType || tk2 == TypeKind.FloatType))
188
                {
189
                    IntType aInt = tk1 == TypeKind.IntType ? (IntType)type1 : (IntType)type2;
190
                    FloatType aFloat = tk1 == TypeKind.IntType ? (FloatType)type2 : (FloatType)type1;
191

    
192
                    double low = (double)aInt.rangeLow < aFloat.low ? (double)aInt.rangeLow : aFloat.low;
193
                    double high = (double)aInt.rangeHigh < aFloat.high ? aFloat.high : (double)aInt.rangeHigh;
194
                    double precision = aFloat.precision > 1 ? 1.0 : aFloat.precision;
195

    
196
                    return new FloatType(low, high, precision, null);
197

    
198
                }
199
                else if ((tk1 == TypeKind.IntType || tk2 == TypeKind.IntType)
200
                    && (tk1 == TypeKind.EnumeratedType || tk2 == TypeKind.EnumeratedType))
201
                {
202
                    IntType intt1 = tk1 == TypeKind.IntType ? (IntType)type1 : (IntType)type2;
203
                    EnumType anEnum = tk1 == TypeKind.IntType ? (EnumType)type2 : (EnumType)type1;
204

    
205
                    if (anEnum is ValuedEnumType)
206
                    {
207
                        IntType intt2 = (IntType)((ValuedEnumType)anEnum).getIntType();
208
                        int low = intt1.rangeLow < intt2.rangeLow ? intt1.rangeLow : intt2.rangeLow;
209
                        int high = intt1.rangeHigh > intt2.rangeHigh ? intt1.rangeHigh : intt2.rangeHigh;
210
                        return new IntType(low, high, null);
211
                    }
212
                    else
213
                        return null;
214
                }
215
                else if (tk1 == TypeKind.Any || tk2 == TypeKind.Any)
216
                {
217
                    AnyType freeVar = tk1 == TypeKind.Any ? (AnyType)type1 : (AnyType)type2;
218
                    UlyssesType fixedType = tk1 == TypeKind.Any ? type2 : type1;
219
                    UlyssesType newcover = freeVar.VariableIdentifier.type.kind == TypeKind.Any
220
                        ? fixedType : CoverType(fixedType, freeVar.VariableIdentifier.type);
221
                    freeVar.VariableIdentifier.SetType(newcover);
222
                    return newcover;
223
                }
224
                else if (tk1 == TypeKind.OoActionSystemType && tk2 == TypeKind.Null)
225
                {
226
                    return type1;
227
                }
228
                else if (tk2 == TypeKind.OoActionSystemType && tk1 == TypeKind.Null)
229
                {
230
                    return type2;
231
                }
232

    
233
                else
234
                    return null;
235
            }
236
            else
237
            {
238
                switch (tk1)
239
                {
240
                    case TypeKind.Any:
241
                        return type1;
242

    
243
                    case TypeKind.IntType:
244
                        IntType intt1 = (IntType)type1;
245
                        IntType intt2 = (IntType)type2;
246
                        int low = intt1.rangeLow < intt2.rangeLow ? intt1.rangeLow : intt2.rangeLow;
247
                        int high = intt1.rangeHigh > intt2.rangeHigh ? intt1.rangeHigh : intt2.rangeHigh;
248
                        return new IntType(low, high, null);
249
                    case TypeKind.BoolType:
250
                        return type1;
251
                    case TypeKind.FloatType:
252
                        FloatType floatt1 = (FloatType)type1;
253
                        FloatType floatt2 = (FloatType)type2;
254
                        double flow = floatt1.low < floatt2.low ? floatt1.low : floatt2.low;
255
                        double fhigh = floatt1.high > floatt2.high ? floatt1.high : floatt2.high;
256
                        double fprec = floatt1.precision < floatt2.precision ? floatt1.precision : floatt2.precision;
257
                        return new FloatType(flow, fhigh, fprec, null);
258
                    case TypeKind.EnumeratedType:
259
                        return null;
260
                    case TypeKind.ListType:
261
                        ListType listt1 = (ListType)type1;
262
                        ListType listt2 = (ListType)type2;
263
                        int maxelems = listt1.maxNumberOfElements > listt2.maxNumberOfElements ?
264
                            listt1.maxNumberOfElements : listt2.maxNumberOfElements;
265
                        // empty lists lack type, so take the other one
266
                        if ((listt1.innerType.kind == TypeKind.Null) && (listt2.innerType.kind != TypeKind.Null))
267
                            return listt2;
268
                        else if ((listt2.innerType.kind == TypeKind.Null) && (listt1.innerType.kind != TypeKind.Null))
269
                            return listt1;
270
                        else if (listt1.innerType.kind == TypeKind.Null && listt2.innerType.kind == TypeKind.Null)
271
                            return listt1;
272
                        else
273
                        {
274
                            UlyssesType subtype = UlyssesType.CoverType(listt1.innerType, listt2.innerType);
275
                            if (subtype != null)
276
                                return new ListType(subtype, maxelems, null);
277
                            else
278
                                return null;
279
                        }
280
                    case TypeKind.MapType:
281
                        MapType mapt1 = (MapType)type1;
282
                        MapType mapt2 = (MapType)type2;
283
                        // empty maps lack type, so take the other one.
284
                        if ((mapt1.fromType.kind == TypeKind.Null && mapt1.toType.kind == TypeKind.Null)
285
                             && (mapt2.fromType.kind != TypeKind.Null && mapt2.toType.kind != TypeKind.Null))
286
                            return mapt2;
287
                        else if ((mapt2.fromType.kind == TypeKind.Null && mapt2.toType.kind == TypeKind.Null)
288
                                 && (mapt1.fromType.kind != TypeKind.Null && mapt1.toType.kind != TypeKind.Null))
289
                            return mapt1;
290
                        else if ((mapt2.fromType.kind == TypeKind.Null && mapt2.toType.kind == TypeKind.Null)
291
                                 && (mapt1.fromType.kind == TypeKind.Null && mapt1.toType.kind == TypeKind.Null))
292
                            return mapt1;
293
                        else
294
                        {
295
                            UlyssesType sub1 = UlyssesType.CoverType(mapt1.fromType, mapt2.fromType);
296
                            UlyssesType sub2 = UlyssesType.CoverType(mapt2.toType, mapt2.toType);
297
                            maxelems = mapt1.maxNumberOfElements > mapt2.maxNumberOfElements ?
298
                                mapt1.maxNumberOfElements : mapt2.maxNumberOfElements;
299
                            if (sub1 != null && sub2 != null)
300
                                return new MapType(sub1, sub2, maxelems, null);
301
                            else
302
                                return null;
303
                        }
304
                    case TypeKind.QrType:
305
                        return null; /*if refs are equal, we do not reach this statement! see above..*/
306
                    case TypeKind.TupleType:
307
                        TupleType tuplet1 = (TupleType)type1;
308
                        TupleType tuplet2 = (TupleType)type2;
309
                        TupleType result = new TupleType(null);
310
                        LinkedListNode<UlyssesType> innert1 = tuplet1.innerTypes.First;
311
                        LinkedListNode<UlyssesType> innert2 = tuplet2.innerTypes.First;
312
                        while (innert1 != null)
313
                        {
314
                            UlyssesType newinner = UlyssesType.CoverType(innert1.Value, innert2.Value);
315
                            if (newinner == null)
316
                                return null;
317
                            result.AddType(newinner);
318

    
319
                            innert1 = innert1.Next;
320
                            innert2 = innert2.Next;
321
                        }
322
                        return result;
323
                    case TypeKind.OoActionSystemType:
324
                        if (type1.kind == TypeKind.Null && type2.kind != TypeKind.Null)
325
                            return type2;
326
                        else if (type2.kind == TypeKind.Null && type1.kind != TypeKind.Null)
327
                            return type1;
328
                        else if (type1.kind == TypeKind.Null && type2.kind == TypeKind.Null)
329
                            return type2;
330
                        else if (ReferenceEquals(type1, type2))
331
                            return type1;
332
                        else
333
                            return ClassBaseType((OoActionSystemType)type1, (OoActionSystemType)type2);
334
                    case TypeKind.OpaqueType:
335
                        System.Diagnostics.Debug.Assert(false);
336
                        return null;
337
                    default:
338
                        throw new NotImplementedException();
339
                }
340
            }
341
        }
342

    
343
        private static UlyssesType ClassBaseType(OoActionSystemType type1, OoActionSystemType type2)
344
        {
345
            // this is rather inefficient.. should be done differently
346
            OoActionSystemType typea = type1;
347
            OoActionSystemType typeb = type2;
348
            OoActionSystemType basea = type1;
349
            OoActionSystemType baseb = type2;
350
            while (basea != null)
351
            {
352
                if (ReferenceEquals(basea, typeb))
353
                    return basea;
354
                basea = basea.baseType;
355
            }
356
            while (baseb != null)
357
            {
358
                if (ReferenceEquals(baseb, typea))
359
                    return baseb;
360
                baseb = baseb.baseType;
361
            }
362
            return null;
363
        }
364

    
365
        public static bool FirstTypeLessRange(UlyssesType type1, UlyssesType type2)
366
        {
367
            TypeKind tk1 = type1.kind;
368
            TypeKind tk2 = type2.kind;
369

    
370
            if (tk1 != tk2)
371
                throw new ArgumentException("Types need to be equal");
372

    
373
            switch (tk1)
374
            {
375
                case TypeKind.IntType:
376
                    IntType Int1 = (IntType)type1;
377
                    IntType Int2 = (IntType)type2;
378
                    return Int1.rangeLow > Int2.rangeLow ||
379
                           Int1.rangeHigh < Int2.rangeHigh;
380
                case TypeKind.BoolType:
381
                    return false;
382
                case TypeKind.FloatType:
383
                    FloatType Float1 = (FloatType)type1;
384
                    FloatType Float2 = (FloatType)type2;
385
                    return Float1.low > Float2.low
386
                        || Float1.high < Float2.high
387
                        || Float1.precision > Float2.precision;
388
                case TypeKind.EnumeratedType:
389
                    return false;
390
                case TypeKind.ListType:
391
                    ListType listt1 = (ListType)type1;
392
                    ListType listt2 = (ListType)type2;
393
                    return (listt1.maxNumberOfElements < listt2.maxNumberOfElements) ||
394
                        UlyssesType.FirstTypeLessRange(listt1.innerType, listt2.innerType);
395
                case TypeKind.MapType:
396
                    MapType mapt1 = (MapType)type1;
397
                    MapType mapt2 = (MapType)type2;
398
                    return (mapt1.maxNumberOfElements < mapt2.maxNumberOfElements) ||
399
                        UlyssesType.FirstTypeLessRange(mapt1.fromType, mapt2.fromType) ||
400
                        UlyssesType.FirstTypeLessRange(mapt1.toType, mapt2.toType);
401
                case TypeKind.QrType:
402
                    return false;
403
                case TypeKind.TupleType:
404
                    TupleType tuplet1 = (TupleType)type1;
405
                    TupleType tuplet2 = (TupleType)type2;
406
                    if (tuplet1.innerTypes.Count != tuplet2.innerTypes.Count)
407
                        return false;
408
                    LinkedListNode<UlyssesType> innert1 = tuplet1.innerTypes.First;
409
                    LinkedListNode<UlyssesType> innert2 = tuplet2.innerTypes.First;
410
                    while (innert1 != null)
411
                    {
412
                        if (UlyssesType.FirstTypeLessRange(innert1.Value, innert2.Value))
413
                            return true;
414
                        innert1 = innert1.Next;
415
                        innert2 = innert2.Next;
416
                    }
417
                    return false;
418
                case TypeKind.OoActionSystemType:
419
                    return false;
420
                case TypeKind.OpaqueType:
421
                    System.Diagnostics.Debug.Assert(false);
422
                    return false;
423
                default:
424
                    throw new NotImplementedException();
425
            }
426
        }
427

    
428
        public static bool TypeEqualByKind(UlyssesType type1, UlyssesType type2)
429
        {
430
            if ((type1 == null) || (type2 == null))
431
                return false;
432

    
433
            TypeKind tk1 = type1.kind;
434
            TypeKind tk2 = type2.kind;
435

    
436
            // if of different kind, then return false..
437
            if (tk1 != tk2)
438
                return false;
439

    
440
            // if same kind, make a rigorous check
441
            switch (tk1)
442
            {
443
                case TypeKind.IntType:
444
                case TypeKind.BoolType:
445
                case TypeKind.FloatType:
446
                    return true;
447
                case TypeKind.EnumeratedType:
448
                    return ReferenceEquals(type1, type2);
449
                case TypeKind.ListType:
450
                    ListType listt1 = (ListType)type1;
451
                    ListType listt2 = (ListType)type2;
452
                    return UlyssesType.TypeEqualByKind(listt1.innerType, listt2.innerType);
453
                case TypeKind.MapType:
454
                    MapType mapt1 = (MapType)type1;
455
                    MapType mapt2 = (MapType)type2;
456
                    return UlyssesType.TypeEqualByKind(mapt1.fromType, mapt2.fromType) &&
457
                        UlyssesType.TypeEqualByKind(mapt1.toType, mapt2.toType);
458
                case TypeKind.QrType:
459
                    QrType qr1 = (QrType)type1;
460
                    QrType qr2 = (QrType)type2;
461
                    return ReferenceEquals(qr1, qr2);
462
                case TypeKind.TupleType:
463
                    TupleType tuplet1 = (TupleType)type1;
464
                    TupleType tuplet2 = (TupleType)type2;
465
                    if (tuplet1.innerTypes.Count != tuplet2.innerTypes.Count)
466
                        return false;
467
                    LinkedListNode<UlyssesType> innert1 = tuplet1.innerTypes.First;
468
                    LinkedListNode<UlyssesType> innert2 = tuplet2.innerTypes.First;
469
                    while (innert1 != null)
470
                    {
471
                        if (!UlyssesType.TypeEqualByKind(innert1.Value, innert2.Value))
472
                            return false;
473
                        innert1 = innert1.Next;
474
                        innert2 = innert2.Next;
475
                    }
476
                    return true;
477
                case TypeKind.OoActionSystemType:
478
                    return ReferenceEquals(type1, type2);
479
                case TypeKind.OpaqueType:
480
                    System.Diagnostics.Debug.Assert(false);
481
                    return false;
482
                default:
483
                    throw new NotImplementedException();
484
            }
485
        }
486

    
487

    
488
        public static bool TypeEqual(UlyssesType type1, UlyssesType type2)
489
        {
490
            // this will also work with opaque types...
491
            while (type1 is OpaqueType)
492
                type1 = ((OpaqueType)type1).resolvedType;
493
            while (type2 is OpaqueType)
494
                type2 = ((OpaqueType)type2).resolvedType;
495

    
496
            if ((type1 == null) || (type2 == null))
497
                return false;
498

    
499
            TypeKind tk1 = type1.kind;
500
            TypeKind tk2 = type2.kind;
501

    
502
            // if of different kind, then return false..
503
            if (tk1 != tk2)
504
                return false;
505

    
506
            // if same kind, make a rigorous check
507
            switch (tk1)
508
            {
509
                case TypeKind.IntType:
510
                    IntType intt1 = (IntType)type1;
511
                    IntType intt2 = (IntType)type2;
512
                    return intt1.rangeLow == intt2.rangeLow &&
513
                        intt1.rangeHigh == intt2.rangeHigh;
514
                case TypeKind.BoolType:
515
                    return true;
516
                case TypeKind.FloatType:
517
                    FloatType floatt1 = (FloatType)type1;
518
                    FloatType floatt2 = (FloatType)type2;
519
                    return floatt1.low == floatt2.low &&
520
                        floatt1.high == floatt2.high &&
521
                        floatt1.precision == floatt2.precision;
522
                case TypeKind.EnumeratedType:
523
                    return ReferenceEquals(type1, type2);
524
                case TypeKind.ListType:
525
                    ListType listt1 = (ListType)type1;
526
                    ListType listt2 = (ListType)type2;
527
                    // an empty list can be of any type.. 
528
                    /*if ((listt1.innerType.kind == TypeKind.Null) || (listt2.innerType.kind == TypeKind.Null))
529
                        return true;
530
                    else*/
531
                    return UlyssesType.TypeEqual(listt1.innerType, listt2.innerType) &&
532
                        listt1.maxNumberOfElements == listt2.maxNumberOfElements; // need this because of covertype
533
                case TypeKind.MapType:
534
                    MapType mapt1 = (MapType)type1;
535
                    MapType mapt2 = (MapType)type2;
536
                    return UlyssesType.TypeEqual(mapt1.fromType, mapt2.fromType) &&
537
                        UlyssesType.TypeEqual(mapt1.toType, mapt2.toType) &&
538
                        mapt1.maxNumberOfElements == mapt2.maxNumberOfElements; // need this because of covertype
539
                case TypeKind.QrType:
540
                    QrType qr1 = (QrType)type1;
541
                    QrType qr2 = (QrType)type2;
542
                    return ReferenceEquals(qr1, qr2);
543
                case TypeKind.TupleType:
544
                    TupleType tuplet1 = (TupleType)type1;
545
                    TupleType tuplet2 = (TupleType)type2;
546
                    if (tuplet1.innerTypes.Count != tuplet2.innerTypes.Count)
547
                        return false;
548
                    LinkedListNode<UlyssesType> innert1 = tuplet1.innerTypes.First;
549
                    LinkedListNode<UlyssesType> innert2 = tuplet2.innerTypes.First;
550
                    while (innert1 != null)
551
                    {
552
                        if (!UlyssesType.TypeEqual(innert1.Value, innert2.Value))
553
                            return false;
554
                        innert1 = innert1.Next;
555
                        innert2 = innert2.Next;
556
                    }
557
                    return true;
558
                case TypeKind.OoActionSystemType:
559
                    return ReferenceEquals(type1, type2);// || Covariance((OoActionSystemType)type1, (OoActionSystemType)type2);
560
                case TypeKind.OpaqueType:
561
                    System.Diagnostics.Debug.Assert(false);
562
                    return false;
563
                case TypeKind.Null:
564
                case TypeKind.Any:
565
                    return true;
566
                default:
567
                    throw new NotImplementedException();
568
            }
569
        }
570

    
571
        /// <summary>
572
        /// checks if type 2 is a desc. of type 1
573
        /// </summary>
574
        public static bool Covariance(OoActionSystemType ooActionSystemType, OoActionSystemType ooActionSystemType_2)
575
        {
576
            // check if type 2 is a desc. of type 1
577
            while (!ReferenceEquals(ooActionSystemType, ooActionSystemType_2) && ooActionSystemType_2.baseType != null)
578
                ooActionSystemType_2 = ooActionSystemType_2.baseType;
579

    
580
            return ReferenceEquals(ooActionSystemType, ooActionSystemType_2);
581
        }
582
    }
583

    
584

    
585
    ///////////////////////////////////////////////
586
    ///  Special type: null
587
    ///  
588
    public sealed class NullType : UlyssesType
589
    {
590
        public NullType()
591
            : base(TypeKind.Null, null)
592
        { }
593

    
594
        public override void Accept(IAstVisitor visitor)
595
        {
596
            visitor.visit(this);
597
        }
598

    
599
        public override string AnonymousName()
600
        {
601
            return "null";
602
        }
603
    }
604

    
605

    
606
    ///////////////////////////////////////////////
607
    ///  Special type: any  (used for free variables)
608
    ///  
609
    public sealed class AnyType : UlyssesType
610
    {
611
        private ExpressionVariableIdentifier m_variableIdentifier;
612

    
613
        public ExpressionVariableIdentifier VariableIdentifier { get { return m_variableIdentifier; } }
614

    
615
        public AnyType(ExpressionVariableIdentifier freeVariable)
616
            : base(TypeKind.Any, null)
617
        {
618
            m_variableIdentifier = freeVariable;
619
        }
620

    
621
        public override void Accept(IAstVisitor visitor)
622
        {
623
            visitor.visit(this);
624
        }
625

    
626
        public override string AnonymousName()
627
        {
628
            return "any";
629
        }
630

    
631
    }
632

    
633

    
634
    ///////////////////////////////////////////////
635
    ///  Simple Type: Int
636
    ///  
637
    public class IntType : UlyssesType
638
    {
639
        protected int m_low;
640
        protected int m_high;
641

    
642
        public int rangeLow { get { return m_low; } }
643
        public int rangeHigh { get { return m_high; } }
644

    
645
        public IntType(int low, int high, TypeIdentifier anIdentifier)
646
            : base(TypeKind.IntType, anIdentifier)
647
        {
648
            m_low = low;
649
            m_high = high;
650
        }
651

    
652
        public override void Accept(IAstVisitor visitor)
653
        {
654
            visitor.visit(this);
655
        }
656

    
657
        public override string AnonymousName()
658
        {
659
            return String.Format("int_{0}_{1}", m_low < 0 ? "m" + Convert.ToString(m_low * (-1)) : Convert.ToString(m_low), m_high);
660
        }
661

    
662
    }
663

    
664
    public sealed class CharType : IntType
665
    {
666
        public CharType(TypeIdentifier anIdentifier)
667
            : base(0, 255, anIdentifier)
668
        { }
669

    
670
        public override void Accept(IAstVisitor visitor)
671
        {
672
            visitor.visit(this);
673
        }
674
    }
675

    
676

    
677

    
678
    ///////////////////////////////////////////////
679
    ///  Simple Type: Bool
680
    ///  
681
    public sealed class BoolType : UlyssesType
682
    {
683
        public BoolType(TypeIdentifier anIdentifier)
684
            : base(TypeKind.BoolType, anIdentifier)
685
        { }
686

    
687
        public override void Accept(IAstVisitor visitor)
688
        {
689
            visitor.visit(this);
690
        }
691

    
692
        public override string AnonymousName()
693
        {
694
            return "bool";
695
        }
696
    }
697

    
698
    ///////////////////////////////////////////////
699
    ///  Simple Type: Float (fixed point)
700
    ///  
701
    public sealed class FloatType : UlyssesType
702
    {
703
        private double m_low;
704
        private double m_high;
705
        private double m_precision;
706

    
707
        public double low { get { return m_low; } }
708
        public double high { get { return m_high; } }
709
        public double precision { get { return m_precision; } }
710
        public static double defaultPrecision { get { return double.Epsilon; } }
711

    
712
        public FloatType(double low, double high, double precision, TypeIdentifier anIdentifier)
713
            : base(TypeKind.FloatType, anIdentifier)
714
        {
715
            m_low = low;
716
            m_high = high;
717
            m_precision = precision;
718
        }
719

    
720
        public override void Accept(IAstVisitor visitor)
721
        {
722
            visitor.visit(this);
723
        }
724

    
725
        public override string AnonymousName()
726
        {
727
            string name = String.Format("float_{0}_{1}_{2}", m_low < 0 ? "m" + Math.Abs(m_low).ToString(CultureInfo.InvariantCulture) : m_low.ToString(CultureInfo.InvariantCulture), m_high.ToString(CultureInfo.InvariantCulture), m_precision.ToString(CultureInfo.InvariantCulture));
728
            name = name.Replace(".", String.Empty);
729
            return name;
730
        }
731
    }
732

    
733

    
734
    ///////////////////////////////////////////////
735
    ///  Simple Type: Enumeration
736
    ///  
737
    public class EnumType : UlyssesType
738
    {
739
        protected SymbolTable m_enumSymbols;
740
        protected List<EnumIdentifier> m_listOfEnumSymbols;
741

    
742
        public SymbolTable symbolTable { get { return m_enumSymbols; } }
743
        public List<EnumIdentifier> listOfEnumSymbols { get { return m_listOfEnumSymbols; } }
744

    
745
        public EnumType(TypeIdentifier anIdentifier)
746
            : base(TypeKind.EnumeratedType, anIdentifier)
747
        {
748
            m_enumSymbols = new SymbolTable();
749
            m_listOfEnumSymbols = new List<EnumIdentifier>();
750
        }
751

    
752
        public void AddEnumSymbol(EnumIdentifier aSymbol)
753
        {
754
            if (m_enumSymbols.Defined(aSymbol.tokenText))
755
                throw new SymbolAlreadyDefinedException(aSymbol.tokenText);
756

    
757
            m_enumSymbols.AddIdentifier(aSymbol);
758
            m_listOfEnumSymbols.Add(aSymbol);
759
        }
760

    
761
        public override void Accept(IAstVisitor visitor)
762
        {
763
            visitor.visit(this);
764
        }
765

    
766
        public override string AnonymousName()
767
        {
768
            StringBuilder result = new StringBuilder();
769
            result.Append("enum_");
770
            foreach (var sym in m_listOfEnumSymbols)
771
            {
772
                result.Append(sym.tokenText);
773
                result.Append("_");
774
            }
775
            return result.ToString();
776
        }
777
    }
778

    
779
    public class ValuedEnumType : EnumType
780
    {
781
        private IntType intType = null;
782

    
783
        public ValuedEnumType(TypeIdentifier anIdentifier)
784
            : base(anIdentifier) { }
785

    
786
        public IntType getIntType()
787
        {
788
            if (intType == null)
789
            {
790
                int min = Int32.MaxValue; int max = Int32.MinValue;
791
                foreach (var x in symbolTable.symbolList)
792
                {
793
                    EnumIdentifier id = (EnumIdentifier)x;
794
                    if (id.Value > max)
795
                        max = id.Value;
796
                    if (id.Value < min)
797
                        min = id.Value;
798
                }
799
                intType = new IntType(min, max, null);
800
            }
801
            return intType;
802
        }
803

    
804
        public override string AnonymousName()
805
        {
806
            StringBuilder result = new StringBuilder();
807
            result.Append("enum_");
808
            foreach (var sym in m_listOfEnumSymbols)
809
            {
810
                result.Append(sym.tokenText);
811
                if (sym.Value < 0)
812
                {
813
                    result.Append("m");
814
                    result.Append(sym.Value * (-1));
815
                }
816
                else
817
                    result.Append(sym.Value);
818
                result.Append("_");
819
            }
820
            return result.ToString();
821
        }
822
    }
823

    
824

    
825

    
826

    
827
    ///////////////////////////////////////////////
828
    ///  Complex Type: QrType
829
    ///  behaves somewhat similar to an enumerated type..
830
    ///  
831
    public sealed class QrType : UlyssesType
832
    {
833
        private SymbolTable m_qspaceSymbols;
834
        private List<LandmarkIdentifier> m_listOfQspaceSymbols;
835

    
836
        public SymbolTable symbolTable { get { return m_qspaceSymbols; } }
837
        public List<LandmarkIdentifier> landmarks { get { return m_listOfQspaceSymbols; } }
838

    
839
        public QrType(TypeIdentifier anIdentifier)
840
            : base(TypeKind.QrType, anIdentifier)
841
        {
842
            m_listOfQspaceSymbols = new List<LandmarkIdentifier>();
843
            m_qspaceSymbols = new SymbolTable();
844
        }
845

    
846
        public void AddLandmark(LandmarkIdentifier aLandmark)
847
        {
848
            if (m_qspaceSymbols.Defined(aLandmark.tokenText))
849
                throw new SymbolAlreadyDefinedException(aLandmark.tokenText);
850

    
851
            m_qspaceSymbols.AddIdentifier(aLandmark);
852
            m_listOfQspaceSymbols.Add(aLandmark);
853
        }
854

    
855
        public override void Accept(IAstVisitor visitor)
856
        {
857
            visitor.visit(this);
858
        }
859

    
860
        public override string AnonymousName()
861
        {
862
            StringBuilder result = new StringBuilder();
863
            result.Append("qr_");
864
            foreach (var sym in m_listOfQspaceSymbols)
865
            {
866
                result.Append(sym.tokenText);
867
                result.Append("_");
868
            }
869
            return result.ToString();
870
        }
871

    
872
    }
873

    
874

    
875

    
876
    ///////////////////////////////////////////////
877
    ///  Complex Type: List
878
    ///  
879
    public sealed class ListType : UlyssesType
880
    {
881
        private UlyssesType m_innerType;
882
        private int m_maxNumberOfElements;
883

    
884
        public UlyssesType innerType { get { return m_innerType; } }
885
        public int maxNumberOfElements { get { return m_maxNumberOfElements; } }
886

    
887
        public ListType(UlyssesType elemType, int max, TypeIdentifier anIdentifier)
888
            : base(TypeKind.ListType, anIdentifier)
889
        {
890
            m_innerType = elemType;
891
            m_maxNumberOfElements = max;
892
        }
893

    
894
        public override void Accept(IAstVisitor visitor)
895
        {
896
            visitor.visit(this);
897
        }
898

    
899
        public void SetInnerType(UlyssesType newType)
900
        {
901
            if (newType == null)
902
                throw new ArgumentException();
903
            m_innerType = newType;
904
        }
905

    
906
        public override string AnonymousName()
907
        {
908
            return String.Format("list_{0}_{1}", m_maxNumberOfElements, m_innerType != null ? m_innerType.ToString() : "uninit");
909
        }
910

    
911
    }
912

    
913
    ///////////////////////////////////////////////
914
    ///  Complex Type: Map
915
    ///  
916
    public sealed class MapType : UlyssesType
917
    {
918
        private UlyssesType m_fromType;
919
        private UlyssesType m_toType;
920
        private int m_maxNumberOfElements;
921

    
922
        public UlyssesType fromType { get { return m_fromType; } }
923
        public UlyssesType toType { get { return m_toType; } }
924
        public int maxNumberOfElements { get { return m_maxNumberOfElements; } }
925

    
926
        public MapType(UlyssesType from, UlyssesType to, int max, TypeIdentifier anIdentifier)
927
            : base(TypeKind.MapType, anIdentifier)
928
        {
929
            m_fromType = from;
930
            m_toType = to;
931
            m_maxNumberOfElements = max;
932
        }
933

    
934
        public override void Accept(IAstVisitor visitor)
935
        {
936
            visitor.visit(this);
937
        }
938

    
939
        public void SetFromType(UlyssesType newType)
940
        {
941
            if (newType == null)
942
                throw new ArgumentException();
943
            m_fromType = newType;
944
        }
945

    
946
        public void SetToType(UlyssesType newType)
947
        {
948
            if (newType == null)
949
                throw new ArgumentException();
950
            m_toType = newType;
951
        }
952

    
953
        public override string AnonymousName()
954
        {
955
            return String.Format("map_{0}_{1}_{2}", m_maxNumberOfElements, m_fromType != null ? m_fromType.ToString() : "uninit", m_toType != null ? m_toType.ToString() : "uninit");
956
        }
957

    
958
    }
959

    
960

    
961
    ///////////////////////////////////////////////
962
    ///  Complex Type: TupleType
963
    ///  
964
    public sealed class TupleType : UlyssesType
965
    {
966
        private LinkedList<UlyssesType> m_innerTypes;
967

    
968
        public LinkedList<UlyssesType> innerTypes { get { return m_innerTypes; } }
969

    
970
        public TupleType(TypeIdentifier anIdentifier)
971
            : base(TypeKind.TupleType, anIdentifier)
972
        {
973
            m_innerTypes = new LinkedList<UlyssesType>();
974
        }
975

    
976
        public void AddType(UlyssesType aType)
977
        {
978
            m_innerTypes.AddLast(aType);
979
        }
980

    
981
        public override void Accept(IAstVisitor visitor)
982
        {
983
            visitor.visit(this);
984
        }
985

    
986
        public override string AnonymousName()
987
        {
988
            StringBuilder result = new StringBuilder();
989
            result.Append("tuple_");
990
            foreach (var inner in m_innerTypes)
991
            {
992
                result.Append(inner == null ? "<null>" : inner.ToString());
993
                result.Append("_");
994
            }
995
            return result.ToString();
996
        }
997

    
998
    }
999

    
1000

    
1001
    ///////////////////////////////////////////////
1002
    ///  Complex Type: Function
1003
    ///  
1004
    public enum FunctionTypeEnum { Observable, Controllable, Continuous, Internal, Method }
1005
    public sealed class FunctionType : UlyssesType
1006
    {
1007
        private bool? m_miracleSafe;
1008
        private bool m_pure;
1009
        private LinkedList<UlyssesType> m_parameter;
1010
        private UlyssesType m_returnType;
1011
        private FunctionTypeEnum m_functionType;
1012

    
1013
        public bool? isMiracleSafe { get { return m_miracleSafe; } }
1014
        public bool isPureFunction { get { return m_pure; } }
1015
        public LinkedList<UlyssesType> parameter { get { return m_parameter; } }
1016
        public UlyssesType returnType { get { return m_returnType; } }
1017
        public FunctionTypeEnum functionType { get { return m_functionType; } }
1018

    
1019
        public FunctionType(FunctionTypeEnum functionType, LinkedList<UlyssesType> parameter, UlyssesType returnType)
1020
            : base(TypeKind.FunctionType, null)
1021
        {
1022
            if (parameter != null)
1023
                m_parameter = parameter;
1024
            else
1025
                m_parameter = new LinkedList<UlyssesType>();
1026
            m_returnType = returnType;
1027
            m_functionType = functionType;
1028
            m_miracleSafe = null;
1029
            m_pure = false;
1030
        }
1031

    
1032

    
1033
        public void AddParameterType(UlyssesType aType)
1034
        {
1035
            m_parameter.AddLast(aType);
1036
        }
1037

    
1038
        public void SetReturnType(UlyssesType aType)
1039
        {
1040
            m_returnType = aType;
1041
        }
1042

    
1043
        public void SetMiracleSafe(bool newValue)
1044
        {
1045
            m_miracleSafe = newValue;
1046
        }
1047

    
1048
        public void SetIsPureFunction(bool newValue)
1049
        {
1050
            m_pure = newValue;
1051
        }
1052

    
1053
        public override void Accept(IAstVisitor visitor)
1054
        {
1055
            visitor.visit(this);
1056
        }
1057

    
1058
        public override string AnonymousName()
1059
        {
1060
            StringBuilder result = new StringBuilder();
1061
            result.Append("fun_");
1062
            result.Append(m_functionType.ToString());
1063
            result.Append("_");
1064
            foreach (var sym in m_parameter)
1065
            {
1066
                result.Append(sym.ToString());
1067
                result.Append("_");
1068
            }
1069
            result.Append("_");
1070
            if (m_returnType != null)
1071
                result.Append(m_returnType.ToString());
1072
            else
1073
                result.Append("void");
1074
            result.Append("_");
1075
            result.Append(m_pure);
1076
            return result.ToString();
1077
        }
1078

    
1079
    }
1080

    
1081

    
1082
    ///////////////////////////////////////////////
1083
    ///  Complex Type: OoActionSystem
1084
    ///  
1085

    
1086
    public sealed class OoActionSystemInstance
1087
    {
1088
        // pointer to type
1089
        public OoActionSystemType Type;
1090
        // name of the current object
1091
        public string Name;
1092
        // counts the number of objects that have been created by this object
1093
        public int numberOfCreatedObjects;
1094
        // pointer to a C# instance of this object
1095
        public TUG.Mogentes.Codegen.CSharp.UlyssesActionSystemClass Instance;
1096
        // pointer to the object that created us
1097
        public OoActionSystemInstance ParentObject;
1098

    
1099
        public OoActionSystemInstance(string aName, OoActionSystemType aType, TUG.Mogentes.Codegen.CSharp.UlyssesActionSystemClass anInstance, OoActionSystemInstance aParentObj)
1100
        {
1101
            Name = aName;
1102
            Type = aType;
1103
            ParentObject = aParentObj;
1104
            Instance = anInstance;
1105
            numberOfCreatedObjects = 0;
1106
            if (ParentObject != null)
1107
                ParentObject.numberOfCreatedObjects++;
1108
        }
1109
    }
1110

    
1111
    public class OoActionSystemType : UlyssesType, IScope
1112
    {
1113
        private bool m_autoCons;
1114
        private OoActionSystemType m_baseType;
1115
        private Block m_doOdBlock;
1116
        private IScope m_parentScope;
1117
        private SymbolTable m_symbols;
1118
        private List<OoActionSystemInstance> m_objects;
1119
        private List<OoActionSystemInstance> m_derivedObjects;
1120
        private bool m_isInSystemDescription;
1121

    
1122
        public Block doOdBlock { get { return m_doOdBlock; } }
1123
        public bool autoConstruction { get { return m_autoCons; } }
1124
        public OoActionSystemType baseType { get { return m_baseType; } }
1125
        public SymbolTable symbols { get { return m_symbols; } }
1126
        public List<OoActionSystemInstance> objects { get { return m_objects; } }
1127
        public List<OoActionSystemInstance> derivedObjects { get { return m_derivedObjects; } }
1128
        public bool isInSystemDescription { get { return m_isInSystemDescription; } }
1129

    
1130
        public OoActionSystemType(
1131
                bool autoCons,
1132
                OoActionSystemType refinedSystem,
1133
                TypeIdentifier typeName)
1134
            : base(TypeKind.OoActionSystemType, typeName)
1135
        {
1136
            m_symbols = new SymbolTable();
1137
            m_autoCons = autoCons;
1138
            m_baseType = refinedSystem;
1139
            m_objects = new List<OoActionSystemInstance>();
1140
            m_derivedObjects = new List<OoActionSystemInstance>();
1141
            m_isInSystemDescription = false;
1142
        }
1143

    
1144
        public void SetDoOdBlock(Block anArg)
1145
        {
1146
            m_doOdBlock = anArg;
1147
        }
1148

    
1149

    
1150
        public IScope GetParentScope()
1151
        {
1152
            return m_parentScope;
1153
        }
1154

    
1155
        public void SetParentScope(IScope parentScope)
1156
        {
1157
            m_parentScope = parentScope;
1158
        }
1159

    
1160
        public Identifier ResolveLocal(string aName)
1161
        {
1162
            if (m_symbols.Defined(aName))
1163
                return m_symbols.Get(aName);
1164
            else
1165
                return null;
1166
        }
1167

    
1168
        public Identifier ResolveIdentifier(string aName)
1169
        {
1170
            Identifier result = ResolveLocal(aName);
1171
            if ((result == null) && (m_baseType != null))
1172
                result = m_baseType.ResolveIdentifier(aName);
1173
            return result;
1174
        }
1175

    
1176
        public void AddIdentifier(Identifier anIdentifier, object tag)
1177
        {
1178
            m_symbols.AddIdentifier(anIdentifier);
1179
        }
1180

    
1181
        public override void Accept(IAstVisitor visitor)
1182
        {
1183
            visitor.visit(this);
1184
        }
1185

    
1186
        public void SetBaseType(OoActionSystemType newType)
1187
        {
1188
            if (newType == null)
1189
                throw new ArgumentException();
1190
            m_baseType = newType;
1191
        }
1192

    
1193
        public SymbolTable getAllSymbols()
1194
        {
1195
            OoActionSystemType system;
1196
            List<OoActionSystemType> inheritance = new List<OoActionSystemType>();
1197
            system = this;
1198
            while (system != null)
1199
            {
1200
                inheritance.Insert(0, system);
1201
                system = system.baseType;
1202
            }
1203
            SymbolTable result = new SymbolTable();
1204
            foreach (var ooas in inheritance)
1205
                result.AddSymbolTable(ooas.symbols);
1206
            result.Replace("self", this.symbols.Get("self"));
1207
            return result;
1208
        }
1209

    
1210
        public override string AnonymousName()
1211
        {
1212
            return String.Format("class_{0}", (uint)this.GetHashCode());
1213
        }
1214

    
1215
        internal void SetIsInSystemDescription(bool p)
1216
        {
1217
            m_isInSystemDescription = p;
1218
        }
1219
    }
1220

    
1221

    
1222
    ///////////////////////////////////////////////
1223
    ///  Opaque Type..
1224
    ///  
1225
    public class OpaqueType : UlyssesType
1226
    {
1227
        private UlyssesType m_resolvedType;
1228

    
1229
        public UlyssesType resolvedType { get { return m_resolvedType; } }
1230

    
1231
        public OpaqueType(TypeIdentifier reference)
1232
            : base(TypeKind.OpaqueType, reference)
1233
        { }
1234

    
1235
        public void SetResolvedType(UlyssesType aType)
1236
        {
1237
            m_resolvedType = aType;
1238
        }
1239

    
1240
        public override void Accept(IAstVisitor visitor)
1241
        {
1242
            visitor.visit(this);
1243
        }
1244

    
1245
        public override string AnonymousName()
1246
        {
1247
            if (m_resolvedType == null)
1248
                return "undef";
1249
            else
1250
                return m_resolvedType.ToString();
1251
        }
1252
    }
1253

    
1254

    
1255

    
1256
    ///////////////////////////////////////////////
1257
    ///  Not really a type - this is the structure for the instantiated action system
1258
    ///  (all the objects flattened)
1259
    ///  
1260

    
1261
    public sealed class ActionSystem : OoActionSystemType
1262
    {
1263
        private List<OoActionSystemType> m_types;
1264

    
1265
        public List<OoActionSystemType> types { get { return m_types; } }
1266

    
1267

    
1268
        public ActionSystem()
1269
            : base(false, null, null)
1270
        {
1271
            m_types = new List<OoActionSystemType>();
1272
            m_identifier = new TypeIdentifier("__system", this, null);
1273
        }
1274

    
1275
    }
1276

    
1277

    
1278

    
1279
}