Project

General

Profile

root / branches / compiler / cSharp / ooasCompiler / src / parser / ooaSymbols.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 TUG.Mogentes.Codegen;
22
using Antlr.Runtime;
23

    
24
namespace TUG.Mogentes
25
{
26

    
27
    public enum IdentifierKind
28
    {
29
        TypeIdentifier,         // some named type
30
        EnumIdentifier,         // identifier of enumerated type
31
        LandmarkIdentifier,     // landmark
32
        AttributeIdentifier,    // global attribute
33
        LocalVariableIdentifier,// local variable
34
        ParameterIdentifier,     // method/named action argument
35
        ExpressionVariableIdentifier, // var in an expression
36
        MethodIdentifier,       // a method
37
        NamedActionIdentifier,  // a named action
38
        Module,                 // the main module - actually this has no name...
39
        List,
40
        Constant
41
    }
42

    
43

    
44
    /* ABSTRACT class Identifier.
45
     * */
46
    public abstract class Identifier : UlyssesBasicClass, IAst, IComparable
47
    {
48
        protected int m_line;
49
        protected int m_column;
50
        protected IScope m_definingScope;
51
        protected IdentifierKind m_identifierKind;
52
        protected string m_tokenText;
53
        protected UlyssesType m_Type;
54

    
55
        // basic attributes of an Identifier
56
        public IdentifierKind kind { get { return m_identifierKind; } } // kind of identifier
57
        public UlyssesType type { get { return m_Type; } }   // type of identifier
58
        public IScope definingScope { get { return m_definingScope; } } // scope where it's defined
59

    
60
        // from lexer
61
        public string tokenText { get { return m_tokenText; } }
62
        public int line { get { return m_line; } }
63
        public int column { get { return m_column; } }
64

    
65
        public AstNodeTypeEnum nodeType { get { return AstNodeTypeEnum.identifier; } }
66

    
67

    
68
        public Identifier(IToken aToken,
69
                          UlyssesType aType,
70
                          IdentifierKind aKind,
71
                          IScope aDefiningScope)
72
        {
73
            m_tokenText = aToken.Text;
74
            m_line = aToken.Line;
75
            m_column = aToken.CharPositionInLine;
76
            m_Type = aType;
77
            m_identifierKind = aKind;
78
            m_definingScope = aDefiningScope;
79
        }
80

    
81
        public Identifier(string name, UlyssesType aType, IdentifierKind aKind, IScope aDefiningScope)
82
        {
83
            m_tokenText = name;
84
            m_line = 0;
85
            m_column = 0;
86
            m_Type = aType;
87
            m_identifierKind = aKind;
88
            m_definingScope = aDefiningScope;
89
        }
90

    
91
        public Identifier(Identifier toCopy)
92
        {
93
            m_tokenText = toCopy.m_tokenText;
94
            m_line = toCopy.m_line;
95
            m_column = toCopy.m_column;
96
            m_Type = toCopy.m_Type;
97
            m_identifierKind = toCopy.m_identifierKind;
98
            m_definingScope = toCopy.m_definingScope;
99
        }
100

    
101
        public virtual Identifier Clone()
102
        {
103
            throw new NotImplementedException();
104
        }
105

    
106

    
107
        public virtual void Accept(IAstVisitor visitor)
108
        {
109
            throw new NotImplementedException();
110
        }
111

    
112
        public void SetType(UlyssesType aType)
113
        {
114
            if (aType == null)
115
                throw new ArgumentException("New type can not be null.");
116

    
117
            m_Type = aType;
118
        }
119

    
120
        public void SetTokenText(string aText)
121
        {
122
            m_tokenText = aText;
123
        }
124

    
125
        public override string ToString()
126
        {
127
            return tokenText;
128
        }
129

    
130
        public int CompareTo(object obj)
131
        {
132
            if (obj is Identifier)
133
                return tokenText.CompareTo(obj.ToString());
134
            else
135
                throw new InvalidCastException();
136
        }
137
    }
138

    
139

    
140
    ///////////////////////////////////////////////
141
    ///  Value Identifiers
142
    ///  
143
    public abstract class ValueIdentifier : Identifier
144
    {
145
        public ValueIdentifier(IToken aToken,
146
                          UlyssesType aType,
147
                          IdentifierKind aKind,
148
                          IScope aDefiningScope)
149
            : base(aToken, aType, aKind, aDefiningScope)
150
        { }
151

    
152
        public ValueIdentifier(ValueIdentifier toCopy)
153
            : base(toCopy)
154
        { }
155
    }
156

    
157

    
158
    public sealed class ConstantIdentifier : ValueIdentifier
159
    {
160
        private Expression m_value;
161

    
162
        public Expression Value { get { return m_value; } }
163

    
164
        public ConstantIdentifier(IToken aToken,
165
                          Expression value,
166
                          IScope aDefiningScope)
167
            : base(aToken, null, IdentifierKind.Constant, aDefiningScope)
168
        {
169
            m_value = value;
170
        }
171

    
172
        public ConstantIdentifier(ConstantIdentifier toCopy)
173
            : base(toCopy)
174
        {
175
            m_value = toCopy.m_value;
176
        }
177

    
178
        public void SetValue(Expression aValue)
179
        {
180
            m_value = aValue;
181
        }
182

    
183
        public override Identifier Clone()
184
        {
185
            return this;
186
        }
187

    
188
        public override void Accept(IAstVisitor visitor)
189
        {
190
            visitor.visit(this);
191
        }
192
    }
193

    
194
    public sealed class EnumIdentifier : ValueIdentifier
195
    {
196
        private int value;
197
        private bool haveValue;
198

    
199
        public int Value { get { return value; } }
200
        public bool HaveValue { get { return haveValue; } }
201

    
202

    
203
        public EnumIdentifier(IToken aToken,
204
                          EnumType aType,
205
                          IScope aDefiningScope)
206
            : base(aToken, aType, IdentifierKind.EnumIdentifier, aDefiningScope)
207
        {
208
            haveValue = false;
209
        }
210

    
211

    
212
        public EnumIdentifier(IToken aToken,
213
                          int aValue,
214
                          EnumType aType,
215
                          IScope aDefiningScope)
216
            : base(aToken, aType, IdentifierKind.EnumIdentifier, aDefiningScope)
217
        {
218
            haveValue = true;
219
            value = aValue;
220
        }
221

    
222

    
223
        public EnumIdentifier(EnumIdentifier toCopy)
224
            : base(toCopy)
225
        {
226
            value = toCopy.value;
227
            haveValue = toCopy.haveValue;
228
        }
229

    
230

    
231
        public override Identifier Clone()
232
        {
233
            return this;
234
        }
235

    
236
        public override void Accept(IAstVisitor visitor)
237
        {
238
            visitor.visit(this);
239
        }
240
    }
241

    
242

    
243
    public sealed class LandmarkIdentifier : ValueIdentifier
244
    {
245
        public LandmarkIdentifier(IToken aToken,
246
                          QrType aType,
247
                          IScope aDefiningScope)
248
            : base(aToken, aType, IdentifierKind.LandmarkIdentifier, aDefiningScope)
249
        { }
250

    
251
        public LandmarkIdentifier(LandmarkIdentifier toCopy)
252
            : base(toCopy)
253
        { }
254

    
255
        public override Identifier Clone()
256
        {
257
            return this;
258
        }
259

    
260
        public override void Accept(IAstVisitor visitor)
261
        {
262
            visitor.visit(this);
263
        }
264
    }
265

    
266

    
267

    
268

    
269
    ///////////////////////////////////////////////
270
    ///  Variable Identifiers
271
    ///  
272

    
273
    public abstract class ValueReferenceIdentifier : Identifier
274
    {
275
        public ValueReferenceIdentifier(IToken aToken,
276
                          UlyssesType aType,
277
                          IdentifierKind aKind,
278
                          IScope aDefiningScope)
279
            : base(aToken, aType, aKind, aDefiningScope)
280
        { }
281

    
282
        public ValueReferenceIdentifier(ValueReferenceIdentifier toCopy)
283
            : base(toCopy)
284
        { }
285

    
286
        public ValueReferenceIdentifier(string name, UlyssesType aType, IdentifierKind aKind, IScope aDefiningScope) :
287
            base(name, aType, aKind, aDefiningScope)
288
        { }
289

    
290
    }
291

    
292

    
293
    public sealed class AttributeIdentifier : ValueReferenceIdentifier
294
    {
295
        private Expression m_initializer;
296
        private bool m_isStatic;
297
        private bool m_isObservable;    // used for qualitative values
298
        private bool m_isControllable;  // used for qualitative values
299

    
300
        public Expression initializer { get { return m_initializer; } }
301
        public bool isStatic { get { return m_isStatic; } }
302
        public bool isObservable { get { return m_isObservable; } }
303
        public bool isControllable { get { return m_isControllable; } }
304

    
305
        public AttributeIdentifier(IToken aToken,
306
                          UlyssesType aType,
307
                          IScope aDefiningScope,
308
                          Expression anInitializer,
309
                          bool isStatic,
310
                          bool isObservable,
311
                          bool isControllable)
312
            : base(aToken, aType, IdentifierKind.AttributeIdentifier, aDefiningScope)
313
        {
314
            m_initializer = anInitializer;
315
            m_isStatic = isStatic;
316
            m_isControllable = isControllable;
317
            m_isObservable = isObservable;
318
        }
319

    
320
        public AttributeIdentifier(AttributeIdentifier toCopy)
321
            : base(toCopy)
322
        {
323
            m_initializer = toCopy.initializer;
324
            m_isStatic = toCopy.m_isStatic;
325
            m_isControllable = toCopy.m_isControllable;
326
            m_isObservable = toCopy.m_isObservable;
327
        }
328

    
329

    
330
        public override Identifier Clone()
331
        {
332
            return new AttributeIdentifier(this);
333
        }
334

    
335
        public override void Accept(IAstVisitor visitor)
336
        {
337
            visitor.visit(this);
338
        }
339

    
340
        public void SetInitializer(Expression newExpr)
341
        {
342
            if (newExpr == null)
343
                throw new ArgumentException();
344
            m_initializer = newExpr;
345
        }
346
    }
347

    
348

    
349
    public class LocalVariableIdentifier : ValueReferenceIdentifier
350
    {
351
        public LocalVariableIdentifier(IToken aToken,
352
                          UlyssesType aType,
353
                          IScope aDefiningScope)
354
            : base(aToken, aType, IdentifierKind.LocalVariableIdentifier, aDefiningScope)
355
        { }
356

    
357
        public LocalVariableIdentifier(LocalVariableIdentifier toCopy)
358
            : base(toCopy)
359
        { }
360

    
361
        public override Identifier Clone()
362
        {
363
            return new LocalVariableIdentifier(this);
364
        }
365

    
366
        public LocalVariableIdentifier(string name, UlyssesType aType, IdentifierKind aKind, IScope aDefiningScope)
367
            : base(name, aType, aKind, aDefiningScope)
368
        { }
369

    
370
        public override void Accept(IAstVisitor visitor)
371
        {
372
            visitor.visit(this);
373
        }
374

    
375
    }
376

    
377

    
378
    public sealed class ParameterIdentifier : LocalVariableIdentifier
379
    {
380
        public ParameterIdentifier(IToken aToken,
381
                          UlyssesType aType,
382
                          IScope aDefiningScope)
383
            : base(aToken, aType, aDefiningScope)
384
        {
385
            m_identifierKind = IdentifierKind.ParameterIdentifier;
386
        }
387

    
388
        public ParameterIdentifier(string name, UlyssesType aType, IScope aDefiningScope)
389
            : base(name, aType, IdentifierKind.ParameterIdentifier, aDefiningScope)
390
        { }
391

    
392
        public ParameterIdentifier(ParameterIdentifier toCopy)
393
            : base(toCopy)
394
        { }
395

    
396
        public override Identifier Clone()
397
        {
398
            return new ParameterIdentifier(this);
399
        }
400

    
401
        public override void Accept(IAstVisitor visitor)
402
        {
403
            visitor.visit(this);
404
        }
405

    
406
    }
407

    
408

    
409
    public sealed class ExpressionVariableIdentifier : LocalVariableIdentifier
410
    {
411
        private bool m_isInitialized;
412

    
413
        public bool initialized { get { return m_isInitialized; } }
414

    
415
        public ExpressionVariableIdentifier(IToken aToken,
416
                          UlyssesType aType,
417
                          IScope aDefiningScope)
418
            : base(aToken, aType, aDefiningScope)
419
        {
420
            m_identifierKind = IdentifierKind.ExpressionVariableIdentifier;
421
        }
422

    
423
        public ExpressionVariableIdentifier(string name, int line, int col)
424
            : base(name, null, IdentifierKind.ExpressionVariableIdentifier, null)
425
        {
426
            m_line = line;
427
            m_column = col;
428
            m_isInitialized = false;
429
        }
430

    
431
        public ExpressionVariableIdentifier(ExpressionVariableIdentifier toCopy)
432
            : base(toCopy)
433
        {
434
            m_line = toCopy.m_line;
435
            m_column = toCopy.m_column;
436
            m_isInitialized = toCopy.m_isInitialized;
437
        }
438

    
439
        public override Identifier Clone()
440
        {
441
            return new ExpressionVariableIdentifier(this);
442
        }
443

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

    
449
        public void SetInitialized(bool newValue)
450
        {
451
            m_isInitialized = newValue;
452
        }
453

    
454
    }
455

    
456

    
457
    ///////////////////////////////////////////////
458
    ///  Type Identifier
459
    ///  
460

    
461
    public class TypeIdentifier : Identifier
462
    {
463
        public string prefix;
464

    
465
        protected TypeIdentifier(IToken aToken,
466
                          UlyssesType aType,
467
                            IdentifierKind someKind,
468
                          IScope aDefiningScope)
469
            : base(aToken, aType, someKind, aDefiningScope)
470
        { }
471

    
472
        protected TypeIdentifier(string aToken,
473
                          UlyssesType aType,
474
                            IdentifierKind someKind,
475
                          IScope aDefiningScope)
476
            : base(aToken, aType, someKind, aDefiningScope)
477
        { }
478

    
479

    
480
        public TypeIdentifier(IToken aToken,
481
                          UlyssesType aType,
482
                          IScope aDefiningScope)
483
            : base(aToken, aType, IdentifierKind.TypeIdentifier, aDefiningScope)
484
        { }
485

    
486

    
487
        public TypeIdentifier(string aName,
488
                          UlyssesType aType,
489
                          IScope aDefiningScope)
490
            : base(aName, aType, IdentifierKind.TypeIdentifier, aDefiningScope)
491
        { }
492

    
493
        public TypeIdentifier(TypeIdentifier toCopy)
494
            : base(toCopy)
495
        {
496
            this.prefix = toCopy.prefix;
497
        }
498

    
499
        public override Identifier Clone()
500
        {
501
            return new TypeIdentifier(this);
502
        }
503

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

    
510
    public sealed class SelfTypeIdentifier : TypeIdentifier
511
    {
512
        public SelfTypeIdentifier(string aName,
513
                          UlyssesType aType,
514
                          IScope aDefiningScope)
515
            : base(aName, aType, aDefiningScope)
516
        { }
517

    
518
        public override void Accept(IAstVisitor visitor)
519
        {
520
            visitor.visit(this);
521
        }
522
    }
523

    
524

    
525
    ///////////////////////////////////////////////
526
    ///  Scope Identifiers
527
    ///  
528
    public abstract class Scope : TypeIdentifier, IScope
529
    {
530
        protected SymbolTable m_symbolTable;
531

    
532
        public Scope(IToken aToken,
533
                     UlyssesType aType,
534
                     IdentifierKind aKind,
535
                     IScope aDefiningScope)
536
            : base(aToken, aType, aKind, aDefiningScope)
537
        {
538
            m_symbolTable = new SymbolTable();
539
        }
540

    
541

    
542
        public Scope(string aName,
543
                     UlyssesType aType,
544
                     IdentifierKind aKind,
545
                     IScope aDefiningScope)
546
            : base(aName, aType, aKind, aDefiningScope)
547
        {
548
            m_symbolTable = new SymbolTable();
549
        }
550

    
551
        public Scope(Scope toCopy)
552
            : base(toCopy)
553
        {
554
            m_symbolTable = toCopy.symbolTable;
555
        }
556

    
557

    
558
        public SymbolTable symbolTable { get { return m_symbolTable; } }
559

    
560
        public IScope GetParentScope()
561
        {
562
            return m_definingScope;
563
        }
564

    
565
        public void SetParentScope(IScope parentScope)
566
        {
567
            m_definingScope = parentScope;
568
        }
569

    
570
        public virtual void AddIdentifier(Identifier anIdentifier, object tag)
571
        {
572
            m_symbolTable.AddIdentifier(anIdentifier);
573
        }
574

    
575
        public Identifier ResolveIdentifier(string aName)
576
        {
577
            if (m_symbolTable.Defined(aName))
578
                return m_symbolTable.Get(aName);
579
            else
580
                return null;
581
        }
582

    
583
    }
584

    
585
    public abstract class FunctionIdentifier : Scope
586
    {
587
        private Block m_body;
588
        private List<ParameterIdentifier> m_parameter = new List<ParameterIdentifier>();
589

    
590
        public Block body { get { return m_body; } }
591
        public List<ParameterIdentifier> parameter { get { return m_parameter; } }
592

    
593

    
594
        public FunctionIdentifier(IToken aToken,
595
                          UlyssesType aType,
596
                          IdentifierKind aKind,
597
                          IScope aDefiningScope)
598
            : base(aToken, aType, aKind, aDefiningScope)
599
        { }
600

    
601
        public FunctionIdentifier(FunctionIdentifier toCopy)
602
            : base(toCopy)
603
        {
604
            m_body = toCopy.m_body;
605
            m_parameter = new List<ParameterIdentifier>(toCopy.m_parameter);
606
        }
607

    
608
        public void SetBody(Block body)
609
        {
610
            m_body = body;
611
        }
612

    
613
        public void AddParameter(ParameterIdentifier aParameter)
614
        {
615
            m_parameter.Add(aParameter);
616
            AddIdentifier(aParameter, null);
617
        }
618
    }
619

    
620

    
621
    public sealed class MethodIdentifier : FunctionIdentifier
622
    {
623
        public MethodIdentifier(IToken aToken,
624
                          UlyssesType aType,
625
                          IScope aDefiningScope)
626
            : base(aToken, aType, IdentifierKind.MethodIdentifier, aDefiningScope)
627
        { }
628

    
629
        public MethodIdentifier(MethodIdentifier toCopy)
630
            : base(toCopy)
631
        { }
632

    
633
        public override Identifier Clone()
634
        {
635
            return new MethodIdentifier(this);
636
        }
637

    
638
        public override void Accept(IAstVisitor visitor)
639
        {
640
            visitor.visit(this);
641
        }
642
    }
643

    
644
    public sealed class NamedActionIdentifier : FunctionIdentifier
645
    {
646
        public NamedActionIdentifier(IToken aToken,
647
                          UlyssesType aType,
648
                          IScope aDefiningScope)
649
            : base(aToken, aType, IdentifierKind.NamedActionIdentifier, aDefiningScope)
650
        { }
651

    
652
        public NamedActionIdentifier(NamedActionIdentifier toCopy)
653
            : base(toCopy)
654
        { }
655

    
656
        public override Identifier Clone()
657
        {
658
            return new NamedActionIdentifier(this);
659
        }
660

    
661
        public override void Accept(IAstVisitor visitor)
662
        {
663
            visitor.visit(this);
664
        }
665
    }
666

    
667
    public class Module : Scope
668
    {
669
        //protected List<OpaqueType> m_typesToFixUp;
670
        //protected List<Expression> m_referencesToResolve;
671

    
672
        //public List<OpaqueType> typesToFixUp { get { return m_typesToFixUp; } }
673
        //public List<Expression> referencesToResolve { get { return m_referencesToResolve; } }
674

    
675
        public Module()
676
            : base("@Module", null, IdentifierKind.Module, null)
677
        {
678
            //m_typesToFixUp = new List<OpaqueType>();
679
            // m_referencesToResolve = new List<Expression>();
680
        }
681

    
682
        public override void Accept(IAstVisitor visitor)
683
        {
684
            visitor.visit(this);
685
        }
686
    }
687

    
688
    public sealed class MainModule : Module
689
    {
690
        private IdentifierList m_systemDescription;
691
        private ActionSystem m_instance;
692

    
693
        public IdentifierList systemDescription { get { return m_systemDescription; } }
694
        public ActionSystem instance { get { return m_instance; } }
695

    
696
        public MainModule()
697
            : base()
698
        {
699
            m_systemDescription = null;
700
        }
701

    
702
        public void SetSystemDescription(IdentifierList aDescr)
703
        {
704
            m_systemDescription = aDescr;
705
        }
706

    
707
        public void SetInstance(ActionSystem anObject)
708
        {
709
            m_instance = anObject;
710
        }
711

    
712
        public override void Accept(IAstVisitor visitor)
713
        {
714
            visitor.visit(this);
715
        }
716
    }
717

    
718

    
719

    
720
    ///////////////////////////////////////////////
721
    ///  Identifier List
722
    ///  
723
    public enum IdentifierListType { normal, nondeterministic, seqential, prioritized }
724
    public abstract class IdentifierList : Identifier
725
    {
726
        private LinkedList<Identifier> m_list;
727
        private IdentifierListType m_type;
728

    
729
        public LinkedList<Identifier> identifiers { get { return m_list; } }
730
        public IdentifierListType listType { get { return m_type; } }
731

    
732
        public IdentifierList(IdentifierListType aConcatType)
733
            : base("list", null, IdentifierKind.List, null)
734
        {
735
            m_list = new LinkedList<Identifier>();
736
            m_type = aConcatType;
737
        }
738

    
739
        public void AddElement(Identifier toAdd)
740
        {
741
            m_list.AddLast(toAdd);
742
        }
743
    }
744

    
745

    
746
    public sealed class NondetIdentifierList : IdentifierList
747
    {
748
        public NondetIdentifierList()
749
            : base(IdentifierListType.nondeterministic)
750
        { }
751

    
752
        public NondetIdentifierList(IdentifierList aParent)
753
            : base(IdentifierListType.nondeterministic)
754
        {
755
            if (aParent != null)
756
                aParent.AddElement(this);
757
        }
758

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

    
765
    public sealed class SeqIdentifierList : IdentifierList
766
    {
767
        public SeqIdentifierList()
768
            : base(IdentifierListType.seqential)
769
        { }
770

    
771
        public SeqIdentifierList(IdentifierList aParent)
772
            : base(IdentifierListType.seqential)
773
        {
774
            if (aParent != null)
775
                aParent.AddElement(this);
776
        }
777

    
778
        public override void Accept(IAstVisitor visitor)
779
        {
780
            visitor.visit(this);
781
        }
782

    
783
    }
784

    
785
    public sealed class PrioIdentifierList : IdentifierList
786
    {
787
        public PrioIdentifierList()
788
            : base(IdentifierListType.prioritized)
789
        { }
790

    
791
        public PrioIdentifierList(IdentifierList aParent)
792
            : base(IdentifierListType.prioritized)
793
        {
794
            if (aParent != null)
795
                aParent.AddElement(this);
796
        }
797

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

    
804
    public sealed class UnspecIdentifierList : IdentifierList
805
    {
806
        public UnspecIdentifierList()
807
            : base(IdentifierListType.normal)
808
        { }
809
        public UnspecIdentifierList(IdentifierList aParent)
810
            : base(IdentifierListType.normal)
811
        {
812
            if (aParent != null)
813
                aParent.AddElement(this);
814
        }
815

    
816
        public override void Accept(IAstVisitor visitor)
817
        {
818
            visitor.visit(this);
819
        }
820
    }
821

    
822

    
823

    
824
}