Project

General

Profile

root / branches / compiler / cSharp / ooasCompiler / src / codegen / CSharp / ooaCSharpCodeGen.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
/*
20
 * Limited C# code generation capabilities. Used for ooaObjectInstantiateVisitor to
21
 * detect how many objects the system creates.
22
*/
23

    
24
using System;
25
using System.Collections.Generic;
26
using System.Text;
27
using TUG.Mogentes.Codegen;
28

    
29

    
30

    
31
namespace TUG.Mogentes.Codegen.CSharp
32
{
33

    
34
    public sealed class CSharpIdentifier
35
    {
36
        public static string GetIdentifierString(string anIdentifier)
37
        {
38
            return String.Format("_{0}", anIdentifier);
39
        }
40
    }
41

    
42

    
43

    
44
    public sealed class CSharpType : OoaTypeVisitor
45
    {
46
        private OoaCodeEmitter m_emitter = new OoaCodeEmitter();
47

    
48
        private string GetIdentifierString(string anIdentifier)
49
        {
50
            return CSharpIdentifier.GetIdentifierString(anIdentifier);
51
        }
52

    
53

    
54

    
55
        public override void visit(CharType charType)
56
        {
57
            m_emitter.Append("int"); // ToDo: map to char?
58
        }
59

    
60
        public override void visit(IntType intType)
61
        {
62
            m_emitter.Append("int");
63
        }
64

    
65
        public override void visit(BoolType boolType)
66
        {
67
            m_emitter.Append("bool");
68
        }
69

    
70
        public override void visit(FloatType floatType)
71
        {
72
            m_emitter.Append("double");
73
        }
74

    
75
        public override void visit(EnumType enumType)
76
        {
77
            m_emitter.Append(GetIdentifierString(enumType.identifier.tokenText));
78
        }
79

    
80
        public override void visit(ListType listType)
81
        {
82
            m_emitter.Append("TUG.Mogentes.Codegen.CSharp.UlyssesList<object>");
83
            //listType.innerType.Accept(this);
84
            //m_emitter.Append(">");
85
        }
86

    
87
        public override void visit(MapType mapType)
88
        {
89
            //System.Collections.Generic.Dictionary
90
            m_emitter.Append("UlyssesDictionary<object,object>");
91
            //mapType.fromType.Accept(this);
92
            //m_emitter.Append(",");
93
            //mapType.toType.Accept(this);
94
            //m_emitter.Append(">");
95
        }
96

    
97
        public override void visit(QrType qrType)
98
        {
99
            m_emitter.Append("UlyssesQualitativeValue");
100
        }
101

    
102
        public override void visit(TupleType tupleType)
103
        {
104
            // we map a tuple to a struct
105
            m_emitter.Append(GetIdentifierString(tupleType.identifier.tokenText));
106
        }
107
        public override void visit(FunctionType functionType)
108
        {
109
            throw new NotImplementedException();
110
        }
111
        public override void visit(OoActionSystemType ooActionSystemType)
112
        {
113
            m_emitter.Append(GetIdentifierString(ooActionSystemType.identifier.tokenText));
114
        }
115
        public override void visit(OpaqueType opaqueType)
116
        {
117
            throw new NotImplementedException();
118
        }
119

    
120

    
121
        public override string ToString()
122
        {
123
            return m_emitter.ToString();
124
        }
125
    }
126

    
127

    
128

    
129
    public sealed class CSharpExpression : OoaExpressionVisitor
130
    {
131
        private OoaCodeEmitter m_emitter = new OoaCodeEmitter();
132
        private StringBuilder m_helpers;
133
        private static List<ObjectConstructor> m_constructors = new List<ObjectConstructor>();
134

    
135
        private string GetCSharpType(UlyssesType aType)
136
        {
137
            CSharpType sharptype = new CSharpType();
138
            aType.Accept(sharptype);
139
            return sharptype.ToString();
140
        }
141
        private string GetIdentifierString(string anIdentifier)
142
        {
143
            return CSharpIdentifier.GetIdentifierString(anIdentifier);
144
        }
145

    
146
        public static List<ObjectConstructor> constructors { get { return m_constructors; } }
147

    
148
        // following calls must not happen
149
        public override void visit(UnresolvedIdentifierExpression unresolvedIdentifierExpression)
150
        {
151
            System.Diagnostics.Debug.Assert(false);
152
        }
153
        public override void visit(CallExpression callExpression)
154
        {
155
            System.Diagnostics.Debug.Assert(false);
156
        }
157

    
158

    
159
        // we need to map all other things to C# constructs
160
        private string OperatorString(Expression expression)
161
        {
162
            switch (expression.kind)
163
            {
164
                case ExpressionKind.abs:    // T_ABS:
165
                case ExpressionKind.card:   // T_CARD:
166
                case ExpressionKind.dom:    // T_DOM:
167
                case ExpressionKind.range:  // T_RNG:
168
                case ExpressionKind.merge:  // T_MERGE:
169
                case ExpressionKind.len:    // T_LEN:
170
                case ExpressionKind.elems:  // T_ELEMS:
171
                case ExpressionKind.head:   // T_HEAD:
172
                case ExpressionKind.tail:   // T_TAIL:
173
                case ExpressionKind.conc:   // T_CONC:
174
                case ExpressionKind.inds:   // T_INDS:
175
                case ExpressionKind.dinter: // T_DINTER:
176
                case ExpressionKind.dunion: // T_DUNION:
177
                case ExpressionKind.domresby:   // T_DOMRESBY:
178
                case ExpressionKind.domresto:   // T_DOMRESTO:
179
                case ExpressionKind.rngresby:   // T_RNGRESBY:
180
                case ExpressionKind.rngresto:   // T_RNGRESTO:
181
                case ExpressionKind.inter:  // T_INTER:
182
                case ExpressionKind.union:  // T_UNION:
183
                case ExpressionKind.diff:   // T_DIFF:
184
                case ExpressionKind.munion: // T_MUNION:
185
                case ExpressionKind.seqmod_mapoverride: // T_SEQMOD_MAPOVERRIDE:
186
                case ExpressionKind.subset:
187
                case ExpressionKind.elemin:
188
                case ExpressionKind.notelemin:
189
                case ExpressionKind.implies:    // T_IMPLIES:
190
                case ExpressionKind.biimplies:  // T_BIIMPLIES:
191
                case ExpressionKind.Primed:
192
                    throw new NotImplementedException();
193
                case ExpressionKind.div:    // T_DIV:
194
                    return "/";
195
                case ExpressionKind.idiv:   // T_IDIV:
196
                    return "/";
197
                case ExpressionKind.mod:    // T_MOD:
198
                    return "%";
199
                case ExpressionKind.prod:   // T_PROD:
200
                    return "*";
201
                case ExpressionKind.sum:    // T_SUM:
202
                    return "+";
203
                case ExpressionKind.minus:  // T_MINUS:
204
                    return "-";
205
                case ExpressionKind.less:
206
                    return "<";
207
                case ExpressionKind.lessequal:
208
                    return "<=";
209
                case ExpressionKind.greater:
210
                    return ">";
211
                case ExpressionKind.greaterequal:
212
                    return ">=";
213
                case ExpressionKind.equal:
214
                    return "==";
215
                case ExpressionKind.notequal:
216
                    return "!=";
217
                case ExpressionKind.and:    // T_AND:
218
                    return "&&";
219
                case ExpressionKind.or:     // T_OR:
220
                    return "||";
221
                case ExpressionKind.not:
222
                    return "!";
223

    
224
                case ExpressionKind.Cast:
225
                    CSharpType ctype = new CSharpType();
226
                    expression.type.Accept(ctype);
227
                    return String.Format("({0})", ctype.ToString()); ;
228

    
229
                default:
230
                    return Enum.GetName(typeof(ExpressionKind), expression.kind);
231
            }
232
        }
233
        public override void visit<T>(ValueExpression<T> valueExpression)
234
        {
235
            if (valueExpression.value == null)
236
                m_emitter.Append("null");
237
            else if (valueExpression is ValueExpression<bool>)
238
                m_emitter.Append(valueExpression.value.ToString().ToLower());
239
            else
240
                m_emitter.Append(valueExpression.value.ToString());
241
        }
242
        public override void visit(IdentifierExpression identifierExpression)
243
        {
244
            if (identifierExpression.identifier.kind == IdentifierKind.LandmarkIdentifier)
245
            {
246
                LandmarkIdentifier lmid = (LandmarkIdentifier)identifierExpression.identifier;
247
                QrType qr = (QrType)lmid.type;
248
                m_emitter.Append(qr.landmarks.IndexOf(lmid));
249
                return;
250
            }
251

    
252
            if (identifierExpression.identifier.kind == IdentifierKind.EnumIdentifier)
253
            {
254
                m_emitter.Append(GetIdentifierString(((EnumIdentifier)identifierExpression.identifier).type.identifier.tokenText));
255
                m_emitter.Append(".");
256
            }
257

    
258
            m_emitter.Append(GetIdentifierString(identifierExpression.identifier.tokenText));
259
        }
260

    
261
        public override void visit(TypeExpression typeExpression)
262
        {
263
            if (typeExpression.type.kind != TypeKind.QrType &&
264
                typeExpression.type.kind != TypeKind.EnumeratedType)
265
                m_emitter.Append(GetIdentifierString(typeExpression.type.identifier.tokenText));
266
        }
267

    
268

    
269
        public override void visit(ObjectConstructor objectConstructor)
270
        {
271
            int num = m_constructors.Count;
272
            m_constructors.Add(objectConstructor);
273
            if (objectConstructor.givenObjectName != null)
274
                m_emitter.Append(String.Format("new {0}(this,{1},{2})", GetIdentifierString(objectConstructor.type.identifier.tokenText), num, objectConstructor.givenObjectName));
275
            else
276
                m_emitter.Append(String.Format("new {0}(this,{1})", GetIdentifierString(objectConstructor.type.identifier.tokenText), num));
277
        }
278

    
279
        public override void visit(ListConstructor listConstructor)
280
        {
281
            if (listConstructor.hasComprehension)
282
            {
283
                // we need a helper for this.
284
                string helpername = String.Format("list_constr_helper_{0}", ((uint)listConstructor.GetHashCode()).ToString());
285
                m_emitter.Append(String.Format("{0}(new TUG.Mogentes.Codegen.CSharp.UlyssesList<object>())",
286
                    helpername));
287
                OoaCodeEmitter helperEmitter = new OoaCodeEmitter();
288
                helperEmitter.AppendLine(String.Format(
289
                    "public TUG.Mogentes.Codegen.CSharp.UlyssesList<object> {0} (TUG.Mogentes.Codegen.CSharp.UlyssesList<object> newList){{",
290
                     helpername));
291

    
292

    
293
                foreach (var sym in listConstructor.comprehensionVariables.symbolList)
294
                {
295
                    CSharpType atype = new CSharpType();
296
                    sym.type.Accept(atype);
297

    
298
                    if (sym.type.IsNumeric())
299
                        helperEmitter.AppendLine(String.Format("for ({0} {1} = {2}; {1} <= {3}; {1}++) {{",
300
                             atype.ToString(), CSharpIdentifier.GetIdentifierString(sym.tokenText), UlyssesType.Low(sym.type), UlyssesType.High(sym.type)));
301
                    else
302
                        throw new NotImplementedException();
303
                }
304

    
305
                StringBuilder helperhelper = new StringBuilder();
306

    
307

    
308
                string guardexpr = "true";
309
                if (listConstructor.comprehension != null)
310
                {
311
                    CSharpExpression expr = new CSharpExpression(helperhelper);
312
                    listConstructor.comprehension.Accept(expr);
313
                    guardexpr = expr.ToString();
314
                }
315

    
316
                CSharpExpression expr2 = new CSharpExpression(helperhelper);
317
                listConstructor.elements[0].Accept(expr2);
318

    
319
                helperEmitter.AppendLine(String.Format("if ({0}) {{", guardexpr));
320
                helperEmitter.AppendLine(String.Format("newList.Add({0});", expr2.ToString()));
321
                helperEmitter.AppendLine("}");
322

    
323
                foreach (var sym in listConstructor.comprehensionVariables.symbolList)
324
                {
325
                    helperEmitter.AppendLine("}");
326
                }
327
                helperEmitter.AppendLineIncIndent("return newList;");
328
                helperEmitter.AppendLine("}");
329
                m_helpers.Append(helperEmitter.ToString());
330
                m_helpers.Append(helperhelper.ToString());
331
            }
332
            else
333
            {
334
                m_emitter.Append("new TUG.Mogentes.Codegen.CSharp.UlyssesList<object>(");
335
                int i = 0;
336
                if (listConstructor.elements.Count > 0)
337
                {
338
                    m_emitter.Append("new object[] { ");
339
                    foreach (var x in listConstructor.elements)
340
                    {
341
                        if (i != 0)
342
                            m_emitter.Append(",");
343
                        else
344
                            i++;
345
                        x.Accept(this);
346
                    }
347
                    m_emitter.Append(" }");
348
                }
349
                m_emitter.Append(")");
350
            }
351
        }
352

    
353
        public override void visit(SetConstructor setConstructor)
354
        {
355
            throw new NotImplementedException();
356
        }
357

    
358
        public override void visit(MapConstructor mapConstructor)
359
        {
360
            throw new NotImplementedException();
361
        }
362

    
363
        public override void visit(TupleConstructor tupleConstructor)
364
        {
365
            m_emitter.Append(String.Format("new {0}(", GetIdentifierString(tupleConstructor.tupleType.tokenText)));
366
            int i = 0;
367
            foreach (var arg in tupleConstructor.values)
368
            {
369
                if (i != 0)
370
                    m_emitter.Append(",");
371
                else
372
                    i++;
373
                arg.Accept(this);
374
            }
375
            m_emitter.Append(")");
376
        }
377

    
378
        public override void visit(QValConstructor qValConstructor)
379
        {
380
            StringBuilder helpers = new StringBuilder();
381

    
382
            string landmarkOne = "null";
383
            if (qValConstructor.value.Length >= 1 && qValConstructor.value[0] != null)
384
            {
385
                CSharpExpression lndmrk1 = new CSharpExpression(helpers);
386
                qValConstructor.value[0].Accept(lndmrk1);
387
                landmarkOne = lndmrk1.ToString();
388
            }
389
            string landmarkTwo = "null";
390
            if (qValConstructor.value.Length >= 2 && qValConstructor.value[1] != null)
391
            {
392
                CSharpExpression lndmrk = new CSharpExpression(helpers);
393
                qValConstructor.value[1].Accept(lndmrk);
394
                landmarkTwo = lndmrk.ToString();
395
            }
396
            string derivation = "null";
397
            if (qValConstructor.valueDeriv != QValDeriv.DonTCare)
398
            {
399
                derivation = Enum.Format(typeof(QValDeriv), qValConstructor.valueDeriv, "d");
400
            }
401

    
402
            m_helpers.Append(helpers.ToString());
403
            m_emitter.Append(String.Format("new UlyssesQualitativeValue({0},{1},{2})", landmarkOne, landmarkTwo, derivation));
404
        }
405

    
406
        public override void visit(AccessExpression accessExpression)
407
        {
408
            if (accessExpression.left.type.kind != TypeKind.QrType &&
409
                accessExpression.left.type.kind != TypeKind.EnumeratedType)
410
            {
411
                // enums and qr types are directly (statically) converted to nums...
412
                VisitSub(accessExpression.left, accessExpression);
413
                m_emitter.Append(".");
414
            }
415
            VisitSub(accessExpression.right, accessExpression);
416
        }
417

    
418
        public override void visit(BinaryOperator binaryOperator)
419
        {
420
            m_emitter.Append("(");
421
            VisitSub(binaryOperator.left, binaryOperator);
422
            m_emitter.Append(") ");
423
            m_emitter.Append(OperatorString(binaryOperator));
424
            m_emitter.Append(" (");
425
            VisitSub(binaryOperator.right, binaryOperator);
426
            m_emitter.Append(")");
427
        }
428

    
429
        public override void visit(TernaryOperator ternaryOperator)
430
        {
431
            m_emitter.Append("(");
432
            VisitSub(ternaryOperator.left, ternaryOperator);
433
            m_emitter.Append(" ? ");
434

    
435
            VisitSub(ternaryOperator.mid, ternaryOperator);
436
            m_emitter.Append(" : ");
437

    
438
            VisitSub(ternaryOperator.right, ternaryOperator);
439
            m_emitter.Append(")");
440
        }
441
        public override void visit(TupleMapAccessExpression tupleMapAccessExpression)
442
        {
443
            throw new NotImplementedException();
444
            /*VisitSub(tupleMapAccessExpression.argument, tupleMapAccessExpression);
445
            VisitSub(tupleMapAccessExpression.child, tupleMapAccessExpression);*/
446
        }
447
        public override void visit(ForallQuantifier quantifier)
448
        {
449
            throw new NotImplementedException();
450

    
451
            /*foreach (var lvar in quantifier.symbols.symbolList)
452
                VisitSub(lvar, quantifier);
453

    
454
            VisitSub(quantifier.child, quantifier);*/
455
        }
456
        public override void visit(ExistsQuantifier quantifier)
457
        {
458
            throw new NotImplementedException();
459
            /*foreach (var lvar in quantifier.symbols.symbolList)
460
                VisitSub(lvar, quantifier);
461

    
462
            VisitSub(quantifier.child, quantifier);*/
463
        }
464
        public override void visit(UnaryOperator unaryOperator)
465
        {
466
            m_emitter.Append(" ");
467
            m_emitter.Append(OperatorString(unaryOperator));
468
            m_emitter.Append("(");
469
            VisitSub(unaryOperator.child, unaryOperator);
470
            m_emitter.Append(")");
471
        }
472

    
473
        public override string ToString()
474
        {
475
            return m_emitter.ToString();
476
        }
477

    
478
        public CSharpExpression(StringBuilder helpers)
479
            : base()
480
        {
481
            m_helpers = helpers;
482
        }
483
    }
484

    
485
}