The StaDyn Programming Language
Source code documentation of StaDyn, a hybrid static and dynamic typing language.
VisitorILCodeGeneration.cs
Go to the documentation of this file.
1 // -------------------------------------------------------------------------- //
3 // Project rROTOR //
4 // -------------------------------------------------------------------------- //
5 // File: VisitorCodeGeneration.cs //
6 // Author: Cristina Gonzalez Muñoz - cristi.gm@gmail.com //
7 // Francisco Ortin - francisco.ortin@gmail.com //
8 // Daniel Zapico Rodríguez - daniel.zapico.rodriguez@gmail.com //
9 // Description: //
10 // This class walks the AST to obtain the IL code. //
11 // Inheritance: VisitorAdapter //
12 // Implements Visitor pattern [Concrete Visitor]. //
13 // Implements Factory method (the constructor) [Creator]. //
14 // -------------------------------------------------------------------------- //
15 // Create date: 28-05-2007 //
16 // Modification date: 21-08-2007 //
18 
19 using System;
20 using System.Collections.Generic;
21 using AST;
22 using TypeSystem;
23 using CodeGeneration.Operations;
24 using TypeSystem.Operations;
25 
26 namespace CodeGeneration {
34  abstract class VisitorILCodeGeneration<T> : VisitorCodeGeneration<T> where T : ILCodeGenerator {
35  #region Fields
36 
40  private List<FieldDefinition>[] fields;
41 
45  protected int indent;
46 
50  private ConstantTable constantsTable;
51 
52 
57  private static String GetAuxFielVar()
58  {
59  return auxFieldVar + (auxFieldVarNumber++) + "_";
60  }
61 
65  private const string auxFieldVar = "v_local_field_temp_";
66 
70  private static int auxFieldVarNumber = 0;
71 
75  private const string auxSwitchCond = "v_local_condition_temp_";
76 
77  #endregion
78 
79  private int namespaceDepth = 0;
80 
81  //int indent = 0;
82  #region Constructor
83 
89  public VisitorILCodeGeneration(string moduleName, T codeGenerator) :
90  base(codeGenerator) {
91  this.codeGenerator.WriteHeader(moduleName);
92  this.indent = 0;
93  this.constantsTable = new ConstantTable();
94  auxFieldVarNumber = 0;
95  }
96 
97  #endregion
98 
99  #region Close()
100 
104  public override void Close() {
105  this.codeGenerator.Close();
106  }
107 
108  #endregion
109 
110  #region AddExceptionCode()
111 
115  public override void AddExceptionCode() {
116  this.codeGenerator.WriteCodeOfExceptions();
117  }
118 
119  #endregion
120 
121  // Declaration
122 
123  #region Visit(SourceFile node, Object obj)
124 
125  public override Object Visit(SourceFile node, Object obj) {
126  this.codeGenerator.InitialComment();
127 
128  foreach (string key in node.Namespacekeys) {
129  int count = node.GetNamespaceDefinitionCount(key);
130  for (int i = 0; i < count; i++)
131  node.GetNamespaceDeclarationElement(key, i).Accept(this, obj);
132  }
133  for (int i = 0; i < node.DeclarationCount; i++)
134  node.GetDeclarationElement(i).Accept(this, obj);
135 
136  return null;
137  }
138 
139  #endregion
140 
141  #region Visit(Namespace node, Object obj)
142 
143  public override Object Visit(Namespace node, Object obj) {
144  this.namespaceDepth++;
145  this.codeGenerator.WriteNamespaceHeader(this.indent++, node.Identifier.Identifier);
146  for (int i = 0; i < node.NamespaceMembersCount; i++)
147  node.GetDeclarationElement(i).Accept(this, obj);
148 
149  this.codeGenerator.WriteEndOfBlock(--this.indent);
150  this.namespaceDepth--;
151  return null;
152  }
153 
154  #endregion
155 
156  #region Visit(ClassDefinition node, Object obj)
157 
158  public override Object Visit(ClassDefinition node, Object obj) {
159  this.constantsTable.Set();
160  this.fields = (List<FieldDefinition>[])node.Accept(new VisitorCodeGeneration2(), null);
161 
162  node.TypeExpr.AcceptOperation(new CGClassDefinitionStartOperation<T>(this.codeGenerator, this.indent, node), null);
163  this.indent++;
164 
165  for (int i = 0; i < node.MemberCount; i++)
166  node.GetMemberElement(i).Accept(this, obj);
167 
168  if (this.fields[0].Count != 0)
169  this.AddConstructor((ClassType)node.TypeExpr, new InheritedAttributes(null, false, null, false, null, false));
170 
171  if (this.fields[1].Count != 0)
172  this.AddStaticConstructor((ClassType)node.TypeExpr, new InheritedAttributes(null, false, null, false, null, false));
173 
174  this.codeGenerator.WriteEndOfClass(--this.indent, node.FullName);
175  this.constantsTable.Reset();
176 
177  return null;
178  }
179  #endregion
180 
181  #region Visit(InterfaceDefinition node, Object obj)
182 
183  public override Object Visit(InterfaceDefinition node, Object obj) {
184  node.TypeExpr.AcceptOperation(new CGInterfaceDefinitionStartOperation<T>(this.codeGenerator, this.indent, node), null);
185  this.indent++;
186 
187  for (int i = 0; i < node.MemberCount; i++)
188  node.GetMemberElement(i).Accept(this, obj);
189 
190  this.codeGenerator.WriteEndOfInterface(--this.indent, node.FullName);
191 
192  return null;
193  }
194 
195  #endregion
196 
197  #region Visit(FieldDeclaration node, Object obj)
198 
199  public override Object Visit(FieldDeclaration node, Object obj) {
200  return node.TypeExpr.AcceptOperation(new CGProcessFieldOperation<T>(this.codeGenerator, this.indent, node, false, obj), null);
201  }
202 
203  #endregion
204 
205  #region Visit(FieldDefinition node, Object obj)
206 
207  public override Object Visit(FieldDefinition node, Object obj) {
208  return node.TypeExpr.AcceptOperation(new CGProcessFieldOperation<T>(this.codeGenerator, this.indent, node, false, obj), null);
209  }
210 
211  #endregion
212 
213  #region Visit(ConstantFieldDefinition node, Object obj)
214 
215  public override Object Visit(ConstantFieldDefinition node, Object obj) {
216  node.TypeExpr.AcceptOperation(new CGProcessFieldOperation<T>(this.codeGenerator, this.indent, node, true, obj), null);
217  node.Init.ILTypeExpression.AcceptOperation(new CGConstantFieldDefinitionInitializationOperation<T>(this.codeGenerator, node, obj), null);
218  this.constantsTable.Insert(node.Identifier, node.Init);
219 
220  return null;
221  }
222 
223  #endregion
224 
225  #region Visit(MethodDeclaration node, Object obj)
226 
227  public override Object Visit(MethodDeclaration node, Object obj) {
228  node.TypeExpr.AcceptOperation(new CGProcessMethodOperation<T>(this.codeGenerator, this.indent, node, obj), null);
229  // as the method is not defined we generate code for an empty block
230  this.codeGenerator.WriteStartBlock(this.indent);
231  this.codeGenerator.WriteEndOfBlock(this.indent);
232  return null;
233  }
234 
235  #endregion
236 
237  #region Visit(MethodDefinition node, Object obj)
238 
239  public override Object Visit(MethodDefinition node, Object obj) {
240  // if the method is abstract generate an empty body and return
241  if (node.ModifiersInfo.Contains(Modifier.Abstract)) {
242  node.TypeExpr.AcceptOperation(new CGProcessMethodOperation<T>(this.codeGenerator, this.indent, node, obj), null);
243  this.codeGenerator.WriteStartBlock(this.indent++);
244  this.codeGenerator.WriteEndOfMethod(--this.indent, ((MethodType)node.TypeExpr).MemberInfo.MemberIdentifier);
245  return null;
246  }
247 
248  this.constantsTable.Set();
249  auxFieldVarNumber = 0;
250 
251  node.TypeExpr.AcceptOperation(new CGProcessMethodOperation<T>(this.codeGenerator, this.indent, node, obj), null);
252  this.codeGenerator.WriteStartBlock(this.indent++);
253  if (node.IsEntryPoint)
254  this.codeGenerator.WriteEntryPoint(this.indent);
255 
256  // First step. Search the information of local variables.
257  List<IdDeclaration> decls = (List<IdDeclaration>)node.Accept(new VisitorCodeGeneration2(), null);
258  this.ProcessLocalVars(decls);
259  this.codeGenerator.WriteLocalVariable(this.indent);
260 
261  // Second step. Visits the method body.
262  node.Body.Accept(this, new InheritedAttributes(node, false, null, false, null, false));
263 
264  // Returns always ...
265  //if (node.ReturnTypeInfo.Equals(VoidType.Instance.FullName))
266  this.codeGenerator.ret(this.indent--);
267  this.codeGenerator.WriteEndOfMethod(this.indent, ((MethodType)node.TypeExpr).MemberInfo.MemberIdentifier);
268  this.constantsTable.Reset();
269 
270  return null;
271  }
272 
273  #endregion
274 
275  #region Visit(ConstructorDefinition node, Object obj)
276 
277  public override Object Visit(ConstructorDefinition node, Object obj) {
278  this.constantsTable.Set();
279  auxFieldVarNumber = 0;
280 
281  node.TypeExpr.AcceptOperation(new CGProcessMethodOperation<T>(this.codeGenerator, this.indent, node, obj), null);
282  this.codeGenerator.WriteStartBlock(this.indent++);
283 
284  // First of all, writes the IL code of fields initialization.
285  if ((((MethodType)node.TypeExpr).MemberInfo.ModifierMask & Modifier.Static) != 0)
286  this.WriteInitStaticFields(new InheritedAttributes(node, false, null, false, null, false));
287  else {
288  this.WriteInitFields(new InheritedAttributes(node, false, null, false, null, false));
289  this.codeGenerator.ldarg(this.indent, 0);
290  if (node.Initialization != null)
291  node.Initialization.Accept(this, new InheritedAttributes(node, false, null, false, null, false));
292  else
293  // calls the default base constructor
294  this.codeGenerator.constructorCall(this.indent, ((ClassType)((MethodType)node.TypeExpr).MemberInfo.Class).BaseClass, ".ctor");
295  }
296 
297  // Second step. Search the information of local variables.
298  List<IdDeclaration> decls = (List<IdDeclaration>)node.Accept(new VisitorCodeGeneration2(), null);
299  this.ProcessLocalVars(decls);
300  this.codeGenerator.WriteLocalVariable(this.indent);
301 
302  // Third step. Visits the method body
303  node.Body.Accept(this, new InheritedAttributes(node, false, null, false, null, false));
304  this.codeGenerator.ret(this.indent--);
305  this.codeGenerator.WriteEndOfMethod(this.indent, ((MethodType)node.TypeExpr).MemberInfo.MemberIdentifier);
306 
307  this.constantsTable.Reset();
308 
309  return null;
310  }
311 
312  #endregion
313 
314  #region WriteInitFields()
315 
316  private void WriteInitFields(Object obj) {
317  Object o;
318  for (int i = 0; i < this.fields[0].Count; i++) {
319  o = this.fields[0][i].Init.Accept(new VisitorCodeGeneration2(), null);
320  if (o is List<IdDeclaration>)
321  this.ProcessLocalVars((List<IdDeclaration>)o);
322  }
323 
324  this.codeGenerator.WriteLocalVariable(this.indent);
325 
326  for (int i = 0; i < this.fields[0].Count; i++) {
327  this.codeGenerator.ldarg(this.indent, 0);
328  this.fields[0][i].Init.Accept(this, obj);
329  this.codeGenerator.stfld(this.indent, this.fields[0][i].TypeExpr, ((FieldType)this.fields[0][i].TypeExpr).MemberInfo.Class.FullName, this.fields[0][i].Identifier);
330  }
331  this.fields[0].Clear();
332  }
333 
334  #endregion
335 
336  #region WriteInitStaticFields()
337 
338  private void WriteInitStaticFields(Object obj) {
339  Object o;
340  for (int i = 0; i < this.fields[1].Count; i++) {
341  o = this.fields[1][i].Init.Accept(new VisitorCodeGeneration2(), null);
342  if (o is List<IdDeclaration>)
343  this.ProcessLocalVars((List<IdDeclaration>)o);
344  }
345 
346  this.codeGenerator.WriteLocalVariable(this.indent);
347 
348  for (int i = 0; i < this.fields[1].Count; i++) {
349  this.fields[1][i].Init.Accept(this, obj);
350  this.codeGenerator.Promotion(this.indent, this.fields[1][i].Init.ExpressionType, this.fields[1][i].Init.ILTypeExpression, this.fields[1][i].TypeExpr, this.fields[1][i].TypeExpr, false, false);
351  this.codeGenerator.stsfld(this.indent, this.fields[1][i].TypeExpr, ((FieldType)this.fields[1][i].TypeExpr).MemberInfo.Class.FullName, this.fields[1][i].Identifier);
352  }
353  this.fields[1].Clear();
354  }
355 
356  #endregion
357 
358  #region AddConstructor()
359 
360  private void AddConstructor(ClassType classType, Object obj) {
361  this.codeGenerator.WriteConstructorHeader(this.indent);
362  this.codeGenerator.WriteStartBlock(this.indent++);
363  this.WriteInitFields(obj);
364  this.codeGenerator.ldarg(this.indent, 0);
365  this.codeGenerator.constructorCall(this.indent, classType.BaseClass, ".ctor");
366  this.codeGenerator.ret(this.indent--);
367 
368  this.codeGenerator.WriteEndOfMethod(this.indent, classType.Name);
369  }
370 
371  #endregion
372 
373  #region AddStaticConstructor()
374 
375  private void AddStaticConstructor(ClassType classType, Object obj) {
376  this.codeGenerator.WriteStaticConstructorHeader(this.indent);
377  this.codeGenerator.WriteStartBlock(this.indent++);
378  this.WriteInitStaticFields(obj);
379  this.codeGenerator.ret(this.indent--);
380  this.codeGenerator.WriteEndOfMethod(this.indent, classType.Name);
381  }
382 
383  #endregion
384 
385  //#region ProcessMethod()
386 
387  //private void ProcessMethod(MethodDeclaration node, Object obj) {
388  // node.TypeExpr.AcceptOperation(new CGProcessMethodOperation<T>(this.codeGenerator, this.indent, node, obj));
389  //}
390 
391  //#endregion
392 
393  //#region ProcessField()
394 
395  //private void ProcessField(FieldDeclaration node, Object obj, bool constantField) {
396  // node.TypeExpr.AcceptOperation(new CGProcessFieldOperation<T>(this.codeGenerator, this.indent, node, constantField, obj));
397  //}
398 
399  //#endregion
400 
401  #region CheckMakeAnUnbox()
402 
403  internal bool CheckMakeAnUnbox(Expression exp) {
404  if (exp is ArgumentExpression)
405  exp = ((ArgumentExpression)exp).Argument;
406  return (bool)exp.AcceptOperation(new AST.Operations.CheckMakeAnUnboxOperation(), null);
407  }
408 
409  #endregion
410 
411  #region Visit(Definition node, Object obj)
412  // no hago mas qe una operación pues me saldrían jerarquias de clase distintas
413  public override Object Visit(Definition node, Object obj) {
414  //node.Init.Accept(this, obj);
415  //InvocationExpression i;
416  //MethodType mt;
417  //if ((i = node.Init as InvocationExpression) != null) {
418  // if ((mt = i.ActualMethodCalled as MethodType) != null) {
419  // // Both elements of condition must be the same, but it is not true, the promotion is different.
420  // if (node.Init.ILTypeExpression.IsValueType() && !mt.Return.IsValueType())
421  // this.codeGenerator.Promotion(this.indent, mt.Return, mt.Return, node.TypeExpr, node.ILTypeExpression, true, CheckMakeAnUnbox(node.Init));
422  // else
423  // this.codeGenerator.Promotion(this.indent, node.Init.ExpressionType, node.Init.ILTypeExpression, node.TypeExpr, node.ILTypeExpression, true, CheckMakeAnUnbox(node.Init));
424  // }
425  //} else
426  // this.codeGenerator.Promotion(this.indent, node.Init.ExpressionType, node.Init.ILTypeExpression, node.TypeExpr, node.ILTypeExpression, true, CheckMakeAnUnbox(node.Init));
427 
428  //this.codeGenerator.stloc(this.indent, node.ILName);
429  //this.codeGenerator.WriteLine();
430  //return null;
431  return node.AcceptOperation(new CGVisitDefinitionNodeOperation<T>(this, node, this.codeGenerator, this.indent, obj), null);
432  }
433 
434 
435  #endregion
436 
437  #region Visit(ConstantDefinition node, Object obj)
438 
439  public override Object Visit(ConstantDefinition node, Object obj) {
440  return this.constantsTable.Insert(node.Identifier, node.Init);
441  }
442 
443  #endregion
444 
445  #region ProcessLocalVars()
446 
447  private void ProcessLocalVars(List<IdDeclaration> decls) {
448  //this.codeGenerator.LocalVariableIndex = 0;
449  for (int i = 0; i < decls.Count; i++)
450  this.codeGenerator.AddLocalVariable(decls[i].ILName, decls[i].ILTypeExpression);
451  }
452 
453  #endregion
454 
455  // obj param stores a code generation helper for each statement or expression.
456  // - stores current method information.
457  // - stores information about assignment expressions.
458  // True if it is necessary to create a store instruction. Otherwise, false.
459  // - stores reference information of a concrete identifier.
460  // - stores information about array access.
461  // True if array access expression found. Otherwise, false.
462  // - stores the type expression of the current invocation.
463  // If not exists, their value is null. // - stores information about the parent node.
464  // True if the parent node is an InvocationExpression. Otherwise, false.
465 
466  // Expressions
467 
468  #region Visit(ArithmeticExpression node, Object obj)
469 
470  public override Object Visit(ArithmeticExpression node, Object obj) {
471  TypeExpression t1 = node.FirstOperand.ILTypeExpression;
472  TypeExpression t2 = node.SecondOperand.ILTypeExpression;
473  t1.AcceptOperation(new NewOperations.CGArithmeticOperation<T>(this, obj, this.indent, node), null);
474  return null;
475  }
476 
477  #endregion
478 
479  #region Visit(BitwiseExpression node, Object obj)
480 
481  public override Object Visit(BitwiseExpression node, Object obj) {
482  TypeExpression t1 = node.FirstOperand.ILTypeExpression;
483  t1.AcceptOperation(new NewOperations.CGBitwiseOperation<T>(this, obj, this.indent, node), null);
484  return null;
485  }
486 
487  #endregion
488 
489  #region Visit(LogicalExpression node, Object obj)
490 
491  public override Object Visit(LogicalExpression node, Object obj) {
492  string label0 = this.codeGenerator.NewLabel;
493  string label1 = this.codeGenerator.NewLabel;
494 
495  node.FirstOperand.Accept(this, obj);
496  // Checks if it is necessary to make a implicit conversion
497  this.codeGenerator.Promotion(this.indent, node.FirstOperand.ExpressionType, node.FirstOperand.ILTypeExpression, node.ExpressionType, node.ExpressionType, true, CheckMakeAnUnbox(node.FirstOperand));
498 
499  switch (node.Operator) {
500  case LogicalOperator.Or:
501  this.codeGenerator.brtrue(this.indent, label0);
502  break;
503  case LogicalOperator.And:
504  this.codeGenerator.brfalse(this.indent, label0);
505  break;
506  default:
507  break;
508  }
509 
510  node.SecondOperand.Accept(this, obj);
511  // Checks if it is necessary to make a implicit conversion
512  this.codeGenerator.Promotion(this.indent, node.SecondOperand.ExpressionType, node.SecondOperand.ILTypeExpression, node.ExpressionType, node.ExpressionType, true, CheckMakeAnUnbox(node.SecondOperand));
513 
514  this.codeGenerator.br(this.indent, label1);
515  this.codeGenerator.WriteLabel(this.indent, label0);
516 
517  switch (node.Operator) {
518  case LogicalOperator.Or:
519  this.codeGenerator.ldci4(this.indent, 1);
520  break;
521  case LogicalOperator.And:
522  this.codeGenerator.ldci4(this.indent, 0);
523  break;
524  default:
525  break;
526  }
527 
528  this.codeGenerator.WriteLabel(this.indent, label1);
529  return null;
530  }
531 
532  #endregion
533 
534  #region Visit(RelationalExpression node, Object obj)
535 
536  public override Object Visit(RelationalExpression node, Object obj) {
537  TypeExpression t1 = node.FirstOperand.ILTypeExpression;
538  t1.AcceptOperation(new NewOperations.CGRelationalOperation<T>(this, obj, this.indent, node), null);
539  return null;
540  }
541 
542  #endregion
543 
544  #region Visit(TernaryExpression node, Object obj)
545 
546  //FirstOperand //FirstOperand
547  //bgt.s IL_0 // Uses the result to jump //SecondOpernd
548  //ThirdOperand //cgt // Stores the result in the stack
549  //br.s IL_1 //stloc.2
550  //IL_0: SecondOperand
551  //IL_1: stloc.2 // c = op1 > op2;
552 
553  // c = op1.1 > op1.2 ? op2 : op3;
554 
555  //FirstOperand
556  //cgt
557  //brtrue IL_0
558  //ThirdOperand
559  //br IL_1
560  //IL_0: SecondOperand
561  //IL_1: stloc.2
562 
563  // c = op1.1 > op1.2 ? op2 : op3;
564 
565  public override Object Visit(TernaryExpression node, Object obj) {
566  string label0 = this.codeGenerator.NewLabel;
567  string label1 = this.codeGenerator.NewLabel;
568 
569  node.FirstOperand.Accept(this, obj);
570  this.codeGenerator.Promotion(this.indent, node.FirstOperand.ExpressionType, node.FirstOperand.ILTypeExpression, BoolType.Instance, BoolType.Instance, true, CheckMakeAnUnbox(node.FirstOperand));
571 
572  this.codeGenerator.brtrue(this.indent, label0);
573 
574  node.ThirdOperand.Accept(this, obj);
575  this.codeGenerator.Promotion(this.indent, node.ThirdOperand.ExpressionType, node.ThirdOperand.ILTypeExpression, node.ExpressionType, node.ExpressionType, true, CheckMakeAnUnbox(node.ThirdOperand));
576  this.codeGenerator.br(this.indent, label1);
577 
578  this.codeGenerator.WriteLabel(this.indent, label0);
579  node.SecondOperand.Accept(this, obj);
580  this.codeGenerator.Promotion(this.indent, node.SecondOperand.ExpressionType, node.SecondOperand.ILTypeExpression, node.ExpressionType, node.ExpressionType, true, CheckMakeAnUnbox(node.SecondOperand));
581 
582  this.codeGenerator.WriteLabel(this.indent, label1);
583 
584  return null;
585  }
586 
587  #endregion
588 
589  #region Visit(UnaryExpression node, Object obj)
590 
591  public override Object Visit(UnaryExpression node, Object obj) {
592  return node.Operand.ILTypeExpression.AcceptOperation(new NewOperations.CGUnaryOperation<T>(this, obj, this.indent, node), null);
593  }
594 
595  #endregion
596 
597  #region Visit(AssignmentExpression node, Object obj)
598 
599  public override Object Visit(AssignmentExpression node, Object obj) {
602 
603  node.SecondOperand.Accept(this, obj);
604  // Checks if is necessary to make a implicit conversion
605  TypeExpression typeExp1 = node.SecondOperand.ExpressionType;
606  TypeExpression certainType1 = node.SecondOperand.ILTypeExpression;
607  TypeExpression typeExp2 = node.FirstOperand.ExpressionType;
608  TypeExpression certainType2 = node.FirstOperand.ILTypeExpression;
609  if (node.FirstOperand.ExpressionType is FieldType && ((FieldType)node.FirstOperand.ExpressionType).FieldTypeExpression is TypeVariable && ((TypeVariable)((FieldType)node.FirstOperand.ExpressionType).FieldTypeExpression).Substitution != null && ((TypeVariable)((FieldType)node.FirstOperand.ExpressionType).FieldTypeExpression).Substitution.IsValueType())
610  {
611  typeExp2 = TypeVariable.NewTypeVariable;
612  certainType2 = TypeVariable.NewTypeVariable;
613  }
614  if (node.SecondOperand.ExpressionType is FieldType && ((FieldType)node.SecondOperand.ExpressionType).FieldTypeExpression is TypeVariable && ((TypeVariable)((FieldType)node.SecondOperand.ExpressionType).FieldTypeExpression).Substitution != null && ((TypeVariable)((FieldType)node.SecondOperand.ExpressionType).FieldTypeExpression).Substitution.IsValueType())
615  {
616  typeExp1 = TypeVariable.NewTypeVariable;
617  certainType1 = TypeVariable.NewTypeVariable;
618  }
619  this.codeGenerator.Promotion(this.indent, typeExp1, certainType1, typeExp2, certainType2, true, CheckMakeAnUnbox(node.SecondOperand));
620 
621 
622 
623  this.codeGenerator.dup(this.indent);
624  bool introspectiveAssignation = false;
626  {
627  FieldAccessExpression fieldAccessExpression = (FieldAccessExpression) node.FirstOperand;
628  bool case1 = fieldAccessExpression.Expression.ExpressionType is TypeVariable && ((TypeVariable)fieldAccessExpression.Expression.ExpressionType).Substitution == null;
629  bool case2 = fieldAccessExpression.Expression.ExpressionType is FieldType && ((FieldType)fieldAccessExpression.Expression.ExpressionType).FieldTypeExpression is TypeVariable && ((TypeVariable)((FieldType)fieldAccessExpression.Expression.ExpressionType).FieldTypeExpression).Substitution == null;
630  bool case3 = fieldAccessExpression.Expression.ExpressionType is UnionType && IsUnionOfTypeVariablesWithoutSustitution(((UnionType)fieldAccessExpression.Expression.ExpressionType));
631  introspectiveAssignation = case1 || case2 || case3;
632  if (introspectiveAssignation)
633  InstrospectiveFieldAssignation(fieldAccessExpression.Expression,fieldAccessExpression.FieldName.Identifier, obj);
634  }
635  if(!introspectiveAssignation)
636  this.WriteStoreInstruction(sa, ia.CurrentMethod);
637 
638 
639  if (node.MoveStat != null)
640  node.MoveStat.Accept(this, obj);
641 
642  return null;
643  }
644 
645  #endregion
646 
647  #region WriteStoreInstruction()
648 
654  private void WriteStoreInstruction(SynthesizedAttributes sa, MethodDefinition currentMethod) {
655  SingleIdentifierExpression idToStore;
656 
657  if ((idToStore = sa.Identifier as SingleIdentifierExpression) != null) {
658  FieldType fieldType;
659  TypeExpression t = null;
660  if (idToStore.IdSymbol != null)
661  t = idToStore.IdSymbol.SymbolType;
662 
663  if (((fieldType = idToStore.ILTypeExpression as FieldType) != null) || ((fieldType = t as FieldType) != null)) {
664  if ((fieldType.MemberInfo.ModifierMask & Modifier.Static) != 0)
665  this.codeGenerator.stsfld(this.indent, fieldType.FieldTypeExpression, fieldType.MemberInfo.Class.FullName, idToStore.Identifier);
666  else {
667  string id = GetAuxFielVar() + idToStore.Identifier;
668  if (sa.CreateAuxiliarVar) {
669  // Uses a new local variable to store the field value to allow use it later
670  if (fieldType.FieldTypeExpression is TypeVariable && ((TypeVariable)fieldType.FieldTypeExpression).Substitution != null && ((TypeVariable)fieldType.FieldTypeExpression).Substitution.IsValueType())
671  this.codeGenerator.WriteAuxiliarLocalVariable(this.indent, id,"object");
672  else if (fieldType.FieldTypeExpression is ClassTypeProxy)
673  this.codeGenerator.WriteAuxiliarLocalVariable(this.indent, id, ((ClassTypeProxy)fieldType.FieldTypeExpression).RealType.ILType());
674  else
675  this.codeGenerator.WriteAuxiliarLocalVariable(this.indent, id, fieldType.FieldTypeExpression.ILType());
676  this.codeGenerator.stloc(this.indent, id);
677  }
678  this.codeGenerator.stfld(this.indent, fieldType.FieldTypeExpression, fieldType.MemberInfo.Class.FullName, idToStore.Identifier);
679  if (sa.CreateAuxiliarVar)
680  this.codeGenerator.ldloc(this.indent, id);
681  }
682  } else {
683  if (idToStore.ILTypeExpression is PropertyType) {
684  if (sa.IdentifierExpressionMode == IdentifierMode.Instance) {
685  string id = GetAuxFielVar() + idToStore.Identifier;
686  if (sa.CreateAuxiliarVar) {
687  // Uses a new local variable to store the field value to allow use it later
688  this.codeGenerator.WriteAuxiliarLocalVariable(this.indent, id, idToStore.ILTypeExpression.ILType());
689  this.codeGenerator.stloc(this.indent, id);
690  }
691 
692  this.codeGenerator.CallVirt(this.indent, (PropertyType)idToStore.ILTypeExpression, ((PropertyType)idToStore.ILTypeExpression).MemberInfo.Class, idToStore.Identifier, true);
693 
694  if (sa.CreateAuxiliarVar)
695  this.codeGenerator.ldloc(this.indent, id);
696  } else
697  this.codeGenerator.Call(this.indent, (PropertyType)idToStore.ILTypeExpression, ((PropertyType)idToStore.ILTypeExpression).MemberInfo.Class, idToStore.Identifier, true);
698  } else {
699  if ((idToStore.IndexOfSSA <= 0) && (currentMethod.SearchParam(idToStore.Identifier)))
700  this.codeGenerator.starg(this.indent, idToStore.ILName);
701  else {
702  if ((idToStore.IndexOfSSA != -1) || (idToStore.ILTypeExpression is ArrayType))
703  this.codeGenerator.stloc(this.indent, idToStore.ILName);
704  }
705  }
706  }
707  } else {
708  string id = GetAuxFielVar();
709  if (sa.CreateAuxiliarVar) {
710  // Uses a new local variable to store the field value to allow use it later
711  this.codeGenerator.WriteAuxiliarLocalVariable(this.indent, id, ((ArrayAccessExpression)sa.Identifier).ExpressionType.ILType());
712  this.codeGenerator.stloc(this.indent, id);
713  }
714  if (sa.Identifier.ExpressionType is TypeVariable && ((TypeVariable)sa.Identifier.ExpressionType).Substitution != null && ((TypeVariable)sa.Identifier.ExpressionType).Substitution.IsValueType() && !(((TypeVariable)sa.Identifier.ExpressionType).Substitution is StringType))
715  codeGenerator.Box(this.indent, sa.Identifier.ExpressionType);
716  writeStoreArrayElement(((ArrayAccessExpression)sa.Identifier).FirstOperand.ILTypeExpression, ((ArrayAccessExpression)sa.Identifier).ExpressionType);
717 
718  if (sa.CreateAuxiliarVar)
719  this.codeGenerator.ldloc(this.indent, id);
720  }
721  }
722 
723  #endregion
724 
725  #region writeStoreArrayElement()
726 
727  private void writeStoreArrayElement(TypeExpression reference, TypeExpression type) {
728  if (TypeExpression.Is<FieldType>(reference))
729  reference = ((FieldType)reference).FieldTypeExpression;
730  if (TypeExpression.Is<ArrayType>(reference))
731  type.AcceptOperation(new CGStoreArrayElementOperation<T>(this.codeGenerator, this.indent), null);
732  else if (reference is UnionType)
733  {
734  bool sw = false;
735  UnionType unionType = (UnionType)reference;
736  foreach (var singleType in unionType.TypeSet)
737  {
738  if (singleType.IsValueType())
739  {
740  type.AcceptOperation(new CGStoreArrayElementOperation<T>(this.codeGenerator, this.indent), null);
741  sw = true;
742  break;
743  }
744  if (singleType is FieldType)
745  {
746  writeStoreArrayElement(singleType, type);
747  sw = true;
748  break;
749  }
750  }
751  if (!sw)
752  TypeVariable.NewTypeVariable.AcceptOperation(new CGStoreArrayElementOperation<T>(this.codeGenerator, this.indent), null);
753  }
754  else if (reference is TypeVariable && ((TypeVariable)reference).Substitution == null)
755  type.AcceptOperation(new CGStoreArrayElementOperation<T>(this.codeGenerator, this.indent), null);
756  else
757  // Only BCLClass can be indexer. (Indexer class definition currently does not apply because it is commented in grammar file).
758  IndexerCall(reference, "set_Item");
759  }
760 
761  #endregion
762 
763  #region writeLoadArrayElement()
764 
765  private void writeLoadArrayElement(TypeExpression reference, TypeExpression type)
766  {
767  if (TypeExpression.Is<FieldType>(reference))
768  reference = ((FieldType)reference).FieldTypeExpression;
769  if (TypeExpression.Is<ArrayType>(reference))
770  type.AcceptOperation(new CGLoadArrayElementOperation<T>(this.codeGenerator, this.indent), null);
771  else if(reference is UnionType) //TODO: Esta parte es muy mejorable
772  {
773  bool sw = false;
774  UnionType unionType = (UnionType) reference;
775  foreach (var singleType in unionType.TypeSet)
776  {
777  if (singleType.IsValueType())
778  {
779  type.AcceptOperation(new CGLoadArrayElementOperation<T>(this.codeGenerator, this.indent), null);
780  sw = true;
781  break;
782  }
783  if (singleType is FieldType)
784  {
785  writeLoadArrayElement(singleType, type);
786  sw = true;
787  break;
788  }
789  }
790  if(!sw)
791  TypeVariable.NewTypeVariable.AcceptOperation(new CGLoadArrayElementOperation<T>(this.codeGenerator, this.indent), null);
792  }
793  else if (reference is TypeVariable && ((TypeVariable)reference).Substitution == null)
794  type.AcceptOperation(new CGLoadArrayElementOperation<T>(this.codeGenerator, this.indent), null);
795  else if(TypeExpression.As<BCLClassType>(reference).TypeInfo.IsArray)
796  type.AcceptOperation(new CGLoadArrayElementOperation<T>(this.codeGenerator, this.indent), null);
797  else
798  // Only BCLClass can be indexer. (Indexer class definition currently does not apply because it is commented in grammar file).
799  IndexerCall(reference, "get_Item");
800  }
801 
802  #endregion
803 
804  #region IndexerCall
805 
806  private void IndexerCall(TypeExpression reference, string memberId) {
807  BCLClassType bclClass = TypeExpression.As<BCLClassType>(reference);
808  if (bclClass != null)
809  if (bclClass.Methods.ContainsKey(memberId)) {
810  MethodType method = bclClass.Methods[memberId].Type as MethodType;
811  string[] args = new string[method.ParameterListCount];
812  for (int i = 0; i < method.ParameterListCount; i++)
813  args[i] = method.GetParameter(i).ILType();
814 
815  this.codeGenerator.CallVirt(this.indent, "instance ", method.Return.ILType(), reference.ILType(), memberId, args);
816  }
817  }
818 
819  #endregion
820 
821  #region Visit(CastExpression node, Object obj)
822  //OPERQCION////
823  public override Object Visit(CastExpression node, Object obj) {
824  node.Expression.Accept(this, obj);
827 
829 
830  if (ia.MessagePassed && node.ExpressionType.IsValueType())
831  return this.LoadAuxiliarVariable(node.ExpressionType.ILType());
832 
833  if (node.CastType.IsValueType() && NewOperations.CGCastOperation<T>.IsInternallyAnObject(node.Expression.ExpressionType))
834  node.Expression.ExpressionType.AcceptOperation(new NewOperations.CGCastOperation<T>(this.codeGenerator, this.indent), node.CastType);
835  else if (node.CastType.IsValueType() && !node.Expression.ILTypeExpression.IsValueType())
836  this.codeGenerator.UnboxAny(indent, node.CastType);
837  else
838  node.CastType.AcceptOperation(new NewOperations.CGCastOperation<T>(this.codeGenerator, this.indent), node.CastType);
839 
840  if (NewOperations.CGCastOperation<T>.ChechBox(node.Expression.ExpressionType))
841  this.codeGenerator.Box(indent, node.CastType);
842  return null;
843  }
844 
845  #endregion
846 
847  #region Visit(IsExpression node, Object obj)
848 
849  public override Object Visit(IsExpression node, Object obj) {
850  node.Expression.Accept(this, obj);
851  this.codeGenerator.isinst(this.indent, node.TypeExpr);
852  return null;
853  }
854 
855  #endregion
856 
857  #region Visit(NewExpression node, Object obj)
858 
859  public override Object Visit(NewExpression node, Object obj) {
860  Object objArgs = obj;
861  MethodType actualMethodCalled = node.ActualMethodCalled as MethodType;
863 
864  if (actualMethodCalled != null)
865  objArgs = new InheritedAttributes(ia.CurrentMethod, ia.Assignment, ia.Reference, ia.ArrayAccessFound, actualMethodCalled, ia.IsParentNodeAnInvocation);
866 
867  node.Arguments.Accept(this, objArgs);
868  this.codeGenerator.newobj(this.indent, actualMethodCalled, node.NewType, ".ctor");
869  return null;
870  }
871 
872  #endregion
873  public virtual void ThrowMissingMethodException(string method) {
874  this.codeGenerator.WriteThrowMissingMethodException(this.indent, method);
875  }
876 
877  #region Visit(NewArrayExpression node, Object obj)
878 
879  public override Object Visit(NewArrayExpression node, Object obj) {
882 
883  node.Size.Accept(this, iA);
884  if (node.Size.ExpressionType is TypeVariable && ((TypeVariable)node.Size.ExpressionType).Substitution == null)
885  this.codeGenerator.Promotion(this.indent, node.Size.ExpressionType , node.Size.ILTypeExpression,IntType.Instance,IntType.Instance, true, CheckMakeAnUnbox(node.Size));
886  else if (node.Size.ExpressionType is FieldType && ((FieldType)node.Size.ExpressionType).FieldTypeExpression is TypeVariable && ((TypeVariable)(((FieldType)node.Size.ExpressionType).FieldTypeExpression)).Substitution == null)
887  this.codeGenerator.Promotion(this.indent, node.Size.ExpressionType, node.Size.ILTypeExpression, IntType.Instance, IntType.Instance, true, CheckMakeAnUnbox(node.Size));
888  this.codeGenerator.newarr(this.indent, ((ArrayType)node.ExpressionType).ArrayTypeExpression);
889 
890  // Stores in auxiliar variable
891  this.codeGenerator.stloc(this.indent, node.Identifier);
892 
893  if (node.Init != null)
894  for (int i = 0; i < node.Init.ExpressionCount; i++) {
895  // Loads the auxiliar variable
896  this.codeGenerator.ldloc(this.indent, node.Identifier);
897  this.codeGenerator.ldci4(this.indent, i);
898  node.Init.GetExpressionElement(i).Accept(this, obj);
899  this.codeGenerator.Promotion(this.indent, node.Init.GetExpressionElement(i).ExpressionType, node.Init.GetExpressionElement(i).ILTypeExpression, ((ArrayType)node.ExpressionType).ArrayTypeExpression, ((ArrayType)node.ExpressionType).ArrayTypeExpression, true, CheckMakeAnUnbox(node.Init.GetExpressionElement(i)));
900  this.writeStoreArrayElement(node.ExpressionType, ((ArrayType)node.ExpressionType).ArrayTypeExpression);
901  }
902 
903  // Stores the auxiliar variable in real variable...
904  this.codeGenerator.ldloc(this.indent, node.Identifier);
905 
906  return null;
907  }
908 
909  #endregion
910 
911  // Synthesized attributes information
912  // - stores the current expression to use in store instruction in assignment node.
913  // - stores the identifier mode (Instance, UserType, Namespace)
914  // - stores information about the creation of auxiliar variables.
915  // True if it is necessary to create an auxiliar variable. Otherwise, false.
916 
917  // Returns Synthesized attributes information
918  #region Visit(ArrayAccessExpression node, Object obj)
919 
920  public override Object Visit(ArrayAccessExpression node, Object obj) {
922  Object o = new InheritedAttributes(ia.CurrentMethod, false, ia.Reference, true, ia.ActualMethodCalled, ia.IsParentNodeAnInvocation);
923 
924  node.FirstOperand.Accept(this, o);
925  node.SecondOperand.Accept(this, o);
926  TypeExpression indexTypeExpression = node.SecondOperand.ExpressionType;
927  if (indexTypeExpression is TypeVariable && (((TypeVariable)indexTypeExpression).Substitution == null || ((TypeVariable)indexTypeExpression).Substitution is UnionType))
928  codeGenerator.UnboxAny(this.indent,IntType.Instance);
929  else if (indexTypeExpression is UnionType)
930  codeGenerator.UnboxAny(this.indent, IntType.Instance);
931 
932  // Checks if it is necessary to promotion the index type expression
933  BCLClassType bclClass;
934  TypeExpression reference = node.FirstOperand.ILTypeExpression;
935  if (TypeExpression.Is<FieldType>(reference))
936  reference = ((FieldType)reference).FieldTypeExpression;
937 
938  if ((bclClass = TypeExpression.As<BCLClassType>(reference)) != null) {
939  if (bclClass.Methods.ContainsKey("get_Item")) {
940  MethodType method = bclClass.Methods["get_Item"].Type as MethodType;
941  if (method.ParameterListCount == 1)
942  this.codeGenerator.Promotion(this.indent, node.SecondOperand.ExpressionType, node.SecondOperand.ILTypeExpression, method.GetParameter(0), method.GetParameter(0), true, CheckMakeAnUnbox(node.SecondOperand));
943  }
944  }
945  else if (node.SecondOperand.ILTypeExpression is FieldType && ((FieldType)node.SecondOperand.ILTypeExpression).FieldTypeExpression is TypeVariable && ((TypeVariable)((FieldType)node.SecondOperand.ILTypeExpression).FieldTypeExpression).Substitution == null)
946  {
947  this.codeGenerator.Promotion(this.indent, node.SecondOperand.ExpressionType, node.SecondOperand.ILTypeExpression, IntType.Instance, IntType.Instance, true, CheckMakeAnUnbox(node.SecondOperand));
948  }
949 
950  if (!((InheritedAttributes)obj).Assignment)
951  this.writeLoadArrayElement(node.FirstOperand.ILTypeExpression, node.ExpressionType);
952 
953  return new SynthesizedAttributes(node);
954  }
955 
956  #endregion
957 
958  // Returns Synthesized attributes information
959  #region Visit(FieldAccessExpression node, Object obj)
960 
961  public bool IsUnionOfProperties(UnionType ut)
962  {
963  foreach (var typeExpression in ut.TypeSet)
964  if (!(typeExpression is PropertyType))
965  return false;
966  return true;
967  }
968 
970  {
971  foreach (var typeExpression in ut.TypeSet)
972  {
973  if (!(typeExpression is TypeVariable))
974  return false;
975  if ((typeExpression as TypeVariable).Substitution != null)
976  return false;
977  }
978  return true;
979  }
980 
981  private bool UnionTypeContainsField(UnionType unionType)
982  {
983  foreach (var typeExpression in unionType.TypeSet)
984  {
985  if (typeExpression is FieldType)
986  return true;
987  }
988  return false;
989  }
990 
991  public override Object Visit(FieldAccessExpression node, Object obj) {
993  InheritedAttributes objLeft = new InheritedAttributes(ia.CurrentMethod, false, ia.Reference, ia.ArrayAccessFound, ia.ActualMethodCalled, false, node, true);
994  InheritedAttributes objRight = new InheritedAttributes(ia.CurrentMethod, ia.Assignment, node.Expression, ia.ArrayAccessFound, ia.ActualMethodCalled, false, node, true);
995  Object o = node.Expression.Accept(this, objLeft);
996 
997  if (!ia.Assignment)
998  {
999  // Grammar file has not property definition. We only can call properties had been defined in mscorlib.
1000  if (node.ILTypeExpression is PropertyType)
1001  {
1002  PropertyType propertyType = (PropertyType) node.ILTypeExpression;
1003  node.FieldName.Accept(this, objRight);
1004  this.CallProperty(propertyType, propertyType.MemberInfo.Class, ia, o);
1005  }
1006  else if (node.ILTypeExpression is UnionType && IsUnionOfProperties((UnionType)node.ILTypeExpression))
1007  {
1008  UnionType unionType = node.ILTypeExpression as UnionType;
1009  node.FieldName.Accept(this, objRight);
1010  string endLabel = this.codeGenerator.NewLabel;
1011  // * 1.2.1.1 The implicit object has unknown type (union types)
1012  bool clean = false;
1013  for (int i = 0; i < unionType.Count; i++) {
1014  PropertyType propertyType = TypeExpression.As<PropertyType>(unionType.TypeSet[i]);
1015  TypeExpression actualClass = TypeExpression.As<TypeExpression>(propertyType.MemberInfo.Class);
1016  if (actualClass != null) {
1017  string nextPropertyLabel = this.codeGenerator.NewLabel;
1018  if ((propertyType.MemberInfo.ModifierMask & Modifier.Static) == 0) {
1019  // check the invocation reference
1020  clean = true;
1021  this.codeGenerator.dup(this.indent);
1022  this.codeGenerator.isinst(this.indent, actualClass);
1023  this.codeGenerator.brfalse(this.indent, nextPropertyLabel);
1024 
1025  if (actualClass.IsValueType())
1026  this.codeGenerator.Unbox(this.indent, actualClass);
1027  }
1028  this.CallProperty(propertyType, actualClass, ia, o);
1029  this.codeGenerator.br(this.indent, endLabel);
1030  if (clean)
1031  this.codeGenerator.WriteLabel(this.indent, nextPropertyLabel);
1032  } // end of actualPropertyCall != null
1033  } // end for
1034  // There are some mistake. Throws MissingMethodException.
1035  this.ThrowMissingMethodException(node.ILTypeExpression.ILType());
1036  // End of invocation.
1037  this.codeGenerator.WriteLabel(this.indent, endLabel);
1038 
1039  }
1040  else {//it can be a Field or a Property
1042  {
1043  node.FieldName.Accept(this, objRight);
1044  // * If fieldname is a method and the expression is a built in type, we must do boxing
1045  MethodType method = TypeExpression.As<MethodType>(node.FieldName.ExpressionType);
1046  if (node.Expression.ExpressionType.IsValueType() && method != null)
1047  this.codeGenerator.BoxIfNeeded(this.indent, node.Expression.ExpressionType);
1048  }
1049  else if ((node.Expression.ILTypeExpression is TypeVariable || (node.Expression.ILTypeExpression is UnionType && IsUnionOfTypeVariablesWithoutSustitution(node.Expression.ILTypeExpression as UnionType))) && !ia.IsParentNodeAnInvocation)
1050  this.InstrospectiveFieldInvocation(node.Expression, node.FieldName.Identifier, objLeft);
1051  else if ((node.Expression.ILTypeExpression is TypeVariable || (node.Expression.ILTypeExpression is UnionType && IsUnionOfTypeVariablesWithoutSustitution(node.Expression.ILTypeExpression as UnionType))) && ia.ActualMethodCalled != null && !node.FieldName.FrozenTypeExpression.typeExpression.Contains("->"))
1052  this.InstrospectiveFieldInvocation(node.Expression, node.FieldName.Identifier, objLeft);
1053  else if ((node.Expression.ILTypeExpression is FieldType) && (((FieldType)node.Expression.ILTypeExpression).FieldTypeExpression is TypeVariable) && !ia.IsParentNodeAnInvocation)
1054  this.InstrospectiveFieldInvocation(node.Expression, node.FieldName.Identifier, objLeft);
1055  else if (node.FieldName.ExpressionType is UnionType && !UnionTypeContainsField(node.FieldName.ExpressionType as UnionType) && !ia.IsParentNodeAnInvocation)
1056  this.InstrospectiveFieldInvocation(node.Expression, node.FieldName.Identifier, objLeft);
1057  else if (node.FieldName.ExpressionType is UnionType && UnionTypeContainsField(node.FieldName.ExpressionType as UnionType))
1058  {
1059  String finalLabel = this.codeGenerator.NewLabel;
1060  String nextLabel = "";
1061  UnionType unionType = node.FieldName.ExpressionType as UnionType;
1062  for (int i = 0; i < unionType.TypeSet.Count; i++)
1063  {
1064  if (i != unionType.TypeSet.Count - 1 && unionType.TypeSet[i] is FieldType)
1065  {
1066  if (!String.IsNullOrEmpty(nextLabel))
1067  this.codeGenerator.WriteLabel(indent, nextLabel);
1068  nextLabel = this.codeGenerator.NewLabel;
1069  this.codeGenerator.dup(indent);
1070  this.codeGenerator.isinst(indent, ((FieldType)unionType.TypeSet[i]).MemberInfo.Class);
1071  this.codeGenerator.brfalse(indent, nextLabel);
1072  WriteLoadField(unionType.TypeSet[i] as FieldType, node.FieldName.Identifier, objRight);
1073  this.codeGenerator.br(indent, finalLabel);
1074  }
1075  else if (i == unionType.TypeSet.Count - 1)
1076  {
1077  if (!String.IsNullOrEmpty(nextLabel))
1078  this.codeGenerator.WriteLabel(indent, nextLabel);
1079  this.InstrospectiveFieldInvocation(node.Expression, node.FieldName.Identifier, objLeft);
1080  this.codeGenerator.WriteLabel(indent, finalLabel);
1081  }
1082  }
1083  }
1084  else
1085  {
1086  node.FieldName.Accept(this, objRight);
1087  // * If fieldname is a method and the expression is a built in type, we must do boxing
1088  MethodType method = TypeExpression.As<MethodType>(node.FieldName.ExpressionType);
1089  if (node.Expression.ExpressionType.IsValueType() && method != null)
1090  this.codeGenerator.BoxIfNeeded(this.indent, node.Expression.ExpressionType);
1091  }
1092  }
1093 
1094  return o;
1095  } else {
1096  Object oAux = node.FieldName.Accept(this, objRight);
1097  if (node.ILTypeExpression is PropertyType)
1098  {
1099  if (oAux is SynthesizedAttributes && o is SynthesizedAttributes)
1100  {
1101  SynthesizedAttributes sa = new SynthesizedAttributes(((SynthesizedAttributes) oAux).Identifier);
1102  sa.IdentifierExpressionMode = ((SynthesizedAttributes) o).IdentifierExpressionMode;
1103  oAux = sa;
1104  }
1105  }
1106  return oAux;
1107  }
1108 
1109  }
1110 
1117  private void CallProperty(FieldAccessExpression node, InheritedAttributes ia, Object o) {
1118  if (o is SynthesizedAttributes && ((SynthesizedAttributes)o).IdentifierExpressionMode == IdentifierMode.Instance)
1119  this.codeGenerator.CallVirt(this.indent, (PropertyType)node.ILTypeExpression, node.Expression.ILTypeExpression, node.FieldName.Identifier, ia.Assignment);
1120  else
1121  this.codeGenerator.Call(this.indent, (PropertyType)node.ILTypeExpression, node.Expression.ILTypeExpression, node.FieldName.Identifier, ia.Assignment);
1122 
1123  if (ia.MessagePassed && node.ExpressionType.IsValueType())
1124  this.LoadAuxiliarVariable(node.ExpressionType.ILType());
1125  }
1126  private void CallProperty(PropertyType propertyType, TypeExpression klass, InheritedAttributes ia, Object o) {
1127  if (o is SynthesizedAttributes && ((SynthesizedAttributes)o).IdentifierExpressionMode == IdentifierMode.Instance)
1128  this.codeGenerator.CallVirt(this.indent, propertyType, klass, propertyType.MemberInfo.MemberIdentifier, ia.Assignment);
1129  else
1130  this.codeGenerator.Call(this.indent, propertyType, klass, propertyType.MemberInfo.MemberIdentifier, ia.Assignment);
1131 
1132  if (ia.MessagePassed && propertyType.PropertyTypeExpression.IsValueType())
1133  this.LoadAuxiliarVariable(propertyType.PropertyTypeExpression.ILType());
1134  }
1135 
1136  #endregion
1137 
1138  #region InstrospectiveFieldInvocation()
1139 
1146  private void InstrospectiveFieldInvocation(Expression node, string memberName, Object obj) {
1147  this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Type", "[mscorlib]System.Object", "GetType", null);
1148  this.codeGenerator.ldstr(this.indent, memberName);
1149  this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Reflection.FieldInfo", "[mscorlib]System.Type", "GetField", new string[] { "string" });
1150  String property = this.codeGenerator.NewLabel;
1151  String fin = this.codeGenerator.NewLabel;
1152  this.codeGenerator.dup(this.indent);
1153  this.codeGenerator.brfalse(this.indent, property);
1154  node.Accept(this, obj); // ld <implicit object>
1155  this.codeGenerator.CallVirt(this.indent, "instance", "object", "[mscorlib]System.Reflection.FieldInfo", "GetValue", new string[] { "object" });
1156  this.codeGenerator.br(this.indent,fin);
1157  this.codeGenerator.WriteLabel(this.indent,property);
1158  this.codeGenerator.pop(this.indent);
1159  node.Accept(this, obj); // ld <implicit object>
1160  this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Type", "[mscorlib]System.Object", "GetType", null);
1161  this.codeGenerator.ldstr(this.indent, memberName);
1162  this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Reflection.PropertyInfo", "[mscorlib]System.Type", "GetProperty", new string[] { "string" });
1163  this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Reflection.MethodInfo", "[mscorlib]System.Reflection.PropertyInfo", "GetGetMethod", new string[] {});
1164  node.Accept(this, obj); // ld <implicit object>
1165  this.codeGenerator.ldnull(this.indent);
1166  this.codeGenerator.CallVirt(this.indent, "instance", "object", "[mscorlib]System.Reflection.MethodBase", "Invoke", new string[] { "object","object[]" });
1167  this.codeGenerator.WriteLabel(this.indent, fin);
1168  }
1169  #endregion
1170 
1171  #region InstrospectiveFieldInvocation()
1172 
1173  private void InstrospectiveFieldAssignation(Expression node, string memberName, Object obj)
1174  {
1175  string id = GetAuxFielVar() + memberName;
1176  this.codeGenerator.WriteAuxiliarLocalVariable(this.indent, id, "object");
1177  this.codeGenerator.stloc(this.indent, id);
1178  this.codeGenerator.pop(this.indent);
1179  node.Accept(this, obj); // ld <implicit object>
1180  this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Type", "[mscorlib]System.Object", "GetType", null);
1181  this.codeGenerator.ldstr(this.indent, memberName);
1182  this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Reflection.FieldInfo", "[mscorlib]System.Type", "GetField", new string[] { "string" });
1183  String property = this.codeGenerator.NewLabel;
1184  String fin = this.codeGenerator.NewLabel;
1185  this.codeGenerator.dup(this.indent);
1186  this.codeGenerator.brfalse(this.indent, property);
1187  node.Accept(this, obj); // ld <implicit object>
1188  this.codeGenerator.ldloc(this.indent, id);
1189  this.codeGenerator.CallVirt(this.indent, "instance", "void", "[mscorlib]System.Reflection.FieldInfo", "SetValue", new string[] { "object","object" });
1190  this.codeGenerator.br(this.indent, fin);
1191  this.codeGenerator.WriteLabel(this.indent, property);
1192  this.codeGenerator.pop(this.indent);
1193  node.Accept(this, obj); // ld <implicit object>
1194  this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Type", "[mscorlib]System.Object", "GetType", null);
1195  this.codeGenerator.ldstr(this.indent, memberName);
1196  this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Reflection.PropertyInfo", "[mscorlib]System.Type", "GetProperty", new string[] { "string" });
1197  this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Reflection.MethodInfo", "[mscorlib]System.Reflection.PropertyInfo", "GetSetMethod", new string[] { });
1198  node.Accept(this, obj); // ld <implicit object>
1199  this.codeGenerator.ldci4(this.indent,1);
1200  this.codeGenerator.newarr(this.indent,"object");
1201  this.codeGenerator.dup(this.indent);
1202  this.codeGenerator.ldci4(this.indent,0);
1203  this.codeGenerator.ldloc(this.indent, id);
1204  this.codeGenerator.stelemRef(this.indent);
1205  this.codeGenerator.CallVirt(this.indent, "instance", "object", "[mscorlib]System.Reflection.MethodBase", "Invoke", new string[] { "object", "object[]" });
1206  this.codeGenerator.pop(this.indent);
1207  this.codeGenerator.WriteLabel(this.indent, fin);
1208  }
1209  #endregion
1210 
1211  #region Visit(CompoundExpression node, Object obj)
1212 
1213  public override Object Visit(CompoundExpression node, Object obj) {
1214  MethodType mt = ((InheritedAttributes)obj).ActualMethodCalled;
1215 
1216  for (int i = 0; i < node.ExpressionCount; i++) {
1217  node.GetExpressionElement(i).Accept(this, obj);
1218  if (mt != null)
1219  this.codeGenerator.Promotion(this.indent, node.GetExpressionElement(i).ExpressionType, node.GetExpressionElement(i).ILTypeExpression, mt.GetParameter(i), mt.GetParameter(i), true, CheckMakeAnUnbox(node.GetExpressionElement(i)));
1220  }
1221  return null;
1222  }
1223 
1224  #endregion
1225 
1226  // Literals
1227 
1228  #region Visit(BaseExpression node, Object obj)
1229 
1230  public override Object Visit(BaseExpression node, Object obj) {
1231  this.codeGenerator.ldarg(this.indent, 0);
1232  return null;
1233  }
1234 
1235  #endregion
1236 
1237  #region Visit(BoolLiteralExpression node, Object obj)
1238 
1239  public override Object Visit(BoolLiteralExpression node, Object obj) {
1240  this.codeGenerator.ldc(this.indent, node.BoolValue);
1241  return null;
1242  }
1243 
1244  #endregion
1245 
1246  #region Visit(CharLiteralExpression node, Object obj)
1247 
1248  public override Object Visit(CharLiteralExpression node, Object obj) {
1249  this.codeGenerator.ldci4(this.indent, Convert.ToUInt16(node.CharValue));
1250  return null;
1251  }
1252 
1253  #endregion
1254 
1255  #region Visit(DoubleLiteralExpression node, Object obj)
1256 
1257  public override Object Visit(DoubleLiteralExpression node, Object obj) {
1258  this.codeGenerator.ldcr8(this.indent, node.ILValue);
1259  return null;
1260  }
1261 
1262  #endregion
1263 
1264  #region Visit(IntLiteralExpression node, Object obj)
1265 
1266  public override Object Visit(IntLiteralExpression node, Object obj) {
1267  this.codeGenerator.ldci4(this.indent, node.IntValue);
1268  return null;
1269  }
1270 
1271  #endregion
1272 
1273  #region Visit(StringLiteralExpression node, Object obj)
1274 
1275  public override Object Visit(StringLiteralExpression node, Object obj) {
1276  this.codeGenerator.ldstr(this.indent, node.StringValue);
1277  return null;
1278  }
1279 
1280  #endregion
1281 
1282  #region Visit(NullExpression node, Object obj)
1283 
1284  public override Object Visit(NullExpression node, Object obj) {
1285  this.codeGenerator.ldnull(this.indent);
1286  return null;
1287  }
1288 
1289  #endregion
1290 
1291  // Returns Synthesizedg attributes information
1292 
1293  #region Visit(SingleIdentifierExpression node, Object obj)
1294  public override Object Visit(SingleIdentifierExpression node, Object obj) {
1296  int scope;
1297  Expression exp = this.constantsTable.Search(node.Identifier, out scope);
1298 
1299  if (exp == null || node.IdSymbol != null && scope + this.namespaceDepth < node.IdSymbol.Scope)
1300  exp = null;
1301 
1302  if (exp == null) {
1303  FieldType field;
1304  TypeExpression t = null;
1305  if (node.IdSymbol != null)
1306  t = node.IdSymbol.SymbolType;
1307 
1308  field = node.ExpressionType as FieldType;
1309  if (field == null)
1310  field = t as FieldType;
1311 
1312  if (node.IdMode == IdentifierMode.Instance && helper.Reference == null && field != null && (field.MemberInfo.ModifierMask & Modifier.Static) == 0)
1313  this.codeGenerator.ldarg(this.indent, 0);
1314 
1315  if (!helper.Assignment)
1316  {
1317  if (field != null)
1318  WriteLoadField(field, node.Identifier, helper);
1319  else
1320  if (node.IndexOfSSA <= 0 && helper.CurrentMethod.SearchParam(node.Identifier))
1321  this.WriteLoadArg(node.ILName, helper);
1322  else
1323  if (node.IndexOfSSA != -1 || node.ILTypeExpression is ArrayType)
1324  this.WriteLoadLocalVar(node.ILName, helper, node.ExpressionType);
1325 
1326  }
1327  else
1328  {
1329  if (helper.ArrayAccessFound) {
1330  if (node.ILTypeExpression is ArrayType)
1331  this.codeGenerator.ldloc(this.indent, node.ILName);
1332  if (node.ILTypeExpression is FieldType && ((FieldType)node.ILTypeExpression).FieldTypeExpression is ArrayType)
1333  WriteLoadField((FieldType)node.ILTypeExpression, node.Identifier, helper);
1334  }
1335  else if (node.ExpressionType is FieldType)
1336  {
1337  if (((FieldType)node.ExpressionType).FieldTypeExpression is TypeVariable)
1338  {
1339  node.FrozenTypeExpression = node.ExpressionType;
1340  }
1341  }
1342  }
1343  }
1344  else
1345  exp.Accept(this, obj);
1346 
1347  return new SynthesizedAttributes(node);
1348  }
1349 
1350  #endregion
1351 
1352  #region WriteLoadField()
1353 
1354  private void WriteLoadField(FieldType type, string id, InheritedAttributes helper) {
1355  BCLClassType baseClass = null;
1356  if (helper.ActualMethodCalled != null)
1357  baseClass = helper.ActualMethodCalled.MemberInfo.Class as BCLClassType;
1358 
1359  if ((type.MemberInfo.ModifierMask & Modifier.Static) != 0)
1360  if (baseClass != null && baseClass.IsValueType())
1361  this.codeGenerator.ldsflda(this.indent, type, type.MemberInfo.Class.ILType(), id);
1362  else
1363  this.codeGenerator.ldsfld(this.indent, type, type.MemberInfo.Class.ILType(), id);
1364  else
1365  if ((baseClass != null) && (baseClass.IsValueType()))
1366  this.codeGenerator.ldflda(this.indent, type, type.MemberInfo.Class.ILType(), id);
1367  else
1368  this.codeGenerator.ldfld(this.indent, type, type.MemberInfo.Class.ILType(), id);
1369  }
1370 
1371  #endregion
1372 
1373  #region WriteLoadLocalVar()
1374 
1375  private void WriteLoadLocalVar(string id, InheritedAttributes helper, TypeExpression type) {
1376  // * Base class could be the BCLClass type of the implicit object...
1377  BCLClassType baseClass = null;
1378  if (helper.ActualMethodCalled != null)
1379  // ... in a method call
1380  baseClass = helper.ActualMethodCalled.MemberInfo.Class as BCLClassType;
1381  else {
1382  // ... or property access
1383  FieldAccessExpression fieldAccess = helper.ParentNode as FieldAccessExpression;
1384  if (fieldAccess != null) {
1385  PropertyType fieldType = fieldAccess.ExpressionType as PropertyType;
1386  if (fieldType != null)
1387  baseClass = fieldType.MemberInfo.Class as BCLClassType;
1388  }
1389  }
1390 
1391  if (baseClass != null && baseClass.IsValueType()) {
1392  if (!type.ILType().Equals("object"))
1393  // * A value type, as an implicit object, generates a ldloca (address)
1394  if (helper.ParentNode is FieldAccessExpression)
1395  this.codeGenerator.ldloca(this.indent, id);
1396  else
1397  // * Otherwise, it generates a lodloc (not the address)
1398  this.codeGenerator.ldloc(this.indent, id);
1399  else {
1400  this.codeGenerator.ldloc(this.indent, id);
1401  this.codeGenerator.Unbox(this.indent, baseClass);
1402  }
1403  } else
1404  this.codeGenerator.ldloc(this.indent, id);
1405  }
1406 
1407  #endregion
1408 
1409  #region WriteLoadArg()
1410 
1411  private void WriteLoadArg(string id, InheritedAttributes helper) {
1412  BCLClassType baseClass = null;
1413  if (helper.ActualMethodCalled != null)
1414  baseClass = helper.ActualMethodCalled.MemberInfo.Class as BCLClassType;
1415  // * A value type, as an implicit object, generates a ldarga (address)
1416  if (baseClass != null && baseClass.IsValueType() && helper.ParentNode is FieldAccessExpression)
1417  this.codeGenerator.ldarga(this.indent, id);
1418  else
1419  this.codeGenerator.ldarg(this.indent, id);
1420  }
1421 
1422  #endregion
1423 
1424  #region Visit(ThisExpression node, Object obj)
1425 
1426  public override Object Visit(ThisExpression node, Object obj) {
1427  this.codeGenerator.ldarg(this.indent, 0);
1428  return null;
1429  }
1430 
1431  #endregion
1432 
1433  // Statements
1434 
1435  #region Visit(ReturnStatement node, Object obj)
1436 
1437  public override Object Visit(ReturnStatement node, Object obj) {
1438  node.Assigns.Accept(this, obj);
1439  if (node.ReturnExpression != null) {
1440  node.ReturnExpression.Accept(this, obj);
1441  if (node.CurrentMethodType.Return is FieldType && ((FieldType)node.CurrentMethodType.Return).FieldTypeExpression is TypeVariable)
1442  this.codeGenerator.Promotion(this.indent, node.ReturnExpression.ExpressionType, node.ReturnExpression.ILTypeExpression, TypeVariable.NewTypeVariable, TypeVariable.NewTypeVariable, true, CheckMakeAnUnbox(node.ReturnExpression));
1443  else
1444  this.codeGenerator.Promotion(this.indent, node.ReturnExpression.ExpressionType, node.ReturnExpression.ILTypeExpression, node.CurrentMethodType.Return, node.CurrentMethodType.Return, true, CheckMakeAnUnbox(node.ReturnExpression));
1445  }
1446  this.codeGenerator.ret(this.indent);
1447  return null;
1448  }
1449 
1450  #endregion
1451 
1452  #region Visit(Block node, Object obj)
1453 
1454  public override Object Visit(Block node, Object obj) {
1455  for (int i = 0; i < node.StatementCount; i++) {
1456  node.GetStatementElement(i).Accept(this, obj);
1457  RemovesTopElement(node.GetStatementElement(i));
1458  }
1459  return null;
1460  }
1461 
1462  #endregion
1463 
1464  #region RemovesTopElement()
1465  private void RemovesTopElement(Statement stat) {
1470  // * If it is not an expression, not pop is needed
1471  if (!(stat is Expression))
1472  return;
1473 
1474  InvocationExpression invocation = stat as InvocationExpression;
1475  bool pop = true; // by default we remove the top
1476 
1477  // * If the method invoked is a procedure, nothing to pop
1478  if (invocation != null)
1479  pop = (bool)invocation.ILTypeExpression.AcceptOperation(new CGRemoveTopElementInvocationOperation(), null);
1480 
1481  if (pop)
1482  this.codeGenerator.pop(this.indent);
1483  }
1484 
1485  #endregion
1486 
1487  #region Visit(MoveStatement node, Object obj)
1488 
1489  public override Object Visit(MoveStatement node, Object obj) {
1492  node.RightExp.Accept(this, obj);
1493  sa.CreateAuxiliarVar = false;
1494  this.codeGenerator.Promotion(this.indent, node.RightExp.ExpressionType, node.RightExp.ILTypeExpression, node.LeftExp.ExpressionType, node.LeftExp.ILTypeExpression, true, CheckMakeAnUnbox(node.RightExp));
1495  WriteStoreInstruction(sa, ia.CurrentMethod);
1496  if (node.MoveStat != null)
1497  node.MoveStat.Accept(this, obj);
1498  return null;
1499  }
1500 
1501  #endregion
1502 
1503  #region Visit(IfElseStatement node, Object obj)
1504 
1505  public override Object Visit(IfElseStatement node, Object obj) {
1506  string labelElse = this.codeGenerator.NewLabel;
1507  string labelEnd = this.codeGenerator.NewLabel;
1508 
1509  node.Condition.Accept(this, obj);
1510  for (int i = 0; i < node.AfterCondition.Count; i++)
1511  node.AfterCondition[i].Accept(this, obj);
1512 
1513  this.codeGenerator.brfalse(this.indent, labelElse);
1514  this.constantsTable.Set();
1515  node.TrueBranch.Accept(this, obj);
1516  this.RemovesTopElement(node.TrueBranch);
1517  this.codeGenerator.br(this.indent, labelEnd);
1518  this.constantsTable.Reset();
1519 
1520  this.constantsTable.Set();
1521  this.codeGenerator.WriteLabel(this.indent, labelElse);
1522  node.FalseBranch.Accept(this, obj);
1523  this.RemovesTopElement(node.FalseBranch);
1524  this.constantsTable.Reset();
1525 
1526  this.codeGenerator.WriteLabel(this.indent, labelEnd);
1527 
1528  //for (int i = 0; i < node.ThetaStatements.Count; i++)
1529  // node.ThetaStatements[i].Accept(this, obj);
1530  return null;
1531  }
1532 
1533  #endregion
1534 
1535  #region Visit(DoStatement node, Object obj)
1536 
1537  public override Object Visit(DoStatement node, Object obj) {
1538  string label = this.codeGenerator.NewLabel;
1539 
1540  for (int i = 0; i < node.InitDo.Count; i++)
1541  node.InitDo[i].Accept(this, obj);
1542 
1543  //for (int i = 0; i < node.BeforeBody.Count; i++)
1544  // node.BeforeBody[i].Accept(this, obj);
1545 
1546  this.constantsTable.Set();
1547  this.codeGenerator.WriteLabel(this.indent, label);
1548  node.Statements.Accept(this, obj);
1549  this.RemovesTopElement(node.Statements);
1550  this.constantsTable.Reset();
1551 
1552  node.Condition.Accept(this, obj);
1553  this.codeGenerator.brtrue(this.indent, label);
1554  return null;
1555  }
1556 
1557  #endregion
1558 
1559  #region Visit(ForStatement node, Object obj)
1560 
1561  public override Object Visit(ForStatement node, Object obj) {
1562  string labelCondition = this.codeGenerator.NewLabel;
1563  string labelBody = this.codeGenerator.NewLabel;
1564 
1565  this.constantsTable.Set();
1566  for (int i = 0; i < node.InitializerCount; i++) {
1567  node.GetInitializerElement(i).Accept(this, obj);
1568  this.RemovesTopElement(node.GetInitializerElement(i));
1569  }
1570  for (int i = 0; i < node.AfterInit.Count; i++) {
1571  node.AfterInit[i].Accept(this, obj);
1572  }
1573  this.codeGenerator.br(this.indent, labelCondition);
1574 
1575  this.codeGenerator.WriteLabel(this.indent, labelBody);
1576  node.Statements.Accept(this, obj);
1577  this.RemovesTopElement(node.Statements);
1578 
1579  for (int i = 0; i < node.IteratorCount; i++) {
1580  node.GetIteratorElement(i).Accept(this, obj);
1581  this.RemovesTopElement(node.GetIteratorElement(i));
1582  }
1583 
1584  this.codeGenerator.WriteLabel(this.indent, labelCondition);
1585  //for (int i = 0; i < node.BeforeCondition.Count; i++)
1586  //{
1587  // node.BeforeCondition[i].Accept(this, obj);
1588  //}
1589  node.Condition.Accept(this, obj);
1590  for (int i = 0; i < node.AfterCondition.Count; i++) {
1591  node.AfterCondition[i].Accept(this, obj);
1592  }
1593  this.codeGenerator.brtrue(this.indent, labelBody);
1594 
1595  this.constantsTable.Reset();
1596  return null;
1597  }
1598 
1599  #endregion
1600 
1601  #region Visit(WhileStatement node, Object obj)
1602 
1603  public override Object Visit(WhileStatement node, Object obj) {
1604  string labelCondition = this.codeGenerator.NewLabel;
1605  string labelBody = this.codeGenerator.NewLabel;
1606 
1607  for (int i = 0; i < node.InitWhile.Count; i++)
1608  node.InitWhile[i].Accept(this, obj);
1609 
1610  this.codeGenerator.br(this.indent, labelCondition);
1611 
1612  this.constantsTable.Set();
1613  this.codeGenerator.WriteLabel(this.indent, labelBody);
1614  node.Statements.Accept(this, obj);
1615  this.RemovesTopElement(node.Statements);
1616  this.constantsTable.Reset();
1617 
1618  //for (int i = 0; i < node.BeforeCondition.Count; i++)
1619  // node.BeforeCondition[i].Accept(this, obj);
1620 
1621  this.codeGenerator.WriteLabel(this.indent, labelCondition);
1622  node.Condition.Accept(this, obj);
1623  for (int i = 0; i < node.AfterCondition.Count; i++)
1624  node.AfterCondition[i].Accept(this, obj);
1625  this.codeGenerator.brtrue(this.indent, labelBody);
1626  return null;
1627  }
1628 
1629  #endregion
1630 
1631  #region Visit(SwitchStatement node, Object obj)
1632 
1633  public override Object Visit(SwitchStatement node, Object obj) {
1634  List<string> labels = new List<string>();
1635 
1636  for (int i = 0; i < node.LabelCount(); i++)
1637  labels.Add(this.codeGenerator.NewLabel);
1638 
1639  string endLabel = this.codeGenerator.NewLabel;
1640  int index = 0;
1641  string defaultLabel = "";
1642  string idSwitchCond = auxSwitchCond + (auxFieldVarNumber++);
1643 
1644  this.codeGenerator.WriteAuxiliarLocalVariable(this.indent, idSwitchCond, node.Condition.ILTypeExpression.ILType());
1645  node.Condition.Accept(this, obj);
1646  this.codeGenerator.stloc(this.indent, idSwitchCond);
1647 
1648  for (int i = 0; i < node.AfterCondition.Count; i++)
1649  node.AfterCondition[i].Accept(this, obj);
1650 
1651  for (int i = 0; i < node.SwitchBlockCount; i++) {
1652  this.constantsTable.Set();
1653 
1654  // First, visits the label section (conditional case section or default section)
1655  for (int j = 0; j < node.GetSwitchSectionElement(i).LabelSection.Count; j++) {
1656  SwitchLabel n = node.GetSwitchSectionElement(i).LabelSection[j];
1657  if (n.SwitchSectionType == SectionType.Case) {
1658  this.codeGenerator.ldloc(this.indent, idSwitchCond);
1659  n.Condition.Accept(this, obj);
1660  this.codeGenerator.beq(this.indent, labels[index]);
1661  } else
1662  defaultLabel = labels[index];
1663  index++;
1664  }
1665  }
1666 
1667 
1668  this.codeGenerator.br(this.indent, defaultLabel != String.Empty ? defaultLabel : endLabel);
1669  index = 0;
1670 
1671  for (int i = 0; i < node.SwitchBlockCount; i++) {
1672  // Second, visits the statement section for each switch section.
1673  for (int j = 0; j < node.GetSwitchSectionElement(i).LabelSection.Count; j++)
1674  this.codeGenerator.WriteLabel(this.indent, labels[index++]);
1675 
1676  node.GetSwitchSectionElement(i).SwitchBlock.Accept(this, obj);
1677  this.RemovesTopElement(node.GetSwitchSectionElement(i).SwitchBlock);
1678  this.codeGenerator.br(this.indent, endLabel);
1679  this.constantsTable.Reset();
1680  }
1681 
1682  //for (int i = 0; i < node.ThetaStatements.Count; i++)
1683  // node.ThetaStatements[i].Accept(this, obj);
1684 
1685  this.codeGenerator.WriteLabel(this.indent, endLabel);
1686  return null;
1687  }
1688 
1689  #endregion
1690 
1691  #region Visit(SwitchLabel node, Object obj)
1692 
1693  public override Object Visit(SwitchLabel node, Object obj) {
1694  if (node.SwitchSectionType == SectionType.Case)
1695  node.Condition.Accept(this, obj);
1696  return null;
1697  }
1698 
1699  #endregion
1700 
1701  #region Visit(BreakStatement node, Object obj) // Nothing to do ¿?
1702 
1703  public override Object Visit(BreakStatement node, Object obj) {
1704  return null;
1705  }
1706 
1707 
1708  #region Visit(ExceptionManagementStatement node, Object obj)
1709 
1710  public override Object Visit(ExceptionManagementStatement node, Object obj) {
1711  this.codeGenerator.WriteTryDirective(this.indent); //.try
1712  this.codeGenerator.WriteOpenBraceTry(this.indent++); // {
1713 
1714  if (node.CatchCount != 0 && node.FinallyBlock != null) {
1715  this.codeGenerator.WriteTryDirective(this.indent); //.try
1716  this.codeGenerator.WriteOpenBraceTry(this.indent++); // {
1717  }
1718  string firstLeaveJump = this.codeGenerator.NewLabel;
1719  string secondLeaveJump = this.codeGenerator.NewLabel;
1720 
1721  node.TryBlock.Accept(this, obj);
1722  this.codeGenerator.WriteLeave(this.indent, firstLeaveJump);
1723  this.codeGenerator.WriteCloseBraceTry(--this.indent); // .end .try{
1724 
1725  if (node.CatchCount != 0) {
1726 
1727  for (int i = 0; i < node.CatchCount; i++) {
1728  node.GetCatchElement(i).Accept(this, obj);
1729  this.codeGenerator.WriteLeave(this.indent--, firstLeaveJump);
1730  this.codeGenerator.WriteCloseBraceCatch(this.indent);
1731  }
1732 
1733  this.codeGenerator.WriteLabel(this.indent, firstLeaveJump);
1734  this.codeGenerator.nop(this.indent);
1735 
1736  if (node.FinallyBlock != null) {
1737  this.codeGenerator.WriteLeave(this.indent, secondLeaveJump);
1738  this.codeGenerator.WriteCloseBraceTry(--this.indent); // .end .finally{
1739  }
1740  }
1741 
1742  if (node.FinallyBlock != null) {
1743  this.codeGenerator.WriteFinally(this.indent);
1744  this.codeGenerator.WriteOpenBraceFinally(this.indent++);
1745  node.FinallyBlock.Accept(this, obj);
1746  this.codeGenerator.WriteLine(this.indent--, "endfinally");
1747  this.codeGenerator.WriteCloseBraceFinally(this.indent); // . end try
1748  this.codeGenerator.WriteLabel(this.indent, node.CatchCount == 0 ? firstLeaveJump : secondLeaveJump);
1749  this.codeGenerator.nop(this.indent);
1750  }
1751 
1752  return null;
1753  }
1754 
1755  #endregion
1756 
1757  #region CatchStatement // very important the brace is not closed.
1758  public override Object Visit(CatchStatement node, Object obj) {
1759  this.codeGenerator.WriteCatch(this.indent, node.Exception.TypeExpr.ILType(), node.Exception.TypeExpr.ILType());
1760  this.codeGenerator.WriteOpenBraceCatch(this.indent++);
1761  this.codeGenerator.stloc(this.indent, node.Exception.ILName);//node.Exception.ILName);
1762  node.Statements.Accept(this, obj);
1763 
1764  return null;
1765  }
1766  #endregion
1767 
1768  #endregion
1769  public override Object Visit(ThrowStatement node, Object obj) {
1770  if (node.ThrowExpression == null)
1771  this.codeGenerator.WriteRethrow(this.indent);
1772  else {
1773  node.ThrowExpression.Accept(this, obj);
1774  codeGenerator.WriteThrow(this.indent);
1775  }
1776  return null;
1777  }
1778  // helpers
1779 
1780  #region LoadAuxiliarVariable
1781 
1782  protected Object LoadAuxiliarVariable(string type) {
1784  string id = tmpVars.SearchId(type);
1785 
1786  this.codeGenerator.stloc_s(this.indent, id);
1787  this.codeGenerator.ldloca_s(this.indent, id);
1788  return null;
1789  }
1790 
1791  #endregion
1792 
1793 
1794  #region RuntimeCheckArguments()
1795  internal abstract void RuntimeCheckArguments(InvocationExpression node, Object objArgs, MethodType actualMethodCalled, List<string> nextMethod);
1803 
1804  #endregion
1805  // Commented
1806 
1807  #region Commented Code
1808 
1809  // #region Visit(ContinueStatement node, Object obj)
1810 
1811  // public override Object Visit(ContinueStatement node, Object obj)
1812  // {
1813  // return null;
1814  // }
1815 
1816  // #endregion
1817 
1818  // #region Visit(ForeachStatement node, Object obj)
1819 
1820  // public override Object Visit(ForeachStatement node, Object obj)
1821  // {
1822  // node.ForEachDeclaration.Accept(this, obj);
1823  // node.ForeachExp.Accept(this, obj);
1824  // node.ForeachBlock.Accept(this, obj);
1825  // return null;
1826  // }
1827 
1828  // #endregion
1829 
1830  // #region Visit(ThrowStatement node, Object obj)
1831 
1832  // public override Object Visit(ThrowStatement node, Object obj)
1833  // {
1834  // return node.ThrowExpression.Accept(this, obj);
1835  // }
1836 
1837  // #endregion
1838 
1839  // #region Visit(ExceptionManagementStatement node, Object obj)
1840 
1841  // public override Object Visit(ExceptionManagementStatement node, Object obj)
1842  // {
1843  // node.TryBlock.Accept(this, obj);
1844  // for (int i = 0; i < node.CatchCount; i++)
1845  // {
1846  // node.GetCatchElement(i).Accept(this, obj);
1847  // }
1848  // node.FinallyBlock.Accept(this, obj);
1849  // return null;
1850  // }
1851 
1852  // #endregion
1853 
1854  // #region Visit(CatchStatement node, Object obj)
1855 
1856  // public override Object Visit(CatchStatement node, Object obj)
1857  // {
1858  // node.Exception.Accept(this, obj);
1859  // node.Statements.Accept(this, obj);
1860  // return null;
1861  // }
1862 
1863  // #endregion
1864 
1865  #endregion
1866 
1867  #region Nothing to do...
1868 
1869  //#region Visit(ThetaStatement node, Object obj)
1870 
1871  //public override Object Visit(ThetaStatement node, Object obj)
1872  //{
1873  // node.ThetaId.Accept(this, obj);
1874  // for (int i = 0; i < node.ThetaList.Count; i++)
1875  // {
1876  // node.ThetaList[i].Accept(this, obj);
1877  // }
1878  // return null;
1879  //}
1880 
1881  //#endregion
1882 
1883  //#region Visit(SwitchSection node, Object obj)
1884 
1885  //public override Object Visit(SwitchSection node, Object obj)
1886  //{
1887  // for (int i = 0; i < node.LabelSection.Count; i++)
1888  // {
1889  // node.LabelSection[i].Accept(this, obj);
1890  // }
1891  // for (int i = 0; i < node.SwitchBlock.StatementCount; i++)
1892  // {
1893  // node.SwitchBlock.GetStatementElement(i).Accept(this, obj);
1894  // }
1895  // return null;
1896  //}
1897 
1898  //#endregion
1899 
1900  // #region Visit(PropertyDefinition node, Object obj)
1901 
1902  // public override Object Visit(PropertyDefinition node, Object obj)
1903  // {
1904  // if (node.GetBlock != null)
1905  // node.GetBlock.Accept(this, obj);
1906  // if (node.SetBlock != null)
1907  // node.SetBlock.Accept(this, obj);
1908  // return null;
1909  // }
1910 
1911  // #endregion
1912 
1913  #endregion
1914  }
1915 }
Encapsulates a Return statement of our programming languages.
Encapsulates a &#39;base&#39; expression.
Encapsulates a definition of a concrete method.
override Object Visit(CatchStatement node, Object obj)
Encapsulates a Break statement of our programming languages.
override Object Visit(UnaryExpression node, Object obj)
override Object Visit(TernaryExpression node, Object obj)
MethodType CurrentMethodType
The method where the return statement appears
Abstract class encapsulate a programming language expression.
Definition: Expression.cs:37
override Object Visit(IfElseStatement node, Object obj)
bool IsParentNodeAnInvocation
Gets or sets true if the parent node is an InvocationExpression. Otherwise, false.
override Object Visit(AssignmentExpression node, Object obj)
Encapsulates a Do statement of our programming language.
Definition: DoStatement.cs:34
Expression FirstOperand
Gets the first operand of the ternary expression
Encapsulates a string literal expression.
Encapsulates the expression to access a field.
override Object Visit(MoveStatement node, Object obj)
Representa a union type.
Definition: UnionType.cs:36
Encapsulates a block of statements.
Definition: Block.cs:34
override Object Visit(StringLiteralExpression node, Object obj)
VisitorILCodeGeneration(string moduleName, T codeGenerator)
Constructor of VisitorCodeGeneration
Encapsulates a namespace definition.
Definition: Namespace.cs:35
List< MoveStatement > InitDo
Gets or sets the statements to use at the init of the do loop.
Definition: DoStatement.cs:83
Representa an array type.
Definition: ArrayType.cs:35
override Object Visit(FieldAccessExpression node, Object obj)
override bool IsValueType()
True if type expression is a ValueType. Otherwise, false.
override Object Visit(MethodDeclaration node, Object obj)
override Object Visit(BreakStatement node, Object obj)
Encapsulates a Catch statement of our programming languages.
override Object Visit(ConstructorDefinition node, Object obj)
Encapsulates a logical binary expression.
override Object Visit(RelationalExpression node, Object obj)
Encapsulates a invocation expression.
Encapsulates a boolean literal expression.
Encapsulates a cast expression.
Encapsulates a definition of a concrete field.
TypeExpression ExpressionType
Gets or sets the type of the expression.
Definition: Expression.cs:71
SectionType SwitchSectionType
Gets the type of the Case statement (case or default)
Definition: SwitchLabel.cs:77
Represent a string type.
Definition: StringType.cs:36
Modifier ModifierMask
Gets the modifier information
Abstract class represents a programming language statement.
Definition: Statement.cs:30
override Object Visit(SourceFile node, Object obj)
MethodType ActualMethodCalled
Gets or sets the type expression of the current invocation expression. If not exists, their value is null.
IdDeclaration Exception
Gets the exception to catch
override Object Visit(ForStatement node, Object obj)
override void AddExceptionCode()
Adds the intermediate code for exception to include in the file.
Dictionary< string, AccessModifier > Methods
Gets the method list
Definition: UserType.cs:96
List< MoveStatement > AfterCondition
Gets or sets the statements after condition.
MoveStatement MoveStat
Gets or sets a move statement associated to the assignment expression.
Encapsulates a constant field definition.
Encapsulates a definition.
Definition: Definition.cs:36
Encapsulates arithmetic binary expressions.
SingleIdentifierExpression RightExp
Gets the right expression
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...
Encapsulates a For statement of our programming languages.
Definition: ForStatement.cs:34
Encapsulates a While statement of our programming languages.
bool ArrayAccessFound
Gets or sets true if array access expression found. Otherwise, gets or sets false.
MethodDefinition CurrentMethod
Gets or sets the current method definition node.
override Object Visit(CharLiteralExpression node, Object obj)
Encapsulates a null expression.
int ParameterListCount
Gets the number of parameters
Definition: MethodType.cs:111
Encapsulates a Is expression.
Definition: IsExpression.cs:35
Expression SecondOperand
Gets the second operand of the binary expression
TypeExpression Return
Gets type expression method return
Definition: MethodType.cs:100
bool CreateAuxiliarVar
Gets or sets true if it is necessary to create an auxiliar variable. Otherwise, false.
override Object Visit(ReturnStatement node, Object obj)
Encapsulates a definition of a concrete interface.
AccessModifier MemberInfo
Gets or sets the attribute information of method type
Definition: FieldType.cs:65
override Object Visit(SwitchStatement node, Object obj)
Encapsulates a switch label (Case + condition or Default section).
Definition: SwitchLabel.cs:47
Represent a integer type.
Definition: IntType.cs:37
Encapsulates a identifier expression of our programming language.
Expression Reference
Gets or sets the reference of a concrete identifier.
override void Close()
Closes the code generator.
override Object Visit(BaseExpression node, Object obj)
override Object Visit(BitwiseExpression node, Object obj)
Encapsulates a declaration of a concrete method.
IdentifierMode
Represents how to use the identifier
Implementation of a table of variables. thist tables search for an id according to its string type re...
This class walks the AST to obtain the field and localinit directives.
override Object Visit(ConstantDefinition node, Object obj)
Encapsulates a set of expressions.
override Object Visit(ExceptionManagementStatement node, Object obj)
Expression ThrowExpression
Gets the throw expression.
abstract bool IsValueType()
True if type expression is a ValueType. Otherwise, false.
Type TypeInfo
Returns the real introspective type
Definition: BCLClassType.cs:36
Implementation of a table of constants.
Encapsulates a relational binary expression.
Encapsulates a bitwise binary expression.
override Object Visit(Namespace node, Object obj)
Encapsulates assignment binary expressions.
CompoundExpression Init
Gets or sets the array initialization
override Object Visit(DoubleLiteralExpression node, Object obj)
Encapsulates a ternary expression of our programming language.
override Object Visit(ClassDefinition node, Object obj)
Encapsulates a If-Else statement of our programming language.
override Object Accept(Visitor v, Object o)
Accept method of a concrete visitor.
Definition: SwitchLabel.cs:121
IdentifierMode IdentifierExpressionMode
Gets or sets the identifier mode (Instance, UserType, Namespace)
virtual string ILType()
Gets the type name to use in IL code.
Encapsulates a new array expression.
Encapsulates a definition of a concrete constructor.
Declaration GetMemberElement(int index)
Gets the element stored in the specified index.
MoveStatement MoveStat
Gets or sets a move statement associated to the current move statement.
TypeExpression FieldTypeExpression
Gets the field type.
Definition: FieldType.cs:58
Encapsulates the source code.
Definition: SourceFile.cs:35
int CatchCount
Gets the number of catch blocks.
Declaration GetDeclarationElement(int index)
Gets the element stored in the specified index.
Definition: Namespace.cs:96
Expression GetExpressionElement(int index)
Gets the element stored in the specified index.
override Object Visit(ThisExpression node, Object obj)
Encapsulates a Try-Catch-finally statement of our programming languages. As C# states catch blcok and...
abstract Object Accept(Visitor v, Object o)
Accept method of a concrete visitor.
override Object Visit(IsExpression node, Object obj)
override Object Visit(NewExpression node, Object obj)
Encapsulates a string literal expression.
override Object Visit(MethodDefinition node, Object obj)
override Object Visit(CompoundExpression node, Object obj)
SingleIdentifierExpression LeftExp
Gets the left expression
override Object Visit(LogicalExpression node, Object obj)
override Object Visit(ConstantFieldDefinition node, Object obj)
override Object Visit(FieldDeclaration node, Object obj)
This class encapsulates several inherited attributes used in code generation process.
Encapsulates a argument expression of our programming language.
List< MoveStatement > AfterCondition
Gets or sets the statements after condition.
int IndexOfSSA
Gets or sets the index associated with SSA algorithm
override Object Visit(IntLiteralExpression node, Object obj)
Encapsulates a &#39;this&#39; expression.
List< MoveStatement > InitWhile
Gets or sets the statements to use at the init of the while loop.
string ILName
Gets the IL name associated to the declaration identifier.
Encapsulates a unary expression of our programming language.
Modifier
Indicates differents modifiers to use in class (only public, internal or static), fields or methods...
int indent
Represents the indentation to write in the code file.
override Object Visit(ThrowStatement node, Object obj)
Expression Identifier
Gets or sets the current expression to use in store instruction in assignment node.
Expression Size
Gets or sets the array size
LogicalOperator Operator
Gets the operator of the binary expression
override bool IsValueType()
True if type expression is a ValueType. Otherwise, false.
Expression ReturnExpression
Gets the return expression.
bool Assignment
Gets or sets true if assignment expression found. Otherwise, gets or sets false.
SectionType
Indicates if it is a case statement or a default case.
Definition: SwitchLabel.cs:31
Representa a property type.
Definition: PropertyType.cs:34
UserType Class
Gets or sets the class type reference
override Object Visit(NullExpression node, Object obj)
Representa a method type.
Definition: MethodType.cs:37
Encapsulates a integer literal expression.
Encapsulates a declaration of a concrete field.
Encapsulates a constant definition.
Encapsulates the array expression to access the concrete position.
Symbol IdSymbol
Gets or sets the symbol of the identifier.
bool IsIntrospectiveInvocation
Gets or sets true the node is an Introspective Invocation. Otherwise, gets or sets false...
override Object Visit(Block node, Object obj)
override Object Visit(SwitchLabel node, Object obj)
override Object Accept(Visitor v, Object o)
Accept method of a concrete visitor.
static IntType Instance
Gets the unique instance of IntType
Definition: IntType.cs:57
Block FinallyBlock
Gets the statements executed in Finally block. if there is no finally statementes can be null ...
Expression ThirdOperand
Gets the third operand of the ternary expression
TypeExpression CastType
Gets or sets the type to convert the expression
Encapsulates a Move instruction to use in SSA algorithm
IList< TypeExpression > TypeSet
Gets the list of type expressions
Definition: UnionType.cs:57
Expression SecondOperand
Gets the second operand of the ternary expression
This class encapsulates several inherited attributes used in code generation process.
TypeExpression Substitution
Gets the substitution; null if it does not exist
override Object Visit(SingleIdentifierExpression node, Object obj)
AccessModifier MemberInfo
Gets or sets the attribute information of method type
Definition: PropertyType.cs:71
IdentifierMode IdMode
Gets the mode to use de identifier.
override Object Visit(NewArrayExpression node, Object obj)
Expression FirstOperand
Gets the first operand of the binary expression
override Object Visit(CastExpression node, Object obj)
override Object Visit(ArrayAccessExpression node, Object obj)
string Identifier
Gets the name name.
bool SearchParam(string param)
Searches the specified param in the method parameter list.
Represents a class type.
Definition: ClassType.cs:35
override Object Visit(FieldDefinition node, Object obj)
Representa a field type.
Definition: FieldType.cs:37
Encapsulates a Throw statement of our programming languages.
override Object Visit(ArithmeticExpression node, Object obj)
SingleIdentifierExpression FieldName
Gets the name to the field.
virtual TypeExpression ILTypeExpression
Gets the type expression to use in code generation.
Definition: Expression.cs:98
List< Modifier > ModifiersInfo
Gets the modifiers information used to obtain its type
override Object Visit(WhileStatement node, Object obj)
override Object Visit(Definition node, Object obj)
TypeExpression GetParameter(int index)
Gets the type expression of the specific parameter
Definition: MethodType.cs:202
Expression Expression
Gets the expression to access a field.
Statement GetStatementElement(int index)
Gets the element stored in the specified index.
Definition: Block.cs:159
List< MoveStatement > AfterCondition
Encapsulates a new expression.
virtual object AcceptOperation(TypeSystemOperation op, object arg)
Encapsulates a definition of a concrete class.
Expression Expression
Gets the expression to convert.
override Object Visit(DoStatement node, Object obj)
TypeExpression TypeExpr
Gets or sets the type of the declaration
Definition: Declaration.cs:63
Encapsulates a Switch statement of our programming languages.
static TemporalVariablesTable Instance
Gets the unique instance of TemporalVariablesTable
override Object Visit(BoolLiteralExpression node, Object obj)
override Object Visit(InterfaceDefinition node, Object obj)
override Object Accept(Visitor v, Object o)
Accept method of a concrete visitor.