The StaDyn Programming Language
Source code documentation of StaDyn, a hybrid static and dynamic typing language.
ArrayType.cs
Go to the documentation of this file.
1 // -------------------------------------------------------------------------- //
3 // Project rROTOR //
4 // -------------------------------------------------------------------------- //
5 // File: ArrayType.cs //
6 // Authors: Cristina Gonzalez Muņoz - cristi.gm@gmail.com //
7 // Francisco Ortin - francisco.ortin@gmail.com //
8 // Description: //
9 // Represents an array type. //
10 // Inheritance: TypeExpression. //
11 // Implements Composite pattern [Composite]. //
12 // -------------------------------------------------------------------------- //
13 // Create date: 27-01-2007 //
14 // Modification date: 05-06-2007 //
16 
17 using System;
18 using System.Collections.Generic;
19 using System.Text;
20 using System.Text.RegularExpressions;
21 
22 using AST;
23 using ErrorManagement;
24 using Tools;
25 using TypeSystem.Operations;
26 
27 namespace TypeSystem {
35  public class ArrayType : TypeExpression {
36  #region Fields
37 
41  private TypeExpression arrayType;
42 
46  private BCLClassType BCLType;
47 
48  #endregion
49 
50  #region Properties
51 
56  get { return this.arrayType; }
57  }
58 
59 
63  public override bool IsDynamic {
64  set {
65  // * If an array is dynamic, so it is its element
66  this.isDynamic = value;
67  if (this.arrayType != null)
68  this.arrayType.IsDynamic = value;
69  }
70  }
71 
72  #endregion
73 
74  #region Constructor
75 
79  public ArrayType(TypeExpression type) {
80  this.arrayType = type;
81  this.fullName = type.FullName + "[]";
82  string introspectiveName = type.GetType().FullName + "[]";
83  this.BCLType = new BCLClassType(this.fullName, Type.GetType(introspectiveName));
84 
85  }
86 
87  #endregion
88 
89  #region Dispatcher
90  public override object AcceptOperation(TypeSystemOperation op, object arg) { return op.Exec(this, arg); }
91  #endregion
92 
93  #region BuildTypeExpressionString()
94  public override string BuildTypeExpressionString(int depthLevel) {
95  if (this.ValidTypeExpression) return this.typeExpression;
96  if (depthLevel <= 0) return this.FullName;
97 
98  this.typeExpression = this.typeExpression = String.Format("Array({0})", this.arrayType.BuildTypeExpressionString(depthLevel - 1));
99  this.ValidTypeExpression = true;
100  return typeExpression;
101  }
102  #endregion
103 
104  #region BuildFullName()
105  public override void BuildFullName() {
109  this.fullName = this.arrayType.fullName + "[]";
110  }
111  #endregion
112 
113  // WriteType inference
114 
115  #region Assignment() ANULAda
116  //public override TypeExpression Assignment(TypeExpression operand, AssignmentOperator op, MethodType methodAnalyzed, SortOfUnification unification,
128  // TypeExpression actualImplicitObject, Location location) {
129  // if ((op == AssignmentOperator.Assign) && (operand.Equivalent(this))) {
130  // if (!this.HasTypeVariables())
131  // return this;
132  // // * Unification
133  // if (this.Unify(operand, unification, new List<Pair<TypeExpression, TypeExpression>>()))
134  // return this;
135  // else {
136  // ErrorManager.Instance.NotifyError(new AssignmentError(operand.FullName, this.FullName, location));
137  // return null;
138  // }
139  // }
140  // ErrorManager.Instance.NotifyError(new AssignmentError(operand.FullName, this.FullName, location));
141  // return null;
142  //}
143 
144  #endregion
145 
146  #region Bracket() ANULADA
147 
158  //public override TypeExpression Bracket(TypeExpression index, MethodType methodAnalyzed, bool showErrorMessage, Location loc) {
159  // if (index.Promotion(IntType.Instance, ArrayOperator.Indexer, methodAnalyzed, loc) != null)
160  // return this.arrayType;
161  // return null;
162  //}
163 
164  #endregion
165 
166 
167  #region AsClassType()
168  public override ClassType AsClassType() {
174  return this.BCLType;
175  }
176  #endregion
177 
178  #region Equivalent() ANULADA
179  //public override bool Equivalent(TypeExpression type) {
185  // // * Is it an array?
186  // ArrayType arrayType = TypeExpression.As<ArrayType>(type);
187  // if (arrayType != null)
188  // return this.arrayType.Equivalent(arrayType.arrayType);
189  // // * It can be a System.Array
190  // BCLClassType bclClassType = TypeExpression.As<BCLClassType>(type);
191  // if (bclClassType.TypeInfo.IsArray) {
192  // TypeExpression elementType = TypeTable.Instance.GetType(bclClassType.TypeInfo.GetElementType().FullName, new Location("", 0, 0));
193  // return elementType.Equivalent(this);
194  // }
195  // return false;
196  //}
197  #endregion
198 
199 
200 
201  #region Relational() ANULADA
202  //public override TypeExpression Relational(TypeExpression operand, RelationalOperator op, MethodType methodAnalyzed, bool showErrorMessage, Location loc) {
214  // // * Operators >= > <= < are note allowed
215  // if ((op == RelationalOperator.GreaterThan || op == RelationalOperator.GreaterThanOrEqual || op == RelationalOperator.LessThan || op == RelationalOperator.LessThanOrEqual)
216  // && showErrorMessage) {
217  // ErrorManager.Instance.NotifyError(new OperationNotAllowedError(op.ToString(), this.fullName, operand.fullName, loc));
218  // return null;
219  // }
220  // if (!(operand is NullType))
221  // ErrorManager.Instance.NotifyError(new OperationNotAllowedError(op.ToString(), this.fullName, operand.fullName, loc));
222  // return null;
223  //}
224 
225  #endregion
226 
227  // WriteType promotion
228 
229  #region PromotionLevel() ANULADA
230  //public override int PromotionLevel(TypeExpression type) {
236  // // * Array and bounded type variable
237  // ArrayType array = TypeExpression.As<ArrayType>(type);
238  // if (array != null)
239  // return this.arrayType.Equals(array.arrayType) ? 0 : -1;
240  // // * A free variable is a complete promotion
241  // TypeVariable typeVariable = type as TypeVariable;
242  // if (typeVariable != null && typeVariable.Substitution == null)
243  // return 0;
244  // // * Union type and bounded type variable
245  // UnionType unionType = TypeExpression.As<UnionType>(type);
246  // if (unionType != null)
247  // return unionType.SuperType(this);
248  // // * Field type and bounded type variable
249  // FieldType fieldType = TypeExpression.As<FieldType>(type);
250  // if (fieldType != null)
251  // return this.PromotionLevel(fieldType.FieldTypeExpression);
252  // // * Use the BCL object oriented approach
253  // return this.BCLType.PromotionLevel(type);
254  //}
255  #endregion
256 
257  #region Equals&GetHashCode()
258  public override bool Equals(object obj) {
259  ArrayType parameter = obj as ArrayType;
260  if (parameter == null)
261  return false;
262  if (parameter == this)
263  return true;
264  return this.arrayType.Equals(parameter.arrayType);
265  }
266  public override int GetHashCode() {
267  return this.FullName.GetHashCode();
268  }
269  #endregion
270 
271  // WriteType Unification
272 
273  #region Unify
274  public override bool Unify(TypeExpression te, SortOfUnification unification, IList<Pair<TypeExpression, TypeExpression>> previouslyUnified) {
282  // * Infinite recursion detection
283  Pair<TypeExpression, TypeExpression> pair = new Pair<TypeExpression, TypeExpression>(this, te);
284  if (previouslyUnified.Contains(pair))
285  return true;
286  previouslyUnified.Add(pair);
287 
288  bool success = false;
289  ArrayType at = te as ArrayType;
290  if (at != null)
291  success = this.arrayType.Unify(at.arrayType, unification, previouslyUnified);
292  else if (te is TypeVariable) {
293  TypeVariable typeVariable = (TypeVariable)te;
294  if (unification != SortOfUnification.Incremental)
295  // * Incremental is commutative
296  success = typeVariable.Unify(this, unification, previouslyUnified);
297  else { // * Array(var) should unify to Var=Array(int)
298  if (typeVariable.Substitution != null)
299  success = this.Unify(typeVariable.Substitution, unification, previouslyUnified);
300  else success = false;
301  }
302  }
303  else if (te is UnionType)
304  success = te.Unify(this, unification, previouslyUnified);
305  // * Clears the type expression cache
306  this.ValidTypeExpression = false;
307  te.ValidTypeExpression = false;
308  return success;
309  }
310  #endregion
311 
312  #region HasTypeVariables()
313  public override bool HasTypeVariables() {
319  if (this.validHasTypeVariables)
320  return this.hasTypeVariablesCache;
321  bool toReturn = this.arrayType.HasTypeVariables();
322  this.validHasTypeVariables = true;
323  return this.hasTypeVariablesCache = toReturn;
324  }
325  #endregion
326 
327  #region CloneType()
328  public override TypeExpression CloneType(IDictionary<TypeVariable, TypeVariable> typeVariableMappings) {
337  if (!this.HasTypeVariables())
338  return this;
339  // * We clone the type of the elements
340  IList<EquivalenceClass> equivalenceClasses = new List<EquivalenceClass>();
341  ArrayType newArrayType = (ArrayType)this.CloneTypeVariables(typeVariableMappings, equivalenceClasses, new List<ClassType>());
342  // * For each equivalence class we create a new one,
343  // substituting the old type variables for the new ones
344  // * The substitution is not altered
345  // * Since equivalence classes and type variables have a bidirectional association,
346  // the new equivalence classes will make type variables update their new equivalence classes
347  foreach (EquivalenceClass equivalenceClass in equivalenceClasses)
348  equivalenceClass.UpdateEquivalenceClass(typeVariableMappings);
349  newArrayType.ValidTypeExpression = false;
350  // * The new class type is returned
351  return newArrayType;
352  }
353  #endregion
354 
355  #region CloneTypeVariables()
356  public override TypeExpression CloneTypeVariables(IDictionary<TypeVariable, TypeVariable> typeVariableMappings, IList<EquivalenceClass> equivalenceClasses, IList<ClassType> clonedClasses) {
367  if (!this.HasTypeVariables())
368  return this;
369  ArrayType newType = (ArrayType)this.MemberwiseClone();
370  newType.arrayType = newType.arrayType.CloneTypeVariables(typeVariableMappings, equivalenceClasses, clonedClasses);
371  newType.ValidTypeExpression = false;
372  return newType;
373  }
374  #endregion
375 
376 
377  #region UpdateEquivalenceClass()
378  public override void UpdateEquivalenceClass(IDictionary<TypeVariable, TypeVariable> typeVariableMappings, IList<TypeExpression> previouslyUpdated) {
385  // * Checks infinite loops
386  if (previouslyUpdated.Contains(this))
387  return;
388  previouslyUpdated.Add(this);
389 
390  // * Updates the equivalence class
391  if (!this.HasTypeVariables())
392  return;
393  this.arrayType.UpdateEquivalenceClass(typeVariableMappings, previouslyUpdated);
394  this.ValidTypeExpression = false;
395  }
396  #endregion
397 
398  #region ReplaceTypeVariables()
399  public override void ReplaceTypeVariables(IDictionary<TypeVariable, TypeVariable> typeVariableMappings) {
405  TypeVariable arrayTypeVariable = this.arrayType as TypeVariable;
406  if (arrayTypeVariable == null) {
407  if (this.arrayType.HasTypeVariables())
408  this.arrayType.ReplaceTypeVariables(typeVariableMappings);
409  return;
410  }
411  if (typeVariableMappings.ContainsKey(arrayTypeVariable))
412  this.arrayType = typeVariableMappings[arrayTypeVariable];
413  this.ValidTypeExpression = false;
414  }
415  #endregion
416 
417  // SSA
418 
419  #region Clone()
420  internal override TypeExpression Clone(IDictionary<int, TypeVariable> clonedTypeVariables, IList<EquivalenceClass> equivalenceClasses, MethodType methodAnalyzed) {
431  if (!this.HasTypeVariables())
432  return this;
433  ArrayType newType = (ArrayType)this.MemberwiseClone();
434  newType.arrayType = newType.arrayType.Clone(clonedTypeVariables, equivalenceClasses, methodAnalyzed);
435  newType.ValidTypeExpression = false;
436  return newType;
437  }
438  #endregion
439 
440  // Code Generation
441 
442  #region ILType()
443 
448  public override string ILType() {
449  if (this.ArrayTypeExpression is TypeVariable && ((TypeVariable)this.ArrayTypeExpression).Substitution != null && ((TypeVariable)this.ArrayTypeExpression).Substitution.IsValueType())
450  return "object[]";
451  else
452  return this.arrayType.ILType() + "[]";
453  }
454 
455  #endregion
456 
457  #region IsValueType()
458 
463  public override bool IsValueType()
464  {
465  return false;
466  }
467 
468  #endregion
469 
470  }
471 }
override bool IsValueType()
True if type expression is a ValueType. Otherwise, false.
Definition: ArrayType.cs:463
override string BuildTypeExpressionString(int depthLevel)
Returns the type expression The maximum depth of recursion to construct type expressions
Definition: ArrayType.cs:94
override object AcceptOperation(TypeSystemOperation op, object arg)
Definition: ArrayType.cs:90
Representa an array type.
Definition: ArrayType.cs:35
override string ILType()
Gets the string type to use in IL code.
Definition: ArrayType.cs:448
override void ReplaceTypeVariables(IDictionary< TypeVariable, TypeVariable > typeVariableMappings)
Replaces type variables substituting the old type variables for the new ones.
Definition: ArrayType.cs:404
bool validHasTypeVariables
To cache the result of the HasTypeVariables method
This class represent the entry wnen sending a message to an operation object derived from TypeExpress...
override void BuildFullName()
Creates/Updates the full name of the type expression
Definition: ArrayType.cs:108
override bool Equals(object obj)
Check if the type can make an relational operation.
Definition: ArrayType.cs:258
Abstract class that represents all different types.
Represents a generic type expression
Definition: TypeVariable.cs:36
virtual void ReplaceTypeVariables(IDictionary< TypeVariable, TypeVariable > typeVariableMappings)
Replaces type variables substituting the old type variables for the new ones.
virtual string FullName
Gets the full name of the type Note: WriteType expression is the longest recursive representation of ...
override int GetHashCode()
Definition: ArrayType.cs:266
abstract bool IsValueType()
True if type expression is a ValueType. Otherwise, false.
override bool Unify(TypeExpression te, SortOfUnification unification, IList< Pair< TypeExpression, TypeExpression >> previouslyUnified)
This method unifies two type expressions (this and te)
Definition: ArrayType.cs:281
override TypeExpression CloneTypeVariables(IDictionary< TypeVariable, TypeVariable > typeVariableMappings, IList< EquivalenceClass > equivalenceClasses, IList< ClassType > clonedClasses)
Method that clones each type variable of a type expression. Equivalence classes are not cloned (but i...
Definition: ArrayType.cs:366
TypeExpression ArrayTypeExpression
Gets the array type.
Definition: ArrayType.cs:55
string fullName
Represents the full name of the type Note: WriteType expression is the longest recursive representati...
virtual bool HasTypeVariables()
To know if the type expression has some type variables and requieres unification The default implemen...
string typeExpression
Represents the type by a debug string Note: WriteType expression is the longest recursive representat...
override bool IsDynamic
Indicates if the type has been set as dynamic
Definition: ArrayType.cs:63
override void UpdateEquivalenceClass(IDictionary< TypeVariable, TypeVariable > typeVariableMappings, IList< TypeExpression > previouslyUpdated)
Replaces the equivalence class of type variables substituting the old type variables for the new ones...
Definition: ArrayType.cs:384
TypeExpression Substitution
Gets the substitution; null if it does not exist
override TypeExpression CloneType(IDictionary< TypeVariable, TypeVariable > typeVariableMappings)
This method creates a new class type, creating new type variables for each field. It these type varia...
Definition: ArrayType.cs:336
override ClassType AsClassType()
Represent a type as a class. It is mainly used to obtain the BCL representation of types (string=Stri...
Definition: ArrayType.cs:173
override bool HasTypeVariables()
To know if the type expression has some type variables and requieres unification The default implemen...
Definition: ArrayType.cs:318
ArrayType(TypeExpression type)
Constructor of ArrayType
Definition: ArrayType.cs:79