2 using System.Collections.Generic;
3 using CodeGeneration.Operations;
4 using TypeSystem.Operations;
9 namespace CodeGeneration.NewOperations
27 this.codeGenerator = visitor.codeGenerator;
29 this.visitor = visitor;
32 this.node.FirstOperand.Accept(this.visitor, this.obj);
36 protected abstract UnionType GenerateAllUnionTypes();
41 ErrorManager.Instance.NotifyError(
new CodeGenerationError(
"No se ha definido la operación solicitada"));
48 this.Exec(typeExpression as UnionType, arg);
50 this.Exec(typeExpression as TypeVariable, arg);
52 this.Exec(((PropertyType)typeExpression).PropertyTypeExpression, arg);
55 FieldType fieldType = ((FieldType) typeExpression);
56 if (fieldType.
FieldTypeExpression is TypeVariable && ((TypeVariable)fieldType.FieldTypeExpression).Substitution != null && ((TypeVariable)fieldType.FieldTypeExpression).Substitution.
IsValueType())
58 UnionType
union = new UnionType();
59 union.AddType(((TypeVariable)((FieldType)typeExpression).FieldTypeExpression).Substitution);
60 this.Exec(
union, arg);
63 this.Exec(((FieldType) typeExpression).FieldTypeExpression, arg);
65 else if (IsValueType(typeExpression) || TypeExpression.Is<
StringType>(typeExpression))
66 GenerateRightOperand(typeExpression, this.node.SecondOperand.ILTypeExpression);
69 this.codeGenerator.ldnull(this.indent);
70 GenerateRightOperand(typeExpression, this.node.SecondOperand.ILTypeExpression);
74 GenerateRightOperand(typeExpression, this.node.SecondOperand.ILTypeExpression);
81 String finalLabel = this.codeGenerator.NewLabel;
82 String nextLabel =
"";
84 List<TypeExpression> typeSet =
new List<TypeExpression>();
85 for (
int i = 0; i < teLeft.TypeSet.Count; i++)
86 typeSet.AddRange(GetTypes(teLeft.
TypeSet[i]));
87 typeSet =
new List<TypeExpression>(
new HashSet<TypeExpression>(typeSet));
88 if (typeSet.Count == 0 && !(
this.node.SecondOperand.ExpressionType is
NullType))
90 typeSet =
new List<TypeExpression>(
new HashSet<TypeExpression>(GenerateAllUnionTypes().TypeSet));
92 if (typeSet.Count > 0)
94 for (
int i = 0; i < typeSet.Count; i++)
96 if (!String.IsNullOrEmpty(nextLabel))
97 this.codeGenerator.WriteLabel(indent, nextLabel);
98 if (i != typeSet.Count - 1)
100 nextLabel = this.codeGenerator.NewLabel;
101 this.codeGenerator.dup(indent);
102 this.codeGenerator.isinst(indent, typeSet[i]);
103 this.codeGenerator.brfalse(indent, nextLabel);
105 GenerateRightOperand(typeSet[i], this.node.SecondOperand.ExpressionType);
106 if (i != typeSet.Count - 1)
107 this.codeGenerator.br(indent, finalLabel);
109 this.codeGenerator.WriteLabel(indent, finalLabel);
122 return this.Exec(GenerateAllUnionTypes(), arg);
124 return this.Exec(teLeft.Substitution, arg);
130 this.GenerateRightOperand(teLeft, teRight as UnionType);
132 this.GenerateRightOperand(teLeft, teRight as TypeVariable);
134 GenerateRightOperand(teLeft, ((PropertyType)teRight).PropertyTypeExpression);
137 FieldType fieldType = ((FieldType)teRight);
138 if (fieldType.
FieldTypeExpression is TypeVariable && ((TypeVariable)fieldType.FieldTypeExpression).Substitution != null && ((TypeVariable)fieldType.FieldTypeExpression).Substitution.
IsValueType())
140 UnionType
union = new UnionType();
141 union.AddType(((TypeVariable)((FieldType)teRight).FieldTypeExpression).Substitution);
142 GenerateRightOperand(teLeft, union);
145 GenerateRightOperand(teLeft, ((FieldType) teRight).FieldTypeExpression);
149 if (IsInternallyAnObject(node.FirstOperand))
151 if (!(teLeft is
StringType) && IsValueType(teRight))
152 this.codeGenerator.UnboxAny(indent, teLeft);
156 if (!CheckUnBox(teLeft, teRight))
157 CheckBox(teLeft, teRight);
160 if (IsInternallyAnObject(node.SecondOperand))
162 if (!(teRight is
StringType) && IsValueType(teLeft))
163 this.codeGenerator.UnboxAny(indent, teRight);
167 if (!CheckUnBox(teRight, teLeft))
168 CheckBox(teRight, teLeft);
170 GenerateOperator(node, MajorType(teLeft, teRight));
174 this.codeGenerator.ldnull(this.indent);
175 GenerateOperator(node, MajorType(teLeft, teRight));
182 if (typeExpression is UnionType)
184 else if (typeExpression is NullType)
186 else if (typeExpression is TypeVariable)
188 if (((TypeVariable)typeExpression).Substitution == null)
190 if (IsValueType(((TypeVariable)typeExpression).Substitution))
196 else if (typeExpression is PropertyType)
197 return !IsValueType(((PropertyType)typeExpression).PropertyTypeExpression);
198 else if (typeExpression is FieldType && ((FieldType)typeExpression).FieldTypeExpression is TypeVariable)
200 else if (typeExpression is FieldType)
201 return !IsValueType(((FieldType)typeExpression).FieldTypeExpression);
202 else if (typeExpression is StringType)
209 List<TypeExpression> typeSet =
new List<TypeExpression>();
210 for (
int i = 0; i < teRight.TypeSet.Count; i++)
211 typeSet.AddRange(GetTypes(teRight.
TypeSet[i]));
212 typeSet =
new List<TypeExpression>(
new HashSet<TypeExpression>(typeSet));
213 String finalLabel = this.codeGenerator.NewLabel;
214 String nextLabel =
"";
215 if (typeSet.Count == 0)
216 typeSet.AddRange(GenerateAllUnionTypes().TypeSet);
217 for (
int i = 0; i < typeSet.Count; i++)
219 if (!String.IsNullOrEmpty(nextLabel))
220 this.codeGenerator.WriteLabel(indent, nextLabel);
221 if (i != typeSet.Count - 1)
224 nextLabel = this.codeGenerator.NewLabel;
225 this.codeGenerator.isinst(indent, typeSet[i]);
226 this.codeGenerator.brfalse(indent, nextLabel);
228 if ((node.FirstOperand.ExpressionType is UnionType || node.FirstOperand.ExpressionType is TypeVariable) && IsValueType(typeSet[i]) && IsInternallyAnObject(node.FirstOperand))
229 this.codeGenerator.UnboxAny(indent, teLeft);
230 else if (this.node.FirstOperand.ExpressionType is FieldType && ((FieldType)
this.node.FirstOperand.ExpressionType).MemberInfo.Modifiers.Contains(
Modifier.Static) && ((FieldType)this.node.FirstOperand.ExpressionType).FieldTypeExpression is TypeVariable)
231 this.codeGenerator.UnboxAny(indent, teLeft);
232 else if (this.node.FirstOperand.ExpressionType is FieldType && ((FieldType)
this.node.FirstOperand.ExpressionType).FieldTypeExpression is TypeVariable && node.SecondOperand.ExpressionType.IsValueType())
233 this.codeGenerator.UnboxAny(indent, teLeft);
234 else if (this.node.FirstOperand.ExpressionType is FieldType && ((FieldType)
this.node.FirstOperand.ExpressionType).FieldTypeExpression is TypeVariable && ((TypeVariable)((FieldType)
this.node.FirstOperand.ExpressionType).FieldTypeExpression).Substitution == null)
235 this.codeGenerator.UnboxAny(indent, teLeft);
236 else if (IsValueType(node.FirstOperand.ExpressionType) && typeSet[i] is StringType)
237 this.codeGenerator.Box(indent, teLeft);
239 if (!(typeSet[i] is StringType) && !(teLeft is StringType))
240 this.codeGenerator.UnboxAny(this.indent, typeSet[i]);
241 GenerateOperator(node, MajorType(teLeft, typeSet[i]));
242 if (i != typeSet.Count - 1)
243 this.codeGenerator.br(indent, finalLabel);
245 this.codeGenerator.WriteLabel(indent, finalLabel);
246 if (!String.IsNullOrEmpty(label_result))
247 this.codeGenerator.ldloc(
this.indent, label_result);
253 this.node.SecondOperand.Accept(this.visitor, this.obj);
259 List<TypeExpression> typeSet =
new List<TypeExpression>();
260 if(evaluated == null)
261 evaluated =
new List<TypeExpression>();
262 if (evaluated.Contains(typeExpression))
265 evaluated.Add(typeExpression);
266 if (IsValueType(typeExpression) || typeExpression is StringType)
267 typeSet.Add(typeExpression);
268 else if (typeExpression is TypeVariable)
270 if (((TypeVariable)typeExpression).Substitution != null)
271 typeSet.AddRange(GetTypes(((TypeVariable)typeExpression).Substitution,evaluated));
273 else if (typeExpression is UnionType)
275 UnionType
union = typeExpression as UnionType;
276 foreach (var expression
in union.TypeSet)
277 typeSet.AddRange(GetTypes(expression,evaluated));
279 else if (typeExpression is FieldType)
281 FieldType fieldType = typeExpression as FieldType;
284 else if (typeExpression is PropertyType)
286 PropertyType propertyType = typeExpression as PropertyType;
292 private void GenerateRightOperand(
TypeExpression teLeft, TypeVariable teRight)
295 this.GenerateRightOperand(teLeft, GenerateAllUnionTypes());
297 this.GenerateRightOperand(teLeft, teRight.Substitution);
304 if (IsValueType(op2) || op2 is TypeVariable || op2 is UnionType)
306 this.codeGenerator.UnboxAny(indent, op1);
315 if (IsValueType(op1))
317 if (op2 is StringType)
319 this.codeGenerator.Box(indent, op1);
336 if (exp is TypeVariable)
337 return IsValueType(((TypeVariable) exp).Substitution);
Encapsulates a binary expression of our programming language.
override object ReportError(TypeExpression te)
Abstract class encapsulate a programming language expression.
static TypeVariable NewTypeVariable
Gets a new identify to the variable type
virtual void LoadSecondOperand()
List< TypeExpression > GetTypes(TypeExpression typeExpression, List< TypeExpression > evaluated=null)
This class walks the AST to obtain the IL code.
This class represent the entry wnen sending a message to an operation object derived from TypeExpress...
bool IsValueType(TypeExpression exp)
override object Exec(TypeVariable teLeft, object arg)
Represent a character type.
Abstract class that represents all different types.
Represents a generic type expression
CGBinaryOperation(VisitorILCodeGeneration< T > visitor, object obj, int indent, BinaryExpression node)
bool CheckUnBox(TypeExpression op1, TypeExpression op2)
Represent a integer type.
Represents a error produced when a MethodType has class information and tries to assign other class i...
abstract bool IsValueType()
True if type expression is a ValueType. Otherwise, false.
Represents a double type.
TypeExpression FieldTypeExpression
Gets the field type.
bool CheckBox(TypeExpression op1, TypeExpression op2)
Modifier
Indicates differents modifiers to use in class (only public, internal or static), fields or methods...
virtual bool HasTypeVariables()
To know if the type expression has some type variables and requieres unification The default implemen...
override object Exec(UnionType teLeft, object arg)
Representa a property type.
virtual void GenerateRightOperand(TypeExpression teLeft, UnionType teRight)
override object Exec(TypeExpression typeExpression, object arg)
bool IsInternallyAnObject(Expression expression)
IList< TypeExpression > TypeSet
Gets the list of type expressions
TypeExpression Substitution
Gets the substitution; null if it does not exist
TypeExpression PropertyTypeExpression
Gets the property type.
virtual TypeExpression ILTypeExpression
Gets the type expression to use in code generation.
Represents a class or interface type.
VisitorILCodeGeneration< T > visitor