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
|
}
|