Project

General

Profile

root / branches / compiler / cSharp / ooasCompiler / src / parser / visitors / ooaObjectsInstantiateVisitor.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
/*
20
 * Visitor that "compiles down" objects to normal action systems
21
 * Implementing the algorithm layed out in 
22
 * Bonsangue, Kok, Sere: An Approach to Object-Orientation in Action Systems, In
23
 * MPC'98, LNCS 1422, pp. 68{95, 1998
24
 *
25
 * Notes:
26
 * 
27
 *    WE DO OBJECT INSTANTIATION HERE: This means (more or less) that we will duplicate all the 
28
 *    classes found. In particular we will create one copy per object. In order to do that, we
29
 *    need to know exactly how many objects of a certain type there will be. We also need to assign each of these
30
 *    new action systems a particular name. Hence within this compilation step, we need to do 
31
 *    the following.
32
 * 
33
 *  -) need to count number of constructed objects per class (in order to be able to assign names)
34
 *       => This is implemented by compiling the action system initialization to CSharp Code and 
35
 *          subsequently running the initialization step.
36
 *  -) each action system (resembling an object now) gets a name that encodes the class name, and 
37
 *       information about which object created the new object.
38
 *       => Per class: find root element, and do instantiation. Then iterate through all objects and
39
 *          do instantiation for objects created in these.... (It makes sense to forbid creation of
40
 *          objects of class A in class A...)
41
 *  -) after the names are known, start instantiation (=copy) process and add necessary runtime 
42
 *       code (see the paper)
43
 * 
44
 * 
45
*/
46
using System;
47
using System.Collections.Generic;
48
using System.Text;
49
using TUG.Mogentes.Codegen;
50
using TUG.Mogentes.Codegen.CSharp;
51

    
52

    
53
namespace TUG.Mogentes
54
{
55
    internal sealed class OoaDummyCheckVisitor : OoaExpressionVisitor
56
    {
57
        public override void visit(AccessExpression accessExpression)
58
        {
59
            if (accessExpression.left.type == null)
60
                System.Console.WriteLine("outch");
61
            base.visit(accessExpression);
62
        }
63

    
64
        public OoaDummyCheckVisitor()
65
        {
66
        }
67

    
68
    }
69

    
70

    
71
    public sealed class OoaObjectInstantiationVisitor : OoaCompleteAstTraversalVisitor
72
    {
73
        private OoaCSharpInitVisitor m_simulator;
74
        private ActionSystem m_actionSystem;
75
        private Identifier self;
76
        private Dictionary<object, object> m_toReplace = new Dictionary<object, object>();
77

    
78
        /// <summary>
79
        /// for a given object and type, the method duplicates the attributes and adds them to the resulting
80
        /// instantiated action system.
81
        /// </summary>
82
        private void DuplicateAttribute(AttributeIdentifier attributeIdentifier,
83
            OoActionSystemInstance obj, OoActionSystemType aType, ActionSystem m_actionSystem)
84
        {
85
            AttributeIdentifier newAttribute = new AttributeIdentifier(attributeIdentifier);
86
            newAttribute.SetTokenText(String.Format("{0}_{1}", obj.Name, attributeIdentifier.tokenText));
87
            m_toReplace.Add(attributeIdentifier, newAttribute);
88

    
89
            newAttribute.SetInitializer(newAttribute.initializer.Clone());
90
            OoaDeepCloneVisitor cloner = new OoaDeepCloneVisitor(m_toReplace, self);
91
            newAttribute.initializer.Accept(cloner);
92

    
93
            m_actionSystem.symbols.AddIdentifier(newAttribute);
94
        }
95

    
96
        private void DuplicateNamedAction(NamedActionIdentifier namedActionIdentifier,
97
            OoActionSystemInstance obj, OoActionSystemType aType, ActionSystem m_actionSystem)
98
        {
99
            NamedActionIdentifier newAction = new NamedActionIdentifier(namedActionIdentifier);
100
            newAction.SetTokenText(String.Format("{0}_{1}", obj.Name, namedActionIdentifier.tokenText));
101
            m_toReplace.Add(namedActionIdentifier, newAction);
102
            OoaDeepCloneVisitor cloner = new OoaDeepCloneVisitor(m_toReplace, self);
103
            newAction.Accept(cloner);
104

    
105
            m_actionSystem.symbols.AddIdentifier(newAction);
106
        }
107

    
108
        public static string GetInstanceFunctionName(OoActionSystemInstance obj, FunctionIdentifier afunction)
109
        {
110
            return String.Format("{0}_{1}", obj.Name, afunction.tokenText);
111
        }
112

    
113
        private void DuplicateMethod(MethodIdentifier methodIdentifier, OoActionSystemInstance obj,
114
            OoActionSystemType aType, ActionSystem m_actionSystem)
115
        {
116
            MethodIdentifier newMethod = new MethodIdentifier(methodIdentifier);
117
            newMethod.SetTokenText(GetInstanceFunctionName(obj, methodIdentifier));
118
            m_toReplace.Add(methodIdentifier, newMethod);
119

    
120
            newMethod.SetBody((Block)newMethod.body.Clone());
121
            OoaDeepCloneVisitor cloner = new OoaDeepCloneVisitor(m_toReplace, self);
122
            newMethod.body.Accept(cloner);
123

    
124
            m_actionSystem.symbols.AddIdentifier(newMethod);
125
        }
126

    
127

    
128
        /*Duplicates the do-od block (incl. any do-od blocks of parent classes)*/
129
        private void DuplicateDoOdBlock(OoActionSystemInstance obj, OoActionSystemType aType, ActionSystem m_actionSystem, Block result)
130
        {
131
            OoActionSystemType rootType = aType;
132
            Block block;
133
            while (aType != null)
134
            {
135
                block = aType.doOdBlock;
136
                if (block != null)
137
                {
138
                    Block clone = (Block)block.Clone();
139
                    OoaDeepCloneVisitor cloner = new OoaDeepCloneVisitor(m_toReplace, self);
140
                    clone.Accept(cloner);
141
                    result.AddStatement(clone);
142
                }
143
                aType = aType.baseType;
144
            }
145
        }
146

    
147
        Dictionary<object, object> objectsdone = new Dictionary<object, object>();
148

    
149
        /// <summary>
150
        /// Generates an OoActionSystemType that is the instantiation of all the objects found in the System Assembling Block
151
        /// </summary>
152
        private void InstantiateObjects(ActionSystem m_actionSystem, MainModule mainModule, IdentifierList sysdescr, Block parent)
153
        {
154

    
155
            //C5.HashSet<OoActionSystemInstance> done = new C5.HashSet<OoActionSystemInstance>();
156
            //
157

    
158
            Block newBlock;
159
            switch (sysdescr.listType)
160
            {
161
                case IdentifierListType.nondeterministic:
162
                    newBlock = new NondetBlock(0, 0);
163
                    break;
164
                case IdentifierListType.prioritized:
165
                    newBlock = new PrioBlock(0, 0);
166
                    break;
167
                case IdentifierListType.seqential:
168
                    newBlock = new SeqBlock(0, 0);
169
                    break;
170

    
171
                case IdentifierListType.normal:
172
                default:
173
                    throw new NotImplementedException();
174
            }
175

    
176
            if (parent == null)
177
                m_actionSystem.SetDoOdBlock(newBlock);
178
            else
179
                parent.AddStatement(newBlock);
180

    
181
            foreach (var id in sysdescr.identifiers)
182
            {
183
                Identifier ident = id;
184
                while (ident.kind == IdentifierKind.List && ((IdentifierList)ident).identifiers.Count == 1)
185
                {
186
                    ident = ((IdentifierList)ident).identifiers.First.Value;
187
                }
188

    
189
                if (ident.kind == IdentifierKind.List)
190
                    InstantiateObjects(m_actionSystem, mainModule, (IdentifierList)ident, newBlock);
191
                else
192
                {
193
                    if (ident.kind == IdentifierKind.TypeIdentifier &&
194
                        ((TypeIdentifier)ident).type.kind == TypeKind.OoActionSystemType)
195
                    {
196

    
197
                        OoActionSystemType aType = (OoActionSystemType)((TypeIdentifier)ident).type;
198
                        objectsdone.Add(aType, m_actionSystem);
199

    
200

    
201
                        Block NondetBlock = null; // holds parallel comp of all objects
202
                        if (aType.doOdBlock != null)
203
                        {
204
                            NondetBlock = new NondetBlock(0, 0);
205
                            newBlock.AddStatement(NondetBlock);
206
                        }
207

    
208

    
209
                        foreach (var obj in aType.objects)
210
                        {
211
                            m_toReplace = new Dictionary<object, object>(objectsdone);
212
                            addParentClassMappings(m_toReplace, aType, m_actionSystem);
213
                            self = new SelfTypeIdentifier(obj.Name, aType, null);
214
                            SymbolTable table = aType.getAllSymbols();
215
                            foreach (var x in table.symbolList)
216
                            {
217
                                // resolve attributes first
218
                                if (x.kind == IdentifierKind.AttributeIdentifier)
219
                                    DuplicateAttribute((AttributeIdentifier)x, obj, aType, m_actionSystem);
220
                            }
221
                            foreach (var x in table.symbolList)
222
                            {
223
                                // now do methods and other stuff
224
                                if (x.kind == IdentifierKind.MethodIdentifier)
225
                                    DuplicateMethod((MethodIdentifier)x, obj, aType, m_actionSystem);
226
                                else if (x.kind == IdentifierKind.NamedActionIdentifier)
227
                                    DuplicateNamedAction((NamedActionIdentifier)x, obj, aType, m_actionSystem);
228
                            }
229
                            // construct parallel composition of all the objects of one class.
230
                            if (aType.doOdBlock != null)
231
                            {
232
                                DuplicateDoOdBlock(obj, aType, m_actionSystem, NondetBlock);
233
                            }
234
                        }
235

    
236
                        // add an error, if a type does not get instantiated and the do-od block is filled..
237
                        // !!!!!!!!!!!!!!! note, if new is also allowed in normal actions, this needs to be disabled (or become a warning) !!!!!!!!!!!!!!!!!!!!!!!!!!
238
                        if (aType.objects.Count == 0 && aType.doOdBlock != null)
239
                        {
240
                            m_ParserState.AddErrorMessage(new ParserError(m_ParserState.filename, aType.identifier.line, aType.identifier.column,
241
                                String.Format("Type '{0}' is never instantiated but has a non-empty do-od block", aType.ToString())));
242
                        }
243

    
244

    
245
                    }
246
                    else
247
                        throw new NotImplementedException();
248
                }
249
            }
250
        }
251

    
252
        private void addParentClassMappings(Dictionary<object, object> m_toReplace, OoActionSystemType aType, ActionSystem m_actionSystem)
253
        {
254
            while (aType != null)
255
            {
256
                if (!m_toReplace.ContainsKey(aType))
257
                    m_toReplace.Add(aType, m_actionSystem); // add base classes to mapping...
258
                aType = aType.baseType;
259
            }
260
        }
261

    
262
        /// <summary>
263
        /// Adds those objects of types that are not found in the SAB.
264
        /// </summary>
265
        private void InstantiatePassiveObjects(ActionSystem m_actionSystem, MainModule mainModule)
266
        {
267
            foreach (var x in mainModule.symbolTable.symbolList)
268
            {
269
                if (x.type.kind == TypeKind.OoActionSystemType && !objectsdone.ContainsKey(x.type))
270
                    if (((OoActionSystemType)x.type).autoConstruction)
271
                    {
272
                        OoActionSystemType aType = (OoActionSystemType)x.type;
273
                        m_ParserState.AddErrorMessage(new ParserError(m_ParserState.filename, aType.identifier.line, aType.identifier.column,
274
                            String.Format("Type '{0}' marked autocons but omitted in system description!", aType.ToString())));
275
                    }
276
                    else
277
                    {
278
                        OoActionSystemType aType = (OoActionSystemType)x.type;
279
                        foreach (var obj in aType.objects)
280
                        {
281
                            m_toReplace = new Dictionary<object, object>(objectsdone);
282
                            addParentClassMappings(m_toReplace, aType, m_actionSystem);
283
                            self = new SelfTypeIdentifier(obj.Name, aType, null);
284
                            SymbolTable table = aType.getAllSymbols();
285
                            foreach (var y in table.symbolList)
286
                            {
287
                                // resolve attributes first
288
                                if (y.kind == IdentifierKind.AttributeIdentifier)
289
                                    DuplicateAttribute((AttributeIdentifier)y, obj, aType, m_actionSystem);
290
                            }
291
                            foreach (var y in table.symbolList)
292
                            {
293
                                // now do methods
294
                                if (y.kind == IdentifierKind.MethodIdentifier)
295
                                    DuplicateMethod((MethodIdentifier)y, obj, aType, m_actionSystem);
296
                                //else if (y.kind == IdentifierKind.NamedActionIdentifier)
297
                                //    m_ParserState.AddErrorMessage(new ParserError(m_ParserState.filename, aType.identifier.line, aType.identifier.column,
298
                                //        String.Format("Type '{0}' has named actions but was omitted in system description!", aType.ToString())));
299
                            }
300
                            if (aType.doOdBlock != null)
301
                                m_ParserState.AddErrorMessage(new ParserError(m_ParserState.filename, aType.identifier.line, aType.identifier.column,
302
                                    String.Format("Type '{0}' has do-od block but was omitted in system description!", aType.ToString())));
303
                        }
304

    
305
                    }
306
            }
307
        }
308

    
309

    
310

    
311

    
312

    
313
        public override void visit(MainModule mainModule)
314
        {
315
            if (mainModule.systemDescription == null)
316
                return;
317

    
318
            /* determine names of objects */
319
            mainModule.Accept(m_simulator);
320

    
321
            /* add information about all the objects to the AST */
322
            //mainModule.SetObjects(m_simulator.initialObjectWorkingSet);
323
            m_actionSystem = new ActionSystem();
324
            m_actionSystem.SetParentScope(mainModule);
325
            InstantiateObjects(m_actionSystem, mainModule, mainModule.systemDescription, m_actionSystem.doOdBlock);
326
            InstantiatePassiveObjects(m_actionSystem, mainModule);
327

    
328
            mainModule.SetInstance(m_actionSystem);
329

    
330
        }
331

    
332
        public override string ToString()
333
        {
334
            return m_simulator.ToString();
335
        }
336

    
337

    
338
        public OoaObjectInstantiationVisitor(ParserState aState)
339
            : base(aState)
340
        {
341
            m_simulator = new OoaCSharpInitVisitor(aState);
342
        }
343
    }
344
}