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); }
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); }