Exemplo n.º 1
0
        public override void GenerateCode(ILCodeGenerator cg)
        {
            //creamos las variables locales
            LocalBuilder i      = cg.ILGenerator.DeclareLocal(typeof(int));
            LocalBuilder length = cg.ILGenerator.DeclareLocal(typeof(int));
            LocalBuilder array  = cg.ILGenerator.DeclareLocal(NodeInfo.Type.ILType);

            //creamos los label
            Label loopCondLabel = cg.ILGenerator.DefineLabel();
            Label loopEndLabel  = cg.ILGenerator.DefineLabel();

            //guardamos el label a donde vamos a saltar
            cg.EndLoopLabelStack.Push(loopEndLabel);

            //generamos la expresion de la longitud del array
            IndexExpression.GenerateCode(cg);

            //creamos el array
            cg.ILGenerator.Emit(OpCodes.Stloc, length);
            cg.ILGenerator.Emit(OpCodes.Ldloc, length);
            cg.ILGenerator.Emit(OpCodes.Newarr, NodeInfo.Type.ElementsType.ILType);
            cg.ILGenerator.Emit(OpCodes.Stloc, array);

            //i = 0
            cg.ILGenerator.Emit(OpCodes.Ldc_I4_0);
            cg.ILGenerator.Emit(OpCodes.Stloc, i);

            //condition del loop
            cg.ILGenerator.MarkLabel(loopCondLabel);

            cg.ILGenerator.Emit(OpCodes.Ldloc, i);
            cg.ILGenerator.Emit(OpCodes.Ldloc, length);

            //si no se cumple la condition, saltamos al fin del ciclo
            cg.ILGenerator.Emit(OpCodes.Clt);
            cg.ILGenerator.Emit(OpCodes.Brfalse, loopEndLabel);

            //asignamos el valor(array[i] = InitExpression.Value)
            cg.ILGenerator.Emit(OpCodes.Ldloc, array);
            cg.ILGenerator.Emit(OpCodes.Ldloc, i);

            //generamos el codigo de la expresion de inicializacion
            InitExpression.GenerateCode(cg);

            //guardamos el elemento
            cg.ILGenerator.Emit(OpCodes.Stelem, NodeInfo.Type.ElementsType.ILType);

            // Incrementar "i".
            cg.ILGenerator.Emit(OpCodes.Ldloc, i);
            cg.ILGenerator.Emit(OpCodes.Ldc_I4_1);
            cg.ILGenerator.Emit(OpCodes.Add);
            cg.ILGenerator.Emit(OpCodes.Stloc, i);
            cg.ILGenerator.Emit(OpCodes.Br, loopCondLabel);

            // Fin del ciclo.
            cg.ILGenerator.MarkLabel(loopEndLabel);

            //sacamos el label guardado
            cg.EndLoopLabelStack.Pop();

            cg.ILGenerator.Emit(OpCodes.Ldloc, array);
        }