Project

General

Profile

root / branches / compiler / cSharp / ooasCompiler / src / parser / ooaExpressions.cs

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 Antlr.Runtime;
22

    
23
namespace TUG.Mogentes
24
{
25
    public enum ExpressionKind
26
    {
27
        /*tern.*/
28
        conditional,
29
        /*map binary*/
30
        domresby, domresto, rngresby, rngresto, munion,
31
        /*set/list binary*/
32
        conc, diff, inter, elemin, notelemin, subset, union,
33
        /*numeric binary*/
34
        div, greater, greaterequal, idiv, less, lessequal, minus, mod, pow, prod, sum,
35
        /*bool binary*/
36
        and, biimplies, implies, or,
37
        /*other binary*/
38
        equal, notequal, seqmod_mapoverride,
39
        /*map unary*/
40
        dom, range, merge,
41
        /*set/list unary*/
42
        card, dconc, dinter, dunion, elems, head, inds, len, tail,
43
        /*unary numberic*/
44
        unminus, unplus, not, abs,
45
        /*unary quantors*/
46
        forall, exists,
47
        /*Constructors*/
48
        ListConstr, SetConstr, MapConstr, TupleConstr, ObjectConstr, QValConstr,
49
        /* constant, identifier */
50
        Value, Identifier, UnresolvedIdentifier, Type,
51
        /* tuple access and method call */
52
        TupleMapAccess, Call,
53
        /* point operator */
54
        Access,
55
        /* primed */
56
        Primed,
57
        /* cast */
58
        Cast,
59
        /* fold */
60
        foldLR, foldRL
61
    }
62

    
63
    /*
64
    public enum UnaryOperatorType { unminus, unplus, not, abs }
65
    public enum SetListUnaryOperatorType { card, dconc, dinter, dunion, elems, head, inds, len, tail }
66
    public enum MapUnaryOperatorType { dom, range, merge }
67
    public enum BinaryOperatorType { equal, notequal, seqmod_mapoverride }
68
    public enum BoolBinaryOperatorType { and, biimplies, implies, or }
69
    public enum NumericBinaryOperatorType { div, greater, greaterequal, idiv, less, lessequal, minus, mod, pow, prod, sum }
70
    public enum SetListBinaryOperatorType { conc, diff, inter, elemin, notelemin, subset, union }
71
    public enum MapBinaryOperatorType { domresby, domresto, rngresby, rngresto, munion }
72
    */
73

    
74
    ///////////////////////////////////////////////
75
    ///  Expressions
76
    ///
77
    /// Note: Since we allow expression of the form
78
    /// myTuple(a,b) = hd x, where a and b are newly
79
    /// introduced placeholders, the expression knows
80
    /// about local variables.
81
    /// Scoping: Consider following expression
82
    ///     3 > a and myTuple(b,d) = hd e and b < 5
83
    /// which gives
84
    ///             and
85
    ///          /       \   
86
    ///         /         and
87
    ///        /        /     \ 
88
    ///       >        =        <
89
    ///      / \      /  \     /  \ 
90
    ///     3   a  (b,d)  e   b    5
91
    ///  the scope of b and d is defined by the binary
92
    ///  expression that has the leaf within its left child
93
    ///  (== the second 'and'). 
94
    ///  Local variables may only be introduced in constructors
95
    ///  of sets, lists, and tuples. Therefore the type is 
96
    ///  known.
97

    
98

    
99
    public abstract class Expression : UlyssesBasicClass, IAst
100
    {
101
        protected ExpressionKind m_kind;
102
        protected UlyssesType m_type;
103
        protected int m_line;
104
        protected int m_pos;
105
        protected SymbolTable m_freeVariables;
106
        protected List<FunctionIdentifier> m_callTargets;
107

    
108
        public ExpressionKind kind { get { return m_kind; } }
109
        public UlyssesType type { get { return m_type; } }
110
        public int line { get { return m_line; } }
111
        public int pos { get { return m_pos; } }
112
        public SymbolTable freeVariables { get { return m_freeVariables; } }
113
        public List<FunctionIdentifier> callTargets { get { return m_callTargets; } }
114

    
115
        public Expression(ExpressionKind aKind, int line, int pos)
116
        {
117
            m_kind = aKind;
118
            m_line = line;
119
            m_pos = pos;
120
            m_callTargets = new List<FunctionIdentifier>();
121
        }
122

    
123
        public Expression(Expression toCopy)
124
        {
125
            m_kind = toCopy.m_kind;
126
            m_line = toCopy.m_line;
127
            m_pos = toCopy.m_pos;
128
            m_callTargets = new List<FunctionIdentifier>(toCopy.callTargets);
129
            m_type = toCopy.m_type;
130
            m_freeVariables = new SymbolTable(toCopy.m_freeVariables);
131
        }
132

    
133
        public virtual Expression Clone()
134
        {
135
            throw new NotImplementedException();
136
        }
137

    
138
        public void SetType(UlyssesType aType)
139
        {
140
            if (aType == null)
141
                throw new ArgumentException();
142
            m_type = aType;
143
        }
144

    
145
        public void SetFreeVariables(SymbolTable aSymTab)
146
        {
147
            m_freeVariables = aSymTab;
148
        }
149

    
150
        public List<ExpressionVariableIdentifier> GetUninitializedFreeVariables()
151
        {
152
            List<ExpressionVariableIdentifier> result = new List<ExpressionVariableIdentifier>();
153
            if (m_freeVariables != null)
154
                foreach (var v in m_freeVariables.symbolList)
155
                {
156
                    ExpressionVariableIdentifier id = (ExpressionVariableIdentifier)v;
157
                    if (id.initialized == false)
158
                        result.Add(id);
159
                }
160
            return result;
161
        }
162

    
163

    
164
        #region IAst Member
165

    
166
        public AstNodeTypeEnum nodeType { get { return AstNodeTypeEnum.expression; } }
167

    
168
        public virtual void Accept(IAstVisitor visitor)
169
        {
170
            throw new NotImplementedException();
171
        }
172

    
173
        #endregion
174

    
175

    
176
        /// <summary>
177
        /// Calculates the arithmetic cover, i.e. the return type of the operation, given two types.
178
        /// This is different from the cover-method defined at the type level.
179
        /// Note: We do saturating operations on the type boundaries.
180
        /// </summary>
181
        public static UlyssesType ArithmeticCover(UlyssesType type1, UlyssesType type2, ExpressionKind op)
182
        {
183
            if (!type1.IsNumeric() || (type2 != null && !type2.IsNumeric()))
184
                throw new ArgumentException();
185

    
186
            if (type1 is ValuedEnumType)
187
                type1 = ((ValuedEnumType)type1).getIntType();
188
            if (type2 is ValuedEnumType)
189
                type2 = ((ValuedEnumType)type2).getIntType();
190

    
191
            AbstractRange result;
192
            AbstractRange rangeType1 = null;
193
            AbstractRange rangeType2 = null;
194
            AbstractOperations operations;
195
            bool resultIsFloat = type1.kind == TypeKind.FloatType
196
                                || op == ExpressionKind.div
197
                                || (type2 != null && type2.kind == TypeKind.FloatType);
198
            if (resultIsFloat)
199
            {
200
                rangeType1 = new DoubleRange(
201
                    type1.kind == TypeKind.IntType ? ((IntType)type1).rangeHigh : ((FloatType)type1).high,
202
                    type1.kind == TypeKind.IntType ? ((IntType)type1).rangeLow : ((FloatType)type1).low);
203
                if (type2 != null)
204
                {
205
                    rangeType2 = new DoubleRange(
206
                        type2.kind == TypeKind.IntType ? ((IntType)type2).rangeHigh : ((FloatType)type2).high,
207
                        type2.kind == TypeKind.IntType ? ((IntType)type2).rangeLow : ((FloatType)type2).low);
208
                }
209
                operations = new SaturatedDoubleOperations();
210
            }
211
            else
212
            {
213
                rangeType1 = new IntegerRange(((IntType)type1).rangeHigh, ((IntType)type1).rangeLow);
214
                rangeType2 = new IntegerRange(((IntType)type2).rangeHigh, ((IntType)type2).rangeLow);
215
                operations = new SaturatedIntegerOperations();
216
            }
217

    
218
            switch (op)
219
            {
220
                case ExpressionKind.pow:
221
                case ExpressionKind.prod:
222
                case ExpressionKind.unminus:
223
                case ExpressionKind.unplus:
224
                case ExpressionKind.minus:
225
                case ExpressionKind.sum:
226
                case ExpressionKind.div:
227
                    result = operations.GenericArithmeticCover(rangeType1, rangeType2, op);
228
                    break;
229

    
230
                case ExpressionKind.idiv:
231
                    if (resultIsFloat)
232
                        throw new ArgumentException();
233
                    System.Diagnostics.Debug.Assert(type2 != null);
234
                    result = operations.GenericArithmeticCover(rangeType1, rangeType2, op);
235
                    break;
236
                case ExpressionKind.mod:
237
                    if (resultIsFloat)
238
                        throw new ArgumentException();
239
                    System.Diagnostics.Debug.Assert(type2 != null);
240
                    result = new IntegerRange(((IntegerRange)rangeType2).max - 1, 0);
241
                    break;
242

    
243
                default:
244
                    throw new NotImplementedException();
245
            }
246

    
247
            if (resultIsFloat)
248
                return new FloatType(((DoubleRange)result).min, ((DoubleRange)result).max, FloatType.defaultPrecision, null);
249
            else
250
                // this is crude, but see whether it works..
251
                return new IntType(((IntegerRange)result).min, ((IntegerRange)result).max, null);
252
        }
253

    
254

    
255
        public override string ToString()
256
        {
257
            OoaPrintVisitor visitor = new OoaPrintVisitor(null);
258
            this.Accept(visitor);
259
            return visitor.ToString();
260
        }
261
    }
262

    
263

    
264
    ///////////////////////////////////////////////
265
    ///  === Leaf Expressions ===
266
    ///  
267
    public enum LeafTypeEnum { unset, boolean, integer, real, chr, qval, reference, identifier, type, complex }
268
    public abstract class LeafExpression : Expression
269
    {
270
        protected LeafTypeEnum m_valueType;
271

    
272
        public LeafTypeEnum valueType { get { return m_valueType; } }
273

    
274
        public LeafExpression(LeafTypeEnum avalueType, ExpressionKind aKind, int line, int pos)
275
            : base(aKind, line, pos)
276
        {
277
            m_valueType = avalueType;
278
        }
279

    
280
        public LeafExpression(LeafExpression toCopy)
281
            : base(toCopy)
282
        {
283
            m_valueType = toCopy.m_valueType;
284
        }
285
    }
286

    
287

    
288

    
289
    ///////////////////////////////////////////////
290
    ///  Some constant bool, int, float, char,
291
    ///  qval or nil value
292
    ///  
293
    public sealed class ValueExpression<T> : LeafExpression
294
    {
295
        private T m_value;
296

    
297
        public T value { get { return m_value; } }
298

    
299
        public ValueExpression(T aValue, int line, int pos)
300
            : base(LeafTypeEnum.unset, ExpressionKind.Value, line, pos)
301
        {
302
            m_value = aValue;
303
            if (typeof(T) == typeof(int))
304
                m_valueType = LeafTypeEnum.integer;
305
            else if (typeof(T) == typeof(bool))
306
                m_valueType = LeafTypeEnum.boolean;
307
            else if (typeof(T) == typeof(double))
308
                m_valueType = LeafTypeEnum.real;
309
            else if (typeof(T) == typeof(char))
310
                m_valueType = LeafTypeEnum.chr;
311
            else if (typeof(T).IsSubclassOf(typeof(QrType)))
312
                m_valueType = LeafTypeEnum.qval;
313
            else if (typeof(T).IsClass)
314
                m_valueType = LeafTypeEnum.reference;
315
            else
316
                throw new ArgumentException();
317
        }
318

    
319
        public ValueExpression(ValueExpression<T> toCopy)
320
            : base(toCopy)
321
        {
322
            m_value = toCopy.m_value;
323
        }
324

    
325
        public override Expression Clone()
326
        {
327
            return new ValueExpression<T>(this);
328
        }
329

    
330
        public override void Accept(IAstVisitor visitor)
331
        {
332
            visitor.visit<T>(this);
333
        }
334
    }
335

    
336

    
337
    ///////////////////////////////////////////////
338
    ///  Some identifier
339
    ///  
340
    public class IdentifierExpression : LeafExpression
341
    {
342
        protected Identifier m_identifier;
343
        protected bool m_self;
344

    
345
        public Identifier identifier { get { return m_identifier; } }
346
        public bool isSelf { get { return m_self; } }
347

    
348
        public IdentifierExpression(Identifier anIdentifier, int line, int pos)
349
            : base(LeafTypeEnum.identifier, ExpressionKind.Identifier, line, pos)
350
        {
351
            m_identifier = anIdentifier;
352
            if (anIdentifier != null)
353
                m_type = m_identifier.type;
354
            m_self = false;
355
        }
356

    
357
        public IdentifierExpression(IdentifierExpression toCopy)
358
            : base(toCopy)
359
        {
360
            m_identifier = toCopy.m_identifier;
361
            m_self = toCopy.m_self;
362
        }
363

    
364
        public override Expression Clone()
365
        {
366
            return new IdentifierExpression(this);
367
        }
368

    
369
        public void setIsSelf(bool newValue)
370
        {
371
            m_self = newValue;
372
        }
373

    
374
        public override void Accept(IAstVisitor visitor)
375
        {
376
            visitor.visit(this);
377
        }
378

    
379
        public void SetIdentifier(Identifier newIdentifier)
380
        {
381
            m_identifier = newIdentifier;
382
        }
383
    }
384

    
385
    ///////////////////////////////////////////////
386
    ///  Some identifier
387
    ///  
388
    public class TypeExpression : LeafExpression
389
    {
390
        public TypeExpression(UlyssesType atype, int line, int pos)
391
            : base(LeafTypeEnum.type, ExpressionKind.Type, line, pos)
392
        {
393
            m_type = atype;
394
        }
395

    
396
        public TypeExpression(TypeExpression toCopy)
397
            : base(toCopy)
398
        { }
399

    
400
        public override Expression Clone()
401
        {
402
            return new TypeExpression(this);
403
        }
404

    
405
        public override void Accept(IAstVisitor visitor)
406
        {
407
            visitor.visit(this);
408
        }
409
    }
410

    
411
    ///////////////////////////////////////////////
412
    ///  Some unresolved identifier
413
    ///  
414
    public sealed class UnresolvedIdentifierExpression : IdentifierExpression
415
    {
416
        private IScope m_scope;
417
        private string m_tokenText;
418

    
419

    
420
        public string tokenText { get { return m_tokenText; } }
421
        public IScope scope { get { return m_scope; } }
422

    
423
        public UnresolvedIdentifierExpression(IToken identifier, IScope aScope)
424
            : base(null, identifier.Line, identifier.CharPositionInLine)
425
        {
426
            m_kind = ExpressionKind.UnresolvedIdentifier;
427
            m_tokenText = identifier.Text;
428
            m_scope = aScope;
429
        }
430

    
431
        public UnresolvedIdentifierExpression(UnresolvedIdentifierExpression toCopy)
432
            : base(toCopy)
433
        {
434
            m_scope = toCopy.m_scope;
435
            m_tokenText = toCopy.m_tokenText;
436
        }
437

    
438
        public override Expression Clone()
439
        {
440
            return new UnresolvedIdentifierExpression(this);
441
        }
442

    
443
        public override void Accept(IAstVisitor visitor)
444
        {
445
            visitor.visit(this);
446
        }
447
    }
448

    
449

    
450
    ///////////////////////////////////////////////
451
    ///  constructors
452
    ///  
453
    public abstract class TypeConstructionExpression : LeafExpression
454
    {
455
        public TypeConstructionExpression(ExpressionKind aKind, int line, int pos)
456
            : base(LeafTypeEnum.complex, aKind, line, pos)
457
        { }
458
        public TypeConstructionExpression(TypeConstructionExpression toCopy)
459
            : base(toCopy)
460
        { }
461
    }
462

    
463
    public sealed class ObjectConstructor : TypeConstructionExpression
464
    {
465
        private List<OoActionSystemInstance> m_instances;
466
        private int m_currentInstance;
467
        private string m_fixedObjectName;
468

    
469
        public int currentInstance { get { return m_currentInstance; } }
470
        public List<OoActionSystemInstance> instances { get { return m_instances; } }
471
        public string givenObjectName { get { return m_fixedObjectName; } }
472
        
473
        public void ResetCurrentInstance() { m_currentInstance = 0; }
474

    
475
        public ObjectConstructor(OpaqueType aType, int line, int pos)
476
            : base(ExpressionKind.ObjectConstr, line, pos)
477
        {
478
            SetType(aType);
479
            m_instances = new List<OoActionSystemInstance>();
480
            m_currentInstance = 0;
481
        }
482

    
483
        public ObjectConstructor(OpaqueType aType, string aName, int line, int pos)
484
            : base(ExpressionKind.ObjectConstr, line, pos)
485
        {
486
            SetType(aType);
487
            m_instances = new List<OoActionSystemInstance>();
488
            m_currentInstance = 0;
489
            m_fixedObjectName = aName;
490
        }
491

    
492

    
493
        public ObjectConstructor(ObjectConstructor toCopy)
494
            : base(toCopy)
495
        {
496
            m_instances = new List<OoActionSystemInstance>( toCopy.m_instances);
497
            m_currentInstance = toCopy.m_currentInstance;
498
            m_fixedObjectName = toCopy.m_fixedObjectName;
499
        }
500

    
501
        public override Expression Clone()
502
        {
503
            return new ObjectConstructor(this);
504
        }
505

    
506
        public override void Accept(IAstVisitor visitor)
507
        {
508
            visitor.visit(this);
509
        }
510

    
511
        public void AddInstance(OoActionSystemInstance anInstance)
512
        {
513
            m_instances.Add(anInstance);
514
        }
515

    
516
        public OoActionSystemInstance GetNextInstance()
517
        {
518
            OoActionSystemInstance result = m_instances[m_currentInstance];
519
            m_currentInstance++;
520
            return result;
521
        }
522
    }
523

    
524
    ///////////////////////////////////////////////
525
    ///  Constructor: List
526
    ///  
527
    public sealed class ListConstructor : TypeConstructionExpression, IScope
528
    {
529
        private List<Expression> m_elements;
530
        private IScope m_parentScope;
531
        private SymbolTable m_comprehensionVars;
532
        private Expression m_comprehension;
533
        private bool m_hasComprehension = false;
534

    
535
        public List<Expression> elements { get { return m_elements; } }
536
        public Expression comprehension { get { return m_comprehension; } }
537
        public bool hasComprehension { get { return m_hasComprehension; } }
538
        public SymbolTable comprehensionVariables { get { return m_comprehensionVars; } }
539

    
540
        public ListConstructor(int line, int pos)
541
            : base(ExpressionKind.ListConstr, line, pos)
542
        {
543
            m_elements = new List<Expression>();
544
            m_comprehensionVars = new SymbolTable();
545
        }
546

    
547
        public ListConstructor(ListConstructor toCopy)
548
            : base(toCopy)
549
        {
550
            m_elements = new List<Expression>(toCopy.m_elements);
551
            m_parentScope = toCopy.m_parentScope;
552
            m_comprehensionVars = new SymbolTable(toCopy.m_comprehensionVars);
553
            m_comprehension = toCopy.m_comprehension;
554
            m_hasComprehension = toCopy.m_hasComprehension;
555
        }
556

    
557
        public override Expression Clone()
558
        {
559
            return new ListConstructor(this);
560
        }
561

    
562
        public void AddElement(Expression anElement)
563
        {
564
            m_elements.Add(anElement);
565
        }
566

    
567
        public void SetComprehension(Expression comprehension)
568
        {
569
            m_comprehension = comprehension;
570
        }
571

    
572
        public void SetHasComprehension(bool flag)
573
        {
574
            m_hasComprehension = flag;
575
        }
576

    
577
        public Identifier ResolveIdentifier(string aName)
578
        {
579
            if (m_comprehensionVars.Defined(aName))
580
                return m_comprehensionVars.Get(aName);
581
            else
582
                return null;
583
        }
584

    
585
        public IScope GetParentScope()
586
        {
587
            return m_parentScope;
588
        }
589

    
590
        public void SetParentScope(IScope parentScope)
591
        {
592
            m_parentScope = parentScope;
593
        }
594

    
595
        public void AddIdentifier(Identifier anIdentifier, object tag)
596
        {
597
            m_comprehensionVars.AddIdentifier(anIdentifier);
598
        }
599

    
600
        public override void Accept(IAstVisitor visitor)
601
        {
602
            visitor.visit(this);
603
        }
604

    
605
        public void SetElements(List<Expression> newElements)
606
        {
607
            m_elements = newElements;
608
        }
609

    
610
    }
611

    
612
    ///////////////////////////////////////////////
613
    ///  Constructor: Set
614
    ///  
615
    public sealed class SetConstructor : TypeConstructionExpression, IScope
616
    {
617
        private List<Expression> m_items;
618
        private SymbolTable m_comprehensionVars;
619
        private IScope m_parentScope;
620
        private Expression m_comprehension;
621
        private bool m_hasComprehension = false;
622

    
623
        public List<Expression> items { get { return m_items; } }
624
        public Expression comprehension { get { return m_comprehension; } }
625
        public bool hasComprehension { get { return m_hasComprehension; } }
626
        public SymbolTable comprehensionVariables { get { return m_comprehensionVars; } }
627

    
628
        public SetConstructor(int line, int pos)
629
            : base(ExpressionKind.SetConstr, line, pos)
630
        {
631
            m_items = new List<Expression>();
632
            m_comprehensionVars = new SymbolTable();
633
        }
634

    
635
        public SetConstructor(SetConstructor toCopy)
636
            : base(toCopy)
637
        {
638
            m_items = new List<Expression>(toCopy.m_items);
639
            m_comprehensionVars = new SymbolTable(toCopy.m_comprehensionVars);
640
            m_parentScope = toCopy.m_parentScope;
641
            m_comprehension = toCopy.m_comprehension;
642
            m_hasComprehension = toCopy.m_hasComprehension;
643
        }
644

    
645
        public override Expression Clone()
646
        {
647
            return new SetConstructor(this);
648
        }
649

    
650
        public void AddItem(Expression anItem)
651
        {
652
            m_items.Add(anItem);
653
        }
654

    
655
        public void SetComprehension(Expression anExpr)
656
        {
657
            m_comprehension = anExpr;
658
        }
659

    
660
        public void SetHasComprehension(bool flag)
661
        {
662
            m_hasComprehension = flag;
663
        }
664

    
665
        public Identifier ResolveIdentifier(string aName)
666
        {
667
            if (m_comprehensionVars.Defined(aName))
668
                return m_comprehensionVars.Get(aName);
669
            else
670
                return null;
671
        }
672

    
673
        public IScope GetParentScope()
674
        {
675
            return m_parentScope;
676
        }
677

    
678
        public void SetParentScope(IScope parentScope)
679
        {
680
            m_parentScope = parentScope;
681
        }
682

    
683
        public void AddIdentifier(Identifier anIdentifier, object tag)
684
        {
685
            m_comprehensionVars.AddIdentifier(anIdentifier);
686
        }
687

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

    
693
        public void SetItems(List<Expression> newItems)
694
        {
695
            m_items = newItems;
696
        }
697

    
698
    }
699

    
700
    ///////////////////////////////////////////////
701
    ///  Constructor: Map
702
    ///  
703
    public sealed class MapConstructor : TypeConstructionExpression
704
    {
705
        public sealed class MapItem
706
        {
707
            public Expression key;
708
            public Expression value;
709
            public MapItem(Expression aKey, Expression aValue)
710
            {
711
                key = aKey;
712
                value = aValue;
713
            }
714
            public MapItem(MapItem toCopy)
715
            {
716
                key = toCopy.key;
717
                value = toCopy.value;
718
            }
719
        }
720

    
721
        private List<MapItem> m_items;
722

    
723
        public List<MapItem> items { get { return m_items; } }
724

    
725
        public MapConstructor(int line, int pos)
726
            : base(ExpressionKind.MapConstr, line, pos)
727
        {
728
            m_items = new List<MapItem>();
729
        }
730

    
731
        public MapConstructor(MapConstructor toCopy)
732
            : base(toCopy)
733
        {
734
            m_items = new List<MapItem>(toCopy.m_items);
735
        }
736

    
737
        public override Expression Clone()
738
        {
739
            return new MapConstructor(this);
740
        }
741

    
742
        public void AddItem(Expression mapFrom, Expression mapTo)
743
        {
744
            MapItem newitem = new MapItem(mapFrom, mapTo);
745
            m_items.Add(newitem);
746
        }
747

    
748
        public override void Accept(IAstVisitor visitor)
749
        {
750
            visitor.visit(this);
751
        }
752

    
753
        public void SetItems(List<MapItem> newItems)
754
        {
755
            m_items = newItems;
756
        }
757

    
758
    }
759

    
760
    ///////////////////////////////////////////////
761
    ///  Constructor: Tuple
762
    ///  
763
    public sealed class TupleConstructor : TypeConstructionExpression
764
    {
765
        private List<Expression> m_values;
766
        private Identifier m_tupleType;
767
        private bool m_matcher;
768

    
769
        public List<Expression> values { get { return m_values; } }
770
        public Identifier tupleType { get { return m_tupleType; } }
771
        public bool isMatcher { get { return m_matcher; } }
772

    
773

    
774
        public TupleConstructor(Identifier aType, System.Collections.Generic.List<Expression> exprs, int line, int pos)
775
            : base(ExpressionKind.TupleConstr, line, pos)
776
        {
777
            m_tupleType = aType;
778
            m_values = new List<Expression>(exprs);
779
            m_matcher = false;
780
        }
781

    
782
        public TupleConstructor(TupleConstructor toCopy)
783
            : base(toCopy)
784
        {
785
            m_values = new List<Expression>(toCopy.m_values);
786
            m_tupleType = toCopy.m_tupleType;
787
            m_matcher = toCopy.m_matcher;
788
        }
789

    
790
        public void SetIsMatcher(bool newVal)
791
        {
792
            m_matcher = newVal;
793
        }
794

    
795
        public override Expression Clone()
796
        {
797
            return new TupleConstructor(this);
798
        }
799

    
800
        public override void Accept(IAstVisitor visitor)
801
        {
802
            visitor.visit(this);
803
        }
804

    
805
        public void SetTupleValues(List<Expression> values)
806
        {
807
            m_values = values;
808
        }
809
    }
810

    
811

    
812
    ///////////////////////////////////////////////
813
    ///  Constructor: Qualitative Value
814
    ///  
815
    public enum QValDeriv { DonTCare, Dec, Steady, Inc }
816
    public sealed class QValConstructor : TypeConstructionExpression
817
    {
818
        private Expression[] m_value;
819
        private QValDeriv m_derivValue;
820

    
821
        public Expression[] value { get { return m_value; } }
822
        public QValDeriv valueDeriv { get { return m_derivValue; } }
823

    
824

    
825
        public QValConstructor(int line, int pos) :
826
            base(ExpressionKind.QValConstr, line, pos)
827
        {
828
            m_value = new Expression[1];
829
            m_value[0] = null;
830
            m_derivValue = QValDeriv.DonTCare;
831
        }
832

    
833
        public QValConstructor(QValConstructor toCopy)
834
            : base(toCopy)
835
        {
836
            m_value = new Expression[toCopy.m_value.Length];
837
            Array.Copy(toCopy.m_value, m_value, m_value.Length);
838
            m_derivValue = toCopy.m_derivValue;
839
        }
840

    
841
        public override Expression Clone()
842
        {
843
            return new QValConstructor(this);
844
        }
845

    
846

    
847
        public override void Accept(IAstVisitor visitor)
848
        {
849
            visitor.visit(this);
850
        }
851

    
852
        public void SetValue(Expression aval)
853
        {
854
            m_value[0] = aval;
855
        }
856

    
857
        public void AddRange(Expression toRange)
858
        {
859
            Expression currVal = m_value[0];
860
            m_value = new Expression[2];
861
            m_value[0] = currVal;
862
            m_value[1] = toRange;
863
        }
864

    
865
        public void SetDerivation(QValDeriv newValue)
866
        {
867
            m_derivValue = newValue;
868
        }
869
    }
870

    
871

    
872

    
873
    ///////////////////////////////////////////////
874
    ///  === Binary Operator ===
875
    ///  
876
    public class BinaryOperator : Expression
877
    {
878
        protected Expression m_left;
879
        protected Expression m_right;
880

    
881
        public Expression left { get { return m_left; } }
882
        public Expression right { get { return m_right; } }
883

    
884

    
885
        public BinaryOperator(ExpressionKind aKind, Expression left, Expression right, int line, int pos)
886
            : base(aKind, line, pos)
887
        {
888
            m_left = left;
889
            m_right = right;
890
        }
891

    
892
        public BinaryOperator(BinaryOperator toCopy)
893
            : base(toCopy)
894
        {
895
            m_left = toCopy.m_left;
896
            m_right = toCopy.m_right;
897
        }
898

    
899
        public override Expression Clone()
900
        {
901
            return new BinaryOperator(this);
902
        }
903

    
904
        public void SetRightChild(Expression child)
905
        {
906
            m_right = child;
907
        }
908

    
909
        public void SetLeftChild(Expression child)
910
        {
911
            m_left = child;
912
        }
913

    
914
        public override void Accept(IAstVisitor visitor)
915
        {
916
            visitor.visit(this);
917
        }
918

    
919
    }
920

    
921

    
922
    ///////////////////////////////////////////////
923
    ///  Element Access (Point operator):  a.b 
924
    ///  
925
    public sealed class AccessExpression : BinaryOperator
926
    {
927
        public AccessExpression(IdentifierExpression anIdentifier, Expression child, int line, int pos)
928
            : base(ExpressionKind.Access, anIdentifier, child, line, pos)
929
        { }
930

    
931
        public AccessExpression(Expression anExpression, Expression child, int line, int pos)
932
            : base(ExpressionKind.Access, anExpression, child, line, pos)
933
        { }
934

    
935
        public AccessExpression(AccessExpression toCopy)
936
            : base(toCopy)
937
        { }
938

    
939
        public override Expression Clone()
940
        {
941
            return new AccessExpression(this);
942
        }
943

    
944
        public override void Accept(IAstVisitor visitor)
945
        {
946
            visitor.visit(this);
947
        }
948

    
949
    }
950

    
951

    
952

    
953
    ///////////////////////////////////////////////
954
    ///  === Ternary Operator ===
955
    ///  
956
    public sealed class TernaryOperator : Expression
957
    {
958
        private Expression m_left;
959
        private Expression m_mid;
960
        private Expression m_right;
961
        private IScope m_definingScope;
962

    
963
        public Expression left { get { return m_left; } }
964
        public Expression mid { get { return m_mid; } }
965
        public Expression right { get { return m_right; } }
966
        public IScope definingScope { get { return m_definingScope; } }
967

    
968
        public TernaryOperator(ExpressionKind aKind, Expression left, Expression mid, Expression right, int line, int pos, IScope aScope)
969
            : base(aKind, line, pos)
970
        {
971
            m_left = left;
972
            m_mid = mid;
973
            m_right = right;
974
            m_definingScope = aScope;
975
        }
976

    
977
        public TernaryOperator(TernaryOperator toCopy)
978
            : base(toCopy)
979
        {
980
            m_left = toCopy.m_left;
981
            m_mid = toCopy.m_mid;
982
            m_right = toCopy.m_right;
983
            m_definingScope = toCopy.definingScope;
984
        }
985

    
986
        public override Expression Clone()
987
        {
988
            return new TernaryOperator(this);
989
        }
990

    
991
        public override void Accept(IAstVisitor visitor)
992
        {
993
            visitor.visit(this);
994
        }
995

    
996
        public void SetLeftChild(Expression newExpression)
997
        {
998
            m_left = newExpression;
999
        }
1000
        public void SetMidChild(Expression newExpression)
1001
        {
1002
            m_mid = newExpression;
1003
        }
1004
        public void SetRightChild(Expression newExpression)
1005
        {
1006
            m_right = newExpression;
1007
        }
1008

    
1009
    }
1010

    
1011

    
1012

    
1013

    
1014
    ///////////////////////////////////////////////
1015
    ///  === Unary Operators ===
1016
    ///  
1017
    public class UnaryOperator : Expression
1018
    {
1019
        private Expression m_child;
1020

    
1021
        public Expression child { get { return m_child; } }
1022

    
1023
        public UnaryOperator(ExpressionKind aKind, Expression child, int line, int pos)
1024
            : base(aKind, line, pos)
1025
        {
1026
            m_child = child;
1027
        }
1028

    
1029
        public UnaryOperator(UnaryOperator toCopy)
1030
            : base(toCopy)
1031
        {
1032
            m_child = toCopy.m_child;
1033
        }
1034

    
1035
        public override Expression Clone()
1036
        {
1037
            return new UnaryOperator(this);
1038
        }
1039

    
1040
        public void SetChild(Expression child)
1041
        {
1042
            m_child = child;
1043
        }
1044

    
1045
        public override void Accept(IAstVisitor visitor)
1046
        {
1047
            visitor.visit(this);
1048
        }
1049

    
1050
        public static Expression CoerceUp(Expression anExpr, UlyssesType target)
1051
        {
1052
            if (target == null)
1053
                throw new ArgumentException();
1054

    
1055
            if (anExpr.kind == ExpressionKind.Value
1056
                && anExpr.type.kind == target.kind)
1057
            {
1058
                // if we are widening the range of a type assigned to a value, then just set the
1059
                // new type and skip constructing a new node.
1060
                anExpr.SetType(target);
1061
                return anExpr;
1062
            }
1063
            else
1064
            {
1065
                UnaryOperator result = new UnaryOperator(ExpressionKind.Cast, anExpr, anExpr.line, anExpr.pos);
1066
                result.SetType(target);
1067
                return result;
1068
            }
1069
        }
1070

    
1071
        public static Expression TryCoerceUp(Expression anExpr, UlyssesType target)
1072
        {
1073
            if (!UlyssesType.TypeEqual(anExpr.type, target))
1074
            {
1075
                return CoerceUp(anExpr, target);
1076
            }
1077
            else
1078
                return anExpr;
1079
        }
1080

    
1081
    }
1082

    
1083

    
1084
    ///////////////////////////////////////////////
1085
    ///  Tuple and Map Access "[...]"
1086
    ///  
1087
    public sealed class TupleMapAccessExpression : UnaryOperator
1088
    {
1089
        private Expression m_argument;
1090

    
1091
        public Expression argument { get { return m_argument; } }
1092

    
1093
        public TupleMapAccessExpression(Expression child, Expression argument, int line, int pos)
1094
            : base(ExpressionKind.TupleMapAccess, child, line, pos)
1095
        {
1096
            m_argument = argument;
1097
        }
1098

    
1099
        public TupleMapAccessExpression(TupleMapAccessExpression toCopy)
1100
            : base(toCopy)
1101
        {
1102
            m_argument = toCopy.m_argument;
1103
        }
1104

    
1105

    
1106
        public override Expression Clone()
1107
        {
1108
            return new TupleMapAccessExpression(this);
1109
        }
1110

    
1111
        public override void Accept(IAstVisitor visitor)
1112
        {
1113
            visitor.visit(this);
1114
        }
1115

    
1116
        public void SetArgument(Expression newarg)
1117
        {
1118
            if (newarg == null)
1119
                throw new ArgumentException();
1120
            m_argument = newarg;
1121
        }
1122
    }
1123

    
1124

    
1125
    ///////////////////////////////////////////////
1126
    ///  Method call  "(....)"
1127
    ///  
1128
    public sealed class CallExpression : UnaryOperator
1129
    {
1130
        private List<Expression> m_arguments;
1131
        private IScope m_CallScope;
1132

    
1133
        public List<Expression> arguments { get { return m_arguments; } }
1134
        public IScope scope { get { return m_CallScope; } }
1135

    
1136
        public CallExpression(Expression child, List<Expression> arguments, int line, int pos, IScope aScope)
1137
            : base(ExpressionKind.Call, child, line, pos)
1138
        {
1139
            if (arguments != null)
1140
                m_arguments = arguments;
1141
            else
1142
                m_arguments = new List<Expression>();
1143
            m_CallScope = aScope;
1144
        }
1145

    
1146
        public CallExpression(CallExpression toCopy)
1147
            : base(toCopy)
1148
        {
1149
            m_arguments = new List<Expression>(toCopy.m_arguments);
1150
            m_CallScope = toCopy.m_CallScope;
1151
        }
1152

    
1153
        public override Expression Clone()
1154
        {
1155
            return new CallExpression(this);
1156
        }
1157

    
1158
        public override void Accept(IAstVisitor visitor)
1159
        {
1160
            visitor.visit(this);
1161
        }
1162

    
1163
        public void SetArguments(List<Expression> newArgs)
1164
        {
1165
            m_arguments = newArgs;
1166
        }
1167
    }
1168

    
1169

    
1170

    
1171
    ///////////////////////////////////////////////
1172
    ///  Quantifier
1173
    ///  
1174
    public abstract class Quantifier : UnaryOperator, IScope
1175
    {
1176
        private SymbolTable m_symbols;
1177
        private IScope m_parentScope;
1178

    
1179
        public SymbolTable symbols { get { return m_symbols; } }
1180

    
1181

    
1182
        public Quantifier(ExpressionKind aKind, Expression child, int line, int pos)
1183
            : base(aKind, child, line, pos)
1184
        {
1185
            m_symbols = new SymbolTable();
1186
        }
1187

    
1188
        public Quantifier(Quantifier toCopy)
1189
            : base(toCopy)
1190
        {
1191
            m_symbols = new SymbolTable(toCopy.m_symbols);
1192
            m_parentScope = toCopy.m_parentScope;
1193
        }
1194

    
1195

    
1196
        public Identifier ResolveIdentifier(string aName)
1197
        {
1198
            if (m_symbols.Defined(aName))
1199
                return m_symbols.Get(aName);
1200
            else
1201
                return null;
1202
        }
1203

    
1204
        public IScope GetParentScope()
1205
        {
1206
            return m_parentScope;
1207
        }
1208

    
1209
        public void SetParentScope(IScope parentScope)
1210
        {
1211
            m_parentScope = parentScope;
1212
        }
1213

    
1214
        public void AddIdentifier(Identifier anIdentifier, object tag)
1215
        {
1216
            m_symbols.AddIdentifier(anIdentifier);
1217
        }
1218

    
1219

    
1220
    }
1221

    
1222
    public sealed class ForallQuantifier : Quantifier
1223
    {
1224
        public ForallQuantifier(Expression child, int line, int pos)
1225
            : base(ExpressionKind.forall, child, line, pos)
1226
        { }
1227

    
1228
        public ForallQuantifier(ForallQuantifier toCopy)
1229
            : base(toCopy) { }
1230

    
1231
        public override Expression Clone()
1232
        {
1233
            return new ForallQuantifier(this);
1234
        }
1235

    
1236
        public override void Accept(IAstVisitor visitor)
1237
        {
1238
            visitor.visit(this);
1239
        }
1240
    }
1241

    
1242
    public sealed class ExistsQuantifier : Quantifier
1243
    {
1244
        public ExistsQuantifier(Expression child, int line, int pos)
1245
            : base(ExpressionKind.exists, child, line, pos)
1246
        { }
1247
        public ExistsQuantifier(ExistsQuantifier toCopy)
1248
            : base(toCopy) { }
1249

    
1250
        public override Expression Clone()
1251
        {
1252
            return new ExistsQuantifier(this);
1253
        }
1254

    
1255
        public override void Accept(IAstVisitor visitor)
1256
        {
1257
            visitor.visit(this);
1258
        }
1259
    }
1260

    
1261

    
1262
}