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