// 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 postYield; if (gen.CompilerOptions.IsEval) { // eval: postYield = Methods.EvalYield.OpCall(gen.CurrentScopeVariable, bfcVariable, resultVariable); } else if (gen.CurrentBlock != null) { // block: postYield = Methods.BlockYield.OpCall(gen.CurrentScopeVariable, gen.CurrentBlock.BfcVariable, bfcVariable, resultVariable); } else { // method: postYield = Methods.MethodYield.OpCall(gen.CurrentScopeVariable, bfcVariable, resultVariable); } return new AstBlock { gen.DebugMarker("#RB: yield begin"), Ast.Assign(bfcVariable, Methods.CreateBfcForYield.OpCall(gen.MakeMethodBlockParameterRead())), Ast.Assign( resultVariable, (Arguments ?? Arguments.Empty).TransformToYield(gen, bfcVariable, gen.MakeMethodBlockParameterSelfRead()) ), AstUtils.IfThen(postYield, gen.Return(resultVariable)), gen.DebugMarker("#RB: yield end"), resultVariable }; }
internal sealed override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen) { string debugString = (IsSingletonDeclaration) ? "SINGLETON" : ((this is ClassDefinition) ? "CLASS" : "MODULE") + " " + QualifiedName.Name; ScopeBuilder outerLocals = gen.CurrentScope; // definition needs to take place outside the defined lexical scope: var definition = MakeDefinitionExpression(gen); var selfVariable = outerLocals.DefineHiddenVariable("#module", typeof(RubyModule)); var parentScope = gen.CurrentScopeVariable; // inner locals: ScopeBuilder scope = DefineLocals(); var scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyScope)); gen.EnterModuleDefinition( scope, selfVariable, scopeVariable, IsSingletonDeclaration ); // transform body: MSA.Expression transformedBody = Body.TransformRead(gen); // outer local: MSA.Expression resultVariable = outerLocals.DefineHiddenVariable("#result", transformedBody.Type); // begin with new scope // self = DefineModule/Class(... parent scope here ...) // <body> // end MSA.Expression result = new AstBlock { gen.DebugMarker(debugString), Ast.Assign(selfVariable, definition), scope.CreateScope( scopeVariable, Methods.CreateModuleScope.OpCall( scope.MakeLocalsStorage(), scope.GetVariableNamesExpression(), parentScope, selfVariable ), Ast.Block( Ast.Assign(resultVariable, transformedBody), AstUtils.Empty() ) ), gen.DebugMarker("END OF " + debugString), resultVariable }; gen.LeaveModuleDefinition(); return(result); }
// 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 )); }
internal sealed override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) { string debugString = (IsSingletonDeclaration) ? "SINGLETON" : ((this is ClassDefinition) ? "CLASS" : "MODULE") + " " + QualifiedName.Name; ScopeBuilder outerLocals = gen.CurrentScope; // definition needs to take place outside the defined lexical scope: var definition = MakeDefinitionExpression(gen); var selfVariable = outerLocals.DefineHiddenVariable("#module", typeof(RubyModule)); var parentScope = gen.CurrentScopeVariable; // inner locals: ScopeBuilder scope = DefineLocals(); var scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyScope)); gen.EnterModuleDefinition( scope, selfVariable, scopeVariable, IsSingletonDeclaration ); // transform body: MSA.Expression transformedBody = Body.TransformRead(gen); // outer local: MSA.Expression resultVariable = outerLocals.DefineHiddenVariable("#result", transformedBody.Type); // begin with new scope // self = DefineModule/Class(... parent scope here ...) // <body> // end MSA.Expression result = new AstBlock { gen.DebugMarker(debugString), Ast.Assign(selfVariable, definition), scope.CreateScope( scopeVariable, Methods.CreateModuleScope.OpCall( scope.MakeLocalsStorage(), scope.GetVariableNamesExpression(), parentScope, selfVariable ), Ast.Block( Ast.Assign(resultVariable, transformedBody), AstUtils.Empty() ) ), gen.DebugMarker("END OF " + debugString), resultVariable }; gen.LeaveModuleDefinition(); return result; }