The StaDyn Programming Language
Source code documentation of StaDyn, a hybrid static and dynamic typing language.
AssignmentOperation.cs
Go to the documentation of this file.
1 using System;
2 using TypeSystem.Operations;
3 using TypeSystem;
4 using ErrorManagement;
5 using AST;
6 using Tools;
7 using System.Collections.Generic;
8 using TypeSystem.Constraints;
9 namespace TypeSystem.Operations {
38  protected Location location;
39 
40  #region Constructor
41  public AssignmentOperation(TypeExpression rightOperand, AssignmentOperator op, MethodType methodAnalyzed, SortOfUnification unification, TypeExpression actualImplicitObject, Location location) {
51  this.rightOperand = rightOperand;
52  this.op = op;
53  this.methodAnalyzed = methodAnalyzed;
54  this.unification = unification;
55  this.actualImplicitObject = actualImplicitObject;
56  this.location = location;
57  }
58  #endregion
59 
60  #region Array = ...
61  public override object Exec(ArrayType leftOperand, object arg) {
68 
69  if (this.op == AssignmentOperator.Assign && (bool)this.rightOperand.AcceptOperation(new EquivalentOperation(leftOperand), arg)) {
70  if (!leftOperand.HasTypeVariables())
71  return leftOperand;
72  // * Unification, meter una ternaria aqúi? igual muy queda la linea muy grande
73  if (leftOperand.Unify(this.rightOperand, this.unification, new List<Pair<TypeExpression, TypeExpression>>()))
74  return leftOperand;
75  else
76  return ReportError(leftOperand);
77  }
78  return ReportError(leftOperand);
79  }
80 
81  #endregion
82 
83  #region Bool = ...
84  public override object Exec(BoolType leftOperand, object arg) {
91  return this.op == AssignmentOperator.Assign // * if the operator is not assing raise and error, in other case, check if the second operand can be promotable to a BoolType
92  ? rightOperand.AcceptOperation(PromotionOperation.Create(leftOperand, this.op, this.methodAnalyzed, this.location), arg)
93  : ReportError(leftOperand);
94  }
95 
96  #endregion
97 
98 
99  #region Class = ...
100  public override object Exec(ClassType leftOperand, object arg) { // the unique allowable operator
107  if (this.op == AssignmentOperator.Assign) {
108  if ( this.rightOperand.AcceptOperation(PromotionOperation.Create(leftOperand, this.op, this.methodAnalyzed, this.location), arg) == null )
109  return null;
110  if (!leftOperand.HasTypeVariables())
111  return leftOperand;
112  // * If the left expression of the assignment has type variables,
113  // we must return the concrete type (not the abstract one)
114  // * Then whe unify the concrete types
115  FieldType fieldType = TypeExpression.As<FieldType>(this.rightOperand);
116  if (fieldType != null)
117  this.rightOperand = fieldType.FieldTypeExpression;
118  if (leftOperand.Unify(this.rightOperand, this.unification, new List<Pair<TypeExpression, TypeExpression>>())) {
119  leftOperand.ValidTypeExpression = false;
120  return leftOperand;
121  }
122  }
123  ErrorManager.Instance.NotifyError(new OperationNotAllowedError(this.op.ToString(), leftOperand.FullName, rightOperand.FullName, this.location));
124  return null;
125 
126  }
127 
128  #endregion
129 
130  #region ClassTypeProxy = ...
131  public override object Exec(ClassTypeProxy leftOperand, object arg) {
138  return leftOperand.RealType.AcceptOperation(this, arg);
139  }
140 
141  #endregion
142 
143  #region Char = ...
144  public override object Exec(CharType leftOperand, object arg) {
151 
152  return rightOperand.AcceptOperation(PromotionOperation.Create(leftOperand, this.op, this.methodAnalyzed, this.location), arg);
153  }
154 
155  #endregion
156  #region Double = ...
163 
164  public override object Exec(DoubleType leftOperand, object arg) {
165 
166  return rightOperand.AcceptOperation(PromotionOperation.Create(leftOperand, this.op, this.methodAnalyzed, this.location), arg);
167  }
168 
169  #endregion
170 
171  #region FieldType = ...
172  public override object Exec(FieldType leftOperand, object arg) {
180 
181  // * We check if a constraint must be generated. Is it an assignment of the implicit object's field?
182  bool found = false;
183  // * In case it has free variables and the reference used is this, we add a constraint to the method
184  if (leftOperand.HasTypeVariables() && this.methodAnalyzed != null &&
185  ClassType.IsConcreteType(this.actualImplicitObject) == null)
186  {
187  // * They should be the same exact (sub)classes. This represent the same instance, not another instance of the same class.
188  ClassType methodSuperClass = (ClassType) this.methodAnalyzed.MemberInfo.Class;
189  while (!(found = (leftOperand.MemberInfo.Class == methodSuperClass)) && methodSuperClass != null)
190  methodSuperClass = methodSuperClass.BaseClass;
191  if (found)
192  {
193  // * An assignment constraint is added, postponing the type inference
194  // * If an actual implicit object is used, we take its field's type
195  FieldType fieldType = leftOperand;
196  ClassType thisType = TypeExpression.As<ClassType>(this.actualImplicitObject);
197  if (thisType == null)
198  {
199  FieldType field = TypeExpression.As<FieldType>(this.actualImplicitObject);
200  if (field != null)
201  thisType = TypeExpression.As<ClassType>(field.FieldTypeExpression);
202  }
203 
204  if (thisType != null)
205  {
206  while (thisType != null && !thisType.Fields.ContainsKey(leftOperand.MemberInfo.MemberIdentifier))
207  {
208  thisType = thisType.BaseClass;
209  }
210  if (thisType != null)
211  fieldType = (FieldType) thisType.Fields[leftOperand.MemberInfo.MemberIdentifier].Type;
212  }
213 
214  this.methodAnalyzed.AddConstraint(new FieldTypeAssignmentConstraint(fieldType, this.rightOperand,
215  this.unification));
216  this.methodAnalyzed.ValidTypeExpression = false;
217  if (leftOperand.FieldTypeExpression is TypeVariable && rightOperand is ArrayType)
218  {
219  TypeVariable typeVariable = (TypeVariable)leftOperand.FieldTypeExpression;
220  typeVariable.AcceptOperation(new AssignmentOperation(rightOperand, this.op, null, SortOfUnification.Override, null, this.location), arg);
221  }
222  else if (leftOperand.FieldTypeExpression is TypeVariable && rightOperand is TypeVariable && ((TypeVariable)rightOperand).Substitution == null && ((TypeVariable)rightOperand).IsDynamic)
223  {
224  TypeVariable typeVariable = (TypeVariable)leftOperand.FieldTypeExpression;
225  typeVariable.AcceptOperation(new AssignmentOperation(rightOperand, this.op, null, SortOfUnification.Override, null, this.location), arg);
226  }
227  return leftOperand.FieldTypeExpression;
228  }
229  if (leftOperand.FieldTypeExpression is TypeVariable)
230  {
231  TypeVariable typeVariable = (TypeVariable) leftOperand.FieldTypeExpression;
232  if (typeVariable.Substitution != null)
233  {
234  return
235  leftOperand.FieldTypeExpression.AcceptOperation(
236  new AssignmentOperation(this.rightOperand, this.op, null,
237  SortOfUnification.Incremental, this.actualImplicitObject,
238  this.location), arg);
239  }
240  }
241  }
242 
243  if (leftOperand.FieldTypeExpression != null)
244  return
245  leftOperand.FieldTypeExpression.AcceptOperation(
246  new AssignmentOperation(this.rightOperand, this.op, null, this.unification,
247  this.actualImplicitObject, this.location), arg);
248 
249  return null;
250  }
251 
252  #endregion
253 
254  #region InterfaceType = ...
255  public override object Exec(InterfaceType leftOperand, object arg) {
264  if (this.op == AssignmentOperator.Assign)
265  return rightOperand.AcceptOperation(PromotionOperation.Create(leftOperand, this.op, this.methodAnalyzed, this.location), arg);
266 
267  return ReportError(leftOperand);
268  }
269  #endregion
270 
279  public override object Exec(IntType leftOperand, object arg) {
280  return rightOperand.AcceptOperation(PromotionOperation.Create(leftOperand, this.op, this.methodAnalyzed, this.location), arg);
281  }
282 
283 
284  #region NullType = ...
285  public override object Exec(NullType leftOperand, object arg) {
291  return op == AssignmentOperator.Assign ? this.rightOperand : ReportError(leftOperand);
292  }
293  #endregion
294 
295 
296  #region PropertyType = ...
297  public override object Exec(PropertyType leftOperand, object arg) {
305  if (!leftOperand.MemberInfo.hasModifier(Modifier.CanWrite)) {
306  ErrorManager.Instance.NotifyError(new PropertyWriteError(leftOperand.MemberInfo.MemberIdentifier, this.location));
307  return null;
308  }
309  if (leftOperand.PropertyTypeExpression != null)
310  return leftOperand.PropertyTypeExpression.AcceptOperation(new AssignmentOperation(this.rightOperand, this.op, null, this.unification, this.actualImplicitObject, this.location), arg);
311 
312  return null;
313  }
314 
315  #endregion
316 
317 
318  #region StringType = ...
319  public override object Exec(StringType leftOperand, object arg) {
325  if (op == AssignmentOperator.Assign || op == AssignmentOperator.PlusAssign)
326  return rightOperand.AcceptOperation(PromotionOperation.Create(leftOperand, this.op, this.methodAnalyzed, this.location), arg);
327  // * se podría aquí hacer un base.ReportError()?;
328  ErrorManager.Instance.NotifyError(new OperationNotAllowedError(leftOperand.FullName, rightOperand.FullName, this.location));
329  return null;
330  }
331 
332  #endregion
333 
334 
335  #region TypeExpression = ...
336 
343  public override object Exec(TypeExpression leftOperand, object arg) {
344  return ReportError(leftOperand);
345  }
346 
347 
348  #endregion
349 
350  #region TypeVariable = ...
351  public override object Exec(TypeVariable leftOperand, object arg) {
357  // * Bounded variable?
358  if (leftOperand.Substitution != null && this.unification == SortOfUnification.Equivalent)
359  // * Check promotion to its substitution
360  return rightOperand.AcceptOperation(PromotionOperation.Create(leftOperand, this.op, this.methodAnalyzed, this.location), arg);
361  // * If the variable its not bounded, we add the parameter to the equivalence list
362  if (leftOperand.addToMyEquivalenceClass(rightOperand, this.unification, new List<Pair<TypeExpression, TypeExpression>>()))
363  return leftOperand;
364  // * If it has not been possible, error
365  ErrorManager.Instance.NotifyError(new OperationNotAllowedError(this.op.ToString(), leftOperand.FullName, rightOperand.FullName, this.location));
366  return null;
367  }
368 
369 
370  #endregion
371 
372  #region UnionType = ...
373  public override object Exec(UnionType leftOperand, object arg) {
381  // * If the unification is incremental, we must add it to the union typeset
382  if (this.unification == SortOfUnification.Incremental) {
383  leftOperand.TypeSet.Add(rightOperand);
384  return leftOperand;
385  }
386  foreach (TypeExpression type in leftOperand.TypeSet)
387  if ((int)rightOperand.AcceptOperation(new PromotionLevelOperation(type), arg) == -1)
388  return ReportError(leftOperand);
389 
390  return leftOperand;
391  }
392 
393  public override object ReportError(TypeExpression tE) {
394  ErrorManager.Instance.NotifyError(new AssignmentError(rightOperand.FullName, tE.FullName, this.location));
395  return null; ;
396  }
397  #endregion
398  }
399 
400 }
Location location
The location (file, line, column) of text being analyzed.
Its operation AcceptOperation() returns an integer value that indicates a promotion level between two...
Dictionary< string, AccessModifier > Fields
Gets the field list
Definition: UserType.cs:82
override string FullName
The full name in type variables is calculated just in time
Representa a union type.
Definition: UnionType.cs:36
Represents a error produced when tries to make an operation not allowed for the specified type...
Representa an array type.
Definition: ArrayType.cs:35
Represent a string type.
Definition: StringType.cs:36
This class encapsulates a location in a specific file. Implements an Inmutable pattern. So it can be used in any context, that is his internal fields never change.
Definition: Location.cs:24
This class represent the entry wnen sending a message to an operation object derived from TypeExpress...
TypeExpression rightOperand
The expression to assignate to the first operrand
override object ReportError(TypeExpression tE)
Represents a interface type.
Represent a character type.
Definition: CharType.cs:38
string MemberIdentifier
Gets the attribute name
bool hasModifier(Modifier mod)
To know if a modifier is supported
override bool HasTypeVariables()
To know if the type expression has some type variables and requieres unification The default implemen...
Definition: UserType.cs:232
Abstract class that represents all different types.
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...
static PromotionOperation Create(TypeExpression type, MethodType methodAnalyzed, Location location)
virtual string FullName
Gets the full name of the type Note: WriteType expression is the longest recursive representation of ...
No location information is provided within this class, because the exec methods invoked by the proper...
AccessModifier MemberInfo
Gets or sets the attribute information of method type
Definition: FieldType.cs:65
Represent a integer type.
Definition: IntType.cs:37
Represents a error produced when an property without write permisses is assigned a value...
SortOfUnification unification
Kind of unification to use: Equivalent, Incremental and Override.
Represents a double type.
Definition: DoubleType.cs:36
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
Represent a null type.
Definition: NullType.cs:36
override object Exec(TypeExpression leftOperand, object arg)
This method never would be called. Is point of double dispatcher. But the dispatch is done with equal...
Represents a error produced when the attribute identifier is not defined.
TypeExpression FieldTypeExpression
Gets the field type.
Definition: FieldType.cs:58
virtual bool IsDynamic
Indicates if the type has been set as dynamic
Implements Double dispatcher Pattern. The class encapsulates encapsulates all it&#39;s needed to perform ...
It represents constraints of the form: alpha := beta, being alpha a field type
Modifier
Indicates differents modifiers to use in class (only public, internal or static), fields or methods...
Representa a property type.
Definition: PropertyType.cs:34
UserType Class
Gets or sets the class type reference
Representa a method type.
Definition: MethodType.cs:37
override object Exec(DoubleType leftOperand, object arg)
Performs an assigment operation between a DoubleType type and the typeExpression stored in this...
override object AcceptOperation(TypeSystemOperation op, object arg)
TypeExpression actualImplicitObject
Only suitable when the assignment is executed as a constraint of a method call. In that case...
IList< TypeExpression > TypeSet
Gets the list of type expressions
Definition: UnionType.cs:57
TypeExpression Substitution
Gets the substitution; null if it does not exist
Represent a bool type.
Definition: BoolType.cs:36
AssignmentOperator op
The kind of assignment to perform. That is, =, +=, -=,... etc
AccessModifier MemberInfo
Gets or sets the attribute information of method type
Definition: PropertyType.cs:71
TypeExpression PropertyTypeExpression
Gets the property type.
Definition: PropertyType.cs:64
MethodType methodAnalyzed
The actual method being analysed.
Represents a class type.
Definition: ClassType.cs:35
Representa a field type.
Definition: FieldType.cs:37
override bool HasTypeVariables()
To know if the type expression has some type variables and requieres unification The default implemen...
Definition: ArrayType.cs:318
override bool Unify(TypeExpression te, SortOfUnification unification, IList< Pair< TypeExpression, TypeExpression >> previouslyUnified)
Returns a value thdat indicates a promotion level.
Definition: ClassType.cs:435
AssignmentOperator
Assignment binary operators
override object Exec(IntType leftOperand, object arg)
Performs an assigment operation between a IntType type and the typeExpression stored in this...
override bool HasTypeVariables()
To know if the type expression has some type variables and requieres unification The default implemen...
Definition: FieldType.cs:402