Ejemplo n.º 1
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            Initializer?.Compile(context, il);

            var start = il.DefineLabel();
            var end   = il.DefineLabel();

            il.MarkLabel(start);

            if (Predicate != null)
            {
                Predicate.Compile(context, il);
            }
            else
            {
                il.Emit(EmitOpCodes.Ldc_I4_1);
            }

            il.Emit(EmitOpCodes.Brfalse, end);

            Body.Compile(context, il);
            Incrementor?.Compile(context, il);
            il.Emit(EmitOpCodes.Br, start);

            il.MarkLabel(end);
        }
Ejemplo n.º 2
0
        internal override IEnumerable <Instruction> Compile()
        {
            List <Instruction> instructions = new List <Instruction>();

            instructions.AddRange(Initializer?.Compile() ?? new Instruction[0]);

            List <Instruction> bodyInstructions = Body.Compile().ToList();

            bodyInstructions.AddRange(Incrementor?.Compile() ?? new Instruction[0]);



            List <Instruction> check;

            if (Condition == null)
            {
                // No condition? We're in a forever loop
                check = new List <Instruction>();
            }
            else
            {
                check = Condition.Compile().ToList();
                check.AddRange(
                    Compiler.CompileImplicitConversion(
                        Condition.GetKnownType(),
                        RedwoodType.GetForCSharpType(typeof(bool))
                        )
                    );
                check.Add(new ConditionalJumpInstruction(2));
                // Next instruction (1) + Body + Increment + Jump instruction (1)
                check.Add(new JumpInstruction(bodyInstructions.Count + 2));
            }

            // Jump back to the beginning of the loop
            bodyInstructions.Add(new JumpInstruction(-(bodyInstructions.Count + check.Count)));

            instructions.AddRange(check);
            instructions.AddRange(bodyInstructions);
            return(instructions);
        }