// see Ruby Language.doc/Runtime/Control Flow Implementation/Yield
internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) {
MSA.Expression bfcVariable = gen.CurrentScope.DefineHiddenVariable("#yielded-bfc", typeof(BlockParam));
MSA.Expression resultVariable = gen.CurrentScope.DefineHiddenVariable("#result", typeof(object));
MSA.Expression evalUnwinder = gen.CurrentScope.DefineHiddenVariable("#unwinder", typeof(EvalUnwinder));
MSA.Expression postYield;
if (gen.CompilerOptions.IsEval) {
// eval:
postYield = Methods.EvalYield.OpCall(gen.CurrentRfcVariable, bfcVariable, resultVariable);
} else if (gen.CurrentBlock != null) {
// block:
postYield = Methods.BlockYield.OpCall(gen.CurrentRfcVariable, gen.CurrentBlock.BfcVariable, bfcVariable, resultVariable);
} else {
// method:
postYield = Methods.MethodYield.OpCall(gen.CurrentRfcVariable, bfcVariable, resultVariable);
}
return AstFactory.Block(
gen.DebugMarker("#RB: yield begin"),
Ast.Assign(bfcVariable, Methods.CreateBfcForYield.OpCall(gen.MakeMethodBlockParameterRead())),
Ast.Assign(resultVariable, (Arguments ?? Arguments.Empty).TransformToYield(gen, bfcVariable,
Ast.Property(AstUtils.Convert(gen.MakeMethodBlockParameterRead(), typeof(Proc)), Proc.SelfProperty)
)),
AstUtils.IfThen(postYield, gen.Return(resultVariable)),
gen.DebugMarker("#RB: yield end"),
resultVariable
);
}