public override void GenCode(ICodeGenerator cg) { //Creamos los campos y asignamos los fieldBuilder a los simbolos var gen = cg.GetGenerator; var iterVar = cg.TypeBuilder.DefineField(IterationVar + "_" + Scope.Id, typeof(int), FieldAttributes.Static | FieldAttributes.Public); IterationInstr.Scope.MappingDeclaration <FieldSymbol>(IterationVar).FieldBuilder = iterVar; //Inicializamos la variable de iteracion InitValue.GenCode(cg); gen.Emit(OpCodes.Stsfld, iterVar); //Creamos una variable local y le asignamos el valor de la cota superior para usarlo en las repetidas iteraciones var upperBound = gen.DeclareLocal(typeof(int)); ConditionExp.GenCode(cg); gen.Emit(OpCodes.Stloc, upperBound); //Creamos los labels de inicio y fin del ciclo var startLoopLabel = gen.DefineLabel(); var endLoopLabel = gen.DefineLabel(); //Ponemos la etiqueta del final en la pila por si hay un break dentro del ciclo cg.LoopsEndLabels.Push(endLoopLabel); //Comprobamos la condicion del ciclo gen.MarkLabel(startLoopLabel); gen.Emit(OpCodes.Ldsfld, iterVar); gen.Emit(OpCodes.Ldloc, upperBound); gen.Emit(OpCodes.Bgt, endLoopLabel); //Generamos el cuerpo del For IterationInstr.GenCode(cg); //Aumentamos en 1 la variable de iteracion gen.Emit(OpCodes.Ldsfld, iterVar); gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Add); gen.Emit(OpCodes.Stsfld, iterVar); //Saltamos al chequeo de la condicion nuevamente gen.Emit(OpCodes.Br, startLoopLabel); //Se termina el ciclo y se quita la etiqueta de la pila gen.MarkLabel(endLoopLabel); cg.LoopsEndLabels.Pop(); }
public override void GenCode(ICodeGenerator cg) { var gen = cg.GetGenerator; var endLabel = gen.DefineLabel(); var loopLabel = gen.DefineLabel(); //ponemos en la pila la etiqueta de fin de ciclo por si necesitamos hacer break dentro del ciclo saber donde saltar cg.LoopsEndLabels.Push(endLabel); gen.MarkLabel(loopLabel); //Inicio del ciclo ConditionExp.GenCode(cg); gen.Emit(OpCodes.Brfalse, endLabel); //Si la condicion es false terminamos el ciclo IterationInstr.GenCode(cg); gen.Emit(OpCodes.Br, loopLabel); gen.MarkLabel(endLabel); cg.LoopsEndLabels.Pop();//Retiramos la etiqueta de la pila }