1 using TypeSystem.Operations;
6 using System.Collections.Generic;
7 using CodeGeneration.ExceptionManagement;
8 namespace CodeGeneration.Operations {
14 internal struct Info {
16 internal bool allTypeExpressions;
20 internal Info[] info =
new Info[2];
26 public int operandOrdinal = 0;
30 public bool isEnd =
false;
33 this.info[0].allTypeExpressions =
false;
34 this.info[0].typeExpression = t1;
35 this.info[0].box =
false;
36 this.info[0].unbox =
false;
37 this.info[1].allTypeExpressions =
false;
38 this.info[1].typeExpression = t2;
39 this.info[1].box =
false;
40 this.info[1].unbox =
false;
46 this.firstTime = c.firstTime;
47 this.operandOrdinal = c.operandOrdinal;
48 this.info =
new Info[c.size];
50 for (
int i = 0; i < c.size; i++ ) {
51 this.info[i].typeExpression = c.info[i].typeExpression;
52 this.info[i].allTypeExpressions = c.info[i].allTypeExpressions;
53 this.info[i].box = c.info[i].box;
54 this.info[i].unbox = c.info[i].unbox;
59 int operandOrdinal,
bool firstTime,
bool allTypeExpressions1,
60 bool allTypeExpressions2)
61 : this(typeExpression1, typeExpression2) {
62 this.operandOrdinal = operandOrdinal;
64 this.info[0].allTypeExpressions = allTypeExpressions1;
65 this.info[1].allTypeExpressions = allTypeExpressions2;
66 this.info[0].box =
false;
67 this.info[0].unbox =
false;
68 this.info[1].box =
false;
69 this.info[1].unbox =
false;
99 protected string endOperationLabel;
101 protected string errorLabel;
107 protected T codeGenerator;
111 protected int indent;
115 protected object obj;
116 private string finalizeOperationLabel;
125 this.codeGenerator = visitor.codeGenerator;
126 this.indent = indent;
127 this.visitor = visitor;
130 this.errorLabel = string.Format(
"{0}_ERROR_OPERATION", this.codeGenerator.NewLabel);
131 this.endOperationLabel = string.Format(
"{0}_END_OPERATION", this.codeGenerator.NewLabel);
132 this.finalizeOperationLabel = string.Format(
"{0}_FINALIZE_OPERATION", this.codeGenerator.NewLabel);
133 this.node.FirstOperand.Accept(this.visitor, this.obj);
137 public virtual CGBinaryOperationsInfo GetFirstInfo(
TypeExpression t1,
object arg) {
138 CGBinaryOperationsInfo ret;
140 ret =
new CGBinaryOperationsInfo(t1, node.SecondOperand.ILTypeExpression);
142 ret.firstTime =
true;
144 ret = ( (CGBinaryOperationsInfo)arg ).Clone();
150 public override object Exec(
TypeVariable t,
object arg) {
153 CGBinaryOperationsInfo info = GetFirstInfo(t, arg);
156 te = GenerateAll(info, this.node);
157 info.info[info.operandOrdinal].allTypeExpressions =
true;
162 info.info[info.operandOrdinal].typeExpression = te;
163 info.info[info.operandOrdinal].unbox =
true;
164 return info.info[0].typeExpression.AcceptOperation(
this, info);
169 CGBinaryOperationsInfo cga = GetFirstInfo(t1, arg);
174 cga.operandOrdinal = 1;
175 node.SecondOperand.Accept(this.visitor, this.obj);
178 cga.operandOrdinal = 1;
184 GenerateOperator(cga, result, node);
185 MakeBoxIfNeeded(result, node);
186 this.codeGenerator.br(this.indent, this.endOperationLabel);
196 public override object Exec(
UnionType ut,
object arg) {
198 CGBinaryOperationsInfo ai = GetFirstInfo(ut, arg);
202 utn = GenerateAll(ai, this.node);
203 ai.info[0].allTypeExpressions =
true;
207 for (
int i = 0; i < utn.TypeSet.Count; i++ ) {
209 CGBinaryOperationsInfo cgi =
new CGBinaryOperationsInfo(ai);
210 cgi.info[cgi.operandOrdinal].typeExpression = ti;
213 ti.AcceptOperation(
this, cgi);
215 cgi.firstTime =
false;
217 ti.AcceptOperation(
this, cgi);
221 cgi.info[0].unbox =
true;
222 cgi.info[0].box =
false;
223 next = string.Format(
"{0}_1Op_not_a_{1}", this.codeGenerator.NewLabel, ti.ILType());
224 this.codeGenerator.Comment(this.indent, string.Format(
"1Op_case: [{0}]", ti.ILType()));
225 this.codeGenerator.dup(this.indent);
226 this.codeGenerator.isinst(this.indent, ti);
227 this.codeGenerator.brfalse(this.indent, i == utn.Count - 1 ? this.errorLabel : next);
228 ti.AcceptOperation(
this, cgi);
229 this.codeGenerator.WriteLabel(this.indent, next);
238 protected virtual void EndOperation() {
239 this.codeGenerator.br(this.indent, this.endOperationLabel);
240 this.codeGenerator.WriteLabel(this.indent, this.errorLabel);
243 this.codeGenerator.WriteLabel(this.indent, this.endOperationLabel);
246 protected virtual void ExecUnionSecondOperand(
TypeExpression t1,
UnionType unionType, CGBinaryOperationsInfo cg) {
247 CGBinaryOperationsInfo cga = cg.Clone();
251 utn = GenerateAll(cga, this.node);
252 cga.info[1].allTypeExpressions =
true;
256 for (
int i = 0; i < utn.TypeSet.Count; i++ ) {
258 CGBinaryOperationsInfo cgi = cga.Clone();
259 cgi.info[cgi.operandOrdinal].typeExpression = ti;
260 cgi.info[0].typeExpression = t1;
261 next = string.Format(
"{0}_2Op_not_a_{1}", this.codeGenerator.NewLabel, ti.ILType());
262 this.codeGenerator.Comment(this.indent, string.Format(
"2Op_case: [{0}]", ti.ILType()));
264 ti.AcceptOperation(
this, cgi);
266 cgi.firstTime =
false;
268 this.codeGenerator.pop(this.indent);
270 ti.AcceptOperation(
this, cgi);
275 cgi.info[1].unbox =
true;
276 cgi.info[1].box =
false;
277 this.codeGenerator.dup(this.indent);
278 this.codeGenerator.isinst(this.indent, ti);
279 this.codeGenerator.brfalse(this.indent, i == utn.Count - 1 ? this.errorLabel : next);
280 this.codeGenerator.pop(this.indent);
281 t1.AcceptOperation(
this, cgi);
283 this.codeGenerator.WriteLabel(this.indent, next);
295 TypeExpression majorType = MajorType(cga.info[0].typeExpression, cga.info[1].typeExpression);
296 if (cga.info[0].unbox)
297 MakeUnboxIfNeeded(cga.info[0].typeExpression);
298 CGConversion(cga.info[0], majorType);
301 this.node.SecondOperand.Accept(this.visitor, this.obj);
302 if ( cga.info[1].unbox )
303 MakeUnboxIfNeeded(cga.info[1].typeExpression);
305 CGConversion(cga.info[1], majorType);
310 virtual protected void CGConversion(CGBinaryOperationsInfo.Info info,
TypeExpression majorType) {
311 info.typeExpression.AcceptOperation(
new CGConvertToOperation<ILCodeGenerator>(majorType, this.codeGenerator, this.indent), null);
315 return (
TypeExpression)typeExpression1.AcceptOperation(
new MajorTypeOperation(typeExpression2), null);
320 this.codeGenerator.BoxIfNeeded(this.indent, t);
326 this.codeGenerator.UnboxAny(
this.indent, t);
329 ErrorManager.Instance.NotifyError(
new CodeGenerationError(
"No se ha definido la operación solicitada"));
Encapsulates a binary expression of our programming language.
It typechecks the runtime arguments, embeded in a method call, with the parametes of this method...
CGBinaryOperationsInfo NotFirstTime()
override bool HasFreshVariable()
To know if it is a type variable with no substitution
virtual bool HasFreshVariable()
To know if it is a type variable with no substitution
This class walks the AST to obtain the IL code.
CGBinaryOperationsInfo(CGBinaryOperationsInfo c)
TypeExpression ExpressionType
Gets or sets the type of the expression.
This class represent the entry wnen sending a message to an operation object derived from TypeExpress...
CGBinaryOperationsInfo(TypeExpression typeExpression1, TypeExpression typeExpression2, int operandOrdinal, bool firstTime, bool allTypeExpressions1, bool allTypeExpressions2)
Abstract class that represents all different types.
Represents a generic type expression
CGBinaryOperationsInfo(TypeExpression t1, TypeExpression t2)
CGBinaryOperationsInfo Clone()
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.
This class encapsulates the IL code to generate an exception produced when the type on the top of the...