The StaDyn Programming Language
Source code documentation of StaDyn, a hybrid static and dynamic typing language.
PromotionLevelOperation.cs
Go to the documentation of this file.
1 using System.Collections.Generic;
2 using DynVarManagement;
3 using System;
4 namespace TypeSystem.Operations {
15 
17 
18  #region Fields
20  #endregion
21 
22  #region Constructors
23  public PromotionLevelOperation(TypeExpression secondOperand) {
24  this.secondOperand = secondOperand;
25  }
26  #endregion
27 
28  #region Array-->#
29  public override object Exec(ArrayType firstOperand, object arg) {
35  // * Array and bounded type variable
36  ArrayType array = TypeExpression.As<ArrayType>(this.secondOperand);
37  if (array != null)
38  return firstOperand.ArrayTypeExpression.Equals(array.ArrayTypeExpression) ? 0 : -1;
39  // * A free variable is a complete promotion
40  TypeVariable typeVariable = this.secondOperand as TypeVariable;
41  if (typeVariable != null && typeVariable.Substitution == null)
42  return 0;
43  // * Union type and bounded type variable
44  UnionType unionType = TypeExpression.As<UnionType>(this.secondOperand);
45  if (unionType != null)
46  return unionType.SuperType(firstOperand);
47  // * Field type and bounded type variable
48  FieldType fieldType = TypeExpression.As<FieldType>(this.secondOperand);
49  if (fieldType != null)
50  return firstOperand.AcceptOperation(new PromotionLevelOperation(fieldType.FieldTypeExpression), arg);
51  // * Use the BCL object oriented approach
52  return firstOperand.AsClassType().AcceptOperation(this, arg);
53  }
54  #endregion
55 
56  #region Bool-->#
57  public override object Exec(BoolType firstOperand, object arg) {
63  // * Bool type and type variable
64  if (TypeExpression.As<BoolType>(this.secondOperand) != null)
65  return 0;
66 
67  // * WriteType variable
68  TypeVariable typeVariable = this.secondOperand as TypeVariable;
69 
70  if (typeVariable != null && typeVariable.Substitution == null)
71  // * A free variable is complete promotion
72  return 0;
73 
74  // * Union type
75  UnionType unionType = TypeExpression.As<UnionType>(this.secondOperand);
76  if (unionType != null)
77  return unionType.SuperType(firstOperand);
78 
79  // * Field type and bounded type variable
80  FieldType fieldType = TypeExpression.As<FieldType>(this.secondOperand);
81  if (fieldType != null)
82  return firstOperand.AcceptOperation(new PromotionLevelOperation(fieldType.FieldTypeExpression), arg);
83 
84  // * Use the BCL object oriented approach
85  return firstOperand.AsClassType().AcceptOperation(this, arg);
86  }
87  #endregion
88 
89  #region ClasType-->#
90  public override object Exec(ClassType firstOperand, object arg) {
91  int aux, less = -1;
92  EquivalentOperation equivalentType = new EquivalentOperation(this.secondOperand);
93 
94  // * The same type
95  if (firstOperand == this.secondOperand)
96  return 0;
97  // * Equivalent types
98  if ((bool)firstOperand.AcceptOperation(equivalentType, arg))
99  return 0;
100 
101  // * Field type and bounded type variable
102  FieldType fieldType = TypeExpression.As<FieldType>(this.secondOperand);
103  if (fieldType != null)
104  return firstOperand.AcceptOperation(new PromotionLevelOperation(fieldType.FieldTypeExpression), arg);
105 
106  // * WriteType variable
107  TypeVariable typeVariable = this.secondOperand as TypeVariable;
108  if (typeVariable != null) {
109  if (typeVariable.Substitution != null)
110  // * If the variable is bounded, the promotion is the one of its substitution
111  return firstOperand.AcceptOperation(new PromotionLevelOperation(typeVariable.EquivalenceClass.Substitution), arg);
112  // * A free variable is complete promotion
113  return 0;
114  }
115 
116  // * Inheritance
117  if (firstOperand.BaseClass == null)
118  // * Object only promotes to object
119  return -1;
120  if ((bool)firstOperand.BaseClass.AcceptOperation(equivalentType, arg))
121  return 1;
122  else {
123  //aux = firstOperand.baseClass.AcceptOperation(new PromotionLevelOperation(this.secondOperand)));
124  aux = (int)firstOperand.BaseClass.AcceptOperation(this, arg);
125  if (aux != -1)
126  return aux + 1;
127  }
128 
129  // * Interfaces
130  if (firstOperand.InterfaceList.Count != 0) {
131  for (int i = 0; i < firstOperand.InterfaceList.Count; i++) {
132  if ((bool)firstOperand.InterfaceList[i].AcceptOperation(equivalentType, arg)) {
133  if (less > 1 || less == -1)
134  less = 1;
135  } else {
136  aux = (int)firstOperand.InterfaceList[i].AcceptOperation(this, arg);
137  if (aux != -1) {
138  if (less > aux + 1 || less == -1)
139  less = aux + 1;
140  }
141  }
142  }
143  }
144  if (less != -1)
145  return less;
146 
147  // * Union type
148  UnionType unionType = TypeExpression.As<UnionType>(this.secondOperand);
149  if (unionType != null)
150  return unionType.SuperType(firstOperand);
151 
152  // * No promotion
153  return -1;
154  }
155  #endregion
156 
157  #region ClassTypeProxy-->#
158  public override object Exec(ClassTypeProxy firstOperand, object arg) {
159  return firstOperand.RealType.AcceptOperation(this, arg); //OJO CON LA RECURSIVIDAD
160  }
161  #endregion
162 
163  #region Char->#
164  public override object Exec(CharType firstOperand, object arg) {
165  // * Char type and type variable
166  if (TypeExpression.As<CharType>(this.secondOperand) != null)
167  return 0;
168  // * Int type and type variable
169  if (TypeExpression.As<IntType>(this.secondOperand) != null)
170  return 1;
171  // * Double type and type variable
172  if (TypeExpression.As<DoubleType>(this.secondOperand) != null)
173  return 2;
174  // * Free type variables
175  TypeVariable typeVariable = this.secondOperand as TypeVariable;
176  if (typeVariable != null && typeVariable.Substitution == null)
177  // * A free variable is complete promotion
178  return 0;
179  // * Union type
180  UnionType unionType = TypeExpression.As<UnionType>(this.secondOperand);
181  if (unionType != null)
182  return unionType.SuperType(firstOperand);
183  // * Field type and bounded type variable
184  FieldType fieldType = TypeExpression.As<FieldType>(this.secondOperand);
185  if (fieldType != null)
186  return firstOperand.AcceptOperation(new PromotionLevelOperation(fieldType.FieldTypeExpression), arg);
187  // * Use the BCL object oriented approach
188  //return firstOperand.BCLType.AcceptOperation(new PromotionLevelOperation(this.secondOperand)));
189  return firstOperand.AsClassType().AcceptOperation(this, arg);
190  }
191 
192  #endregion
193 
194 
195  #region Double-->#
196  public override object Exec(DoubleType firstOperand, object arg) {
197  // * Double type and bounded type variable
198  if (TypeExpression.As<DoubleType>(this.secondOperand) != null)
199  return 0;
200  // * WriteType variable
201  TypeVariable typeVariable = this.secondOperand as TypeVariable;
202  if (typeVariable != null && typeVariable.Substitution == null)
203  // * A free variable is complete promotion
204  return 0;
205  // * Union type
206  UnionType unionType = TypeExpression.As<UnionType>(this.secondOperand);
207  if (unionType != null)
208  return unionType.SuperType(firstOperand);
209  // * Field type and bounded type variable
210  FieldType fieldType = TypeExpression.As<FieldType>(this.secondOperand);
211  if (fieldType != null)
212  return firstOperand.AcceptOperation(new PromotionLevelOperation(fieldType.FieldTypeExpression), arg);
213  // * Use the BCL object oriented approach
214  return firstOperand.AsClassType().AcceptOperation(this, arg);
215  }
216 
217  #endregion
218 
219  #region FieldType-->#
220  public override object Exec(FieldType firstOperand, object arg) {
221  if (firstOperand.FieldTypeExpression != null)
222  return firstOperand.FieldTypeExpression.AcceptOperation(this, arg);
223  return -1;
224  }
225  #endregion
226 
227  #region InterfaceType-->#
228  public override object Exec(InterfaceType firstOperand, object arg) {
229  int aux, less = -1;
230  // * Equivalent types
231  if ( (bool)firstOperand.AcceptOperation(new EquivalentOperation(this.secondOperand), arg) )
232  less = 0;
233 
234  // * WriteType variable
235  TypeVariable typeVariable = this.secondOperand as TypeVariable;
236  if (typeVariable != null) {
237  if (typeVariable.Substitution != null)
238  // * If the variable is bounded, the promotion is the one of its substitution
239  return firstOperand.AcceptOperation(new PromotionLevelOperation(typeVariable.EquivalenceClass.Substitution), arg);
240  // * A free variable is complete promotion
241  return 0;
242  }
243 
244  // * Field type and bounded type variable
245  FieldType fieldType = TypeExpression.As<FieldType>(this.secondOperand);
246  if (fieldType != null)
247  return firstOperand.AcceptOperation(new PromotionLevelOperation(fieldType.FieldTypeExpression), arg);
248 
249  // * Interface List
250  if (firstOperand.InterfaceList.Count != 0) {
251  for (int i = 0; i < firstOperand.InterfaceList.Count; i++) {
252  if ( (bool)firstOperand.InterfaceList[i].AcceptOperation(new EquivalentOperation(this.secondOperand), arg) ) {
253  if ((less > 1) || (less == -1))
254  less = 1;
255  } else {
256  aux = (int)firstOperand.InterfaceList[i].AcceptOperation(this, arg);
257  if (aux != -1) {
258  if (less > aux + 1 || less == -1)
259  less = aux + 1;
260  }
261  }
262  }
263  }
264  if (less != -1)
265  return less;
266 
267  // * Union type
268  UnionType unionType = TypeExpression.As<UnionType>(this.secondOperand);
269  if (unionType != null)
270  return unionType.SuperType(firstOperand);
271 
272  // * No promotion
273  return -1;
274  }
275  #endregion
276 
277  #region IntType-->#
278  public override object Exec(IntType firstOperand, object arg) {
279  // * Int type and bounded type variable
280  if (TypeExpression.As<IntType>(this.secondOperand) != null)
281  return 0;
282  // * Double type and bounded type variable
283  if (TypeExpression.As<DoubleType>(this.secondOperand) != null)
284  return 1;
285  // * WriteType variable
286  TypeVariable typeVariable = this.secondOperand as TypeVariable;
287  if (typeVariable != null && typeVariable.Substitution == null)
288  return 0;
289  // * Union type
290  UnionType unionType = TypeExpression.As<UnionType>(this.secondOperand);
291  if (unionType != null)
292  return unionType.SuperType(firstOperand);
293  // * Field type and bounded type variable
294  FieldType fieldType = TypeExpression.As<FieldType>(this.secondOperand);
295  if (fieldType != null)
296  return firstOperand.AcceptOperation(new PromotionLevelOperation(fieldType.FieldTypeExpression), arg);
297  // * Use the BCL object oriented approach
298  return firstOperand.AsClassType().AcceptOperation(this, arg);
299  }
300  #endregion
301 
302  #region NullType-->#
303  public override object Exec(NullType firstOperand, object arg) {
304  // * Built-in types: no promotion, except string
305  if (this.secondOperand is BoolType || this.secondOperand is CharType || this.secondOperand is DoubleType || this.secondOperand is IntType || this.secondOperand is VoidType)
306  return -1;
307  // * BCL Value Types (structs): No promotion
308  BCLClassType bclClass = TypeExpression.As<BCLClassType>(this.secondOperand);
309  if (bclClass != null) {
310  if (bclClass.TypeInfo.IsValueType)
311  return -1;
312  // * Correct promotion to classes that are not value types
313  return 0;
314  }
315  // * WriteType variable
316  TypeVariable typeVariable = this.secondOperand as TypeVariable;
317  if (typeVariable != null) {
318  if (typeVariable.Substitution != null)
319  // * If the variable is bounded, the promotion is the one of its substitution
320  return firstOperand.AcceptOperation(new PromotionLevelOperation(typeVariable.EquivalenceClass.Substitution), arg);
321  // * A free variable is complete promotion
322  return 0;
323  }
324  // * Union type
325  UnionType unionType = TypeExpression.As<UnionType>(this.secondOperand);
326  if (unionType != null)
327  return unionType.SuperType(firstOperand);
328  // * Field type and bounded type variable
329  FieldType fieldType = TypeExpression.As<FieldType>(this.secondOperand);
330  if (fieldType != null)
331  return firstOperand.AcceptOperation(new PromotionLevelOperation(fieldType.FieldTypeExpression), arg);
332  // * Correct Promotion
333  return 0;
334  }
335  #endregion
336 
337  #region PropertyType-->#
338  public override object Exec(PropertyType firstOperand, object arg) {
339  if (firstOperand.PropertyTypeExpression != null)
340  return firstOperand.PropertyTypeExpression.AcceptOperation(this, arg);
341  return -1;
342  }
343 
344  #endregion
345 
346  #region StringType-->#
347 
348  public override object Exec(StringType firstOperand, object arg) {
349  // * String WriteType and bounded type variables
350  if (TypeExpression.As<StringType>(this.secondOperand) != null)
351  return 0;
352  // * WriteType variable
353  TypeVariable typeVariable = this.secondOperand as TypeVariable;
354  if (typeVariable != null && typeVariable.Substitution == null)
355  // * A free variable is complete promotion
356  return 0;
357  // * Union type
358  UnionType unionType = TypeExpression.As<UnionType>(this.secondOperand);
359  if (unionType != null)
360  return unionType.SuperType(firstOperand);
361  // * Field type and bounded type variable
362  FieldType fieldType = TypeExpression.As<FieldType>(this.secondOperand);
363  if (fieldType != null)
364  return firstOperand.AcceptOperation(new PromotionLevelOperation(fieldType.FieldTypeExpression), arg);
365  // * Use the BCL object oriented approach
366  return firstOperand.AsClassType().AcceptOperation(this, arg);
367  }
368 
369  #endregion
370 
371 
372  #region TypeExpression-->#
373  public override object Exec(TypeExpression type, object arg) {
374  return -1;
375  }
376  #endregion
377 
378 
379  #region TypeVariable-->#
380  public override object Exec(TypeVariable firstOperand, object arg) {
381  if (firstOperand.Substitution != null) {
382  DynVarOptions.Instance.AssignDynamism(firstOperand.Substitution, firstOperand.IsDynamic);
383  // * If the variable is bounded, the promotion is the one of its substitution
384  return firstOperand.EquivalenceClass.Substitution.AcceptOperation(this, arg);
385  }
386  // * A free variable is complete promotion
387  return 0;
388  }
389  #endregion
390 
391  #region UnionType-->#
392 
393  // * To detect recursive promotion level calls of recursive type variable expressions
394  private static IList<UnionType> recursivePromotionLevelDetection = new List<UnionType>();
395 
396  public override object Exec(UnionType firstOperand, object arg) {
397  // * Checks recursion
398  if (recursivePromotionLevelDetection.Contains(firstOperand))
399  return 0;
400  recursivePromotionLevelDetection.Add(firstOperand);
401  // * Static Behaviour: Takes the addition of all the promotion level
402  // * Dynamic Behaviour: Takes the addition of all the promotion level
403  int promotionLevel = firstOperand.IsDynamic ? Int32.MaxValue : 0;
404  foreach (TypeExpression subType in firstOperand.TypeSet) {
405  int aux = (int)subType.AcceptOperation(this, arg);
406  if (firstOperand.IsDynamic && aux != -1) {
407  // * Dynamic
408  promotionLevel = Math.Min(promotionLevel, aux);
409  if (promotionLevel == 0)
410  break;
411  }
412  if (!firstOperand.IsDynamic) {
413  // * Static
414  if (aux == -1) {
415  promotionLevel = -1;
416  break;
417  }
418  promotionLevel += aux;
419  }
420  }
421  if (firstOperand.IsDynamic && promotionLevel == Int32.MaxValue)
422  // * No promotion at all
423  promotionLevel = -1;
424  // * Clears the loop detection for futures method calls
425  recursivePromotionLevelDetection.Clear();
426  return promotionLevel;
427  }
428  #endregion
429 
430  #region Void-->#
431  public override object Exec(VoidType firstOperand, object arg) {
432  return this.secondOperand is VoidType ? 0 : -1;
433  }
434  #endregion
435 
436  #region ReportError()
437  public override object ReportError(TypeExpression firstOperand) {
438  System.Diagnostics.Debug.Assert(false, "Error en código op1 = " + firstOperand + "OP2=" + this.secondOperand);
439  return null;
440  }
441  #endregion
442  }
443 }
Its operation AcceptOperation() returns an integer value that indicates a promotion level between two...
override object Exec(TypeExpression type, object arg)
override object Exec(NullType firstOperand, object arg)
Representa a union type.
Definition: UnionType.cs:36
TypeExpression Substitution
A equivalence class could be bounded to a unique no variable type
Representa an array type.
Definition: ArrayType.cs:35
override object ReportError(TypeExpression firstOperand)
override object Exec(TypeVariable firstOperand, object arg)
Represent a string type.
Definition: StringType.cs:36
This class represent the entry wnen sending a message to an operation object derived from TypeExpress...
Represents a void type.
Definition: VoidType.cs:34
Represents a interface type.
Represent a character type.
Definition: CharType.cs:38
Abstract class that represents all different types.
override object Exec(UnionType firstOperand, object arg)
Represents a generic type expression
Definition: TypeVariable.cs:36
Represents a proxy of a class type. It implements the unfold operatations of theoretical type systes...
override object Exec(DoubleType firstOperand, object arg)
No location information is provided within this class, because the exec methods invoked by the proper...
Represent a integer type.
Definition: IntType.cs:37
Type TypeInfo
Returns the real introspective type
Definition: BCLClassType.cs:36
Represents a double type.
Definition: DoubleType.cs:36
override object Exec(VoidType firstOperand, object arg)
override object Exec(PropertyType firstOperand, object arg)
Represent a null type.
Definition: NullType.cs:36
TypeExpression FieldTypeExpression
Gets the field type.
Definition: FieldType.cs:58
List< InterfaceType > InterfaceList
Gets the list of interfaces
Definition: UserType.cs:157
virtual bool IsDynamic
Indicates if the type has been set as dynamic
override object Exec(StringType firstOperand, object arg)
Representa a property type.
Definition: PropertyType.cs:34
override object AcceptOperation(TypeSystemOperation op, object arg)
ClassType BaseClass
Gets the base type (null if not exists).
Definition: ClassType.cs:56
override object Exec(InterfaceType firstOperand, object arg)
override object Exec(FieldType firstOperand, object arg)
TypeExpression Substitution
Gets the substitution; null if it does not exist
Represent a bool type.
Definition: BoolType.cs:36
TypeExpression PropertyTypeExpression
Gets the property type.
Definition: PropertyType.cs:64
Represents a class type.
Definition: ClassType.cs:35
override object AcceptOperation(TypeSystemOperation op, object arg)
Definition: ClassType.cs:177
Representa a field type.
Definition: FieldType.cs:37
override object Exec(ClassTypeProxy firstOperand, object arg)
EquivalenceClass EquivalenceClass
The equivalence class of the type variable (see the dragon book)
Definition: TypeVariable.cs:88
override object Exec(ClassType firstOperand, object arg)
override object Exec(IntType firstOperand, object arg)
virtual object AcceptOperation(TypeSystemOperation op, object arg)
override object Exec(CharType firstOperand, object arg)