internal sealed override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen) { string debugString = (IsSingletonDeclaration) ? "SINGLETON" : ((this is ClassDeclaration) ? "CLASS" : "MODULE") + " " + QualifiedName.Name; ScopeBuilder outerLocals = gen.CurrentScope; // definition needs to take place outside the defined lexical scope: MSA.Expression definition = MakeDefinitionExpression(gen); MSA.Expression selfVariable = outerLocals.DefineHiddenVariable("#module", typeof(RubyModule)); MSA.Expression rfcVariable = gen.CurrentRfcVariable; MSA.Expression parentScope = gen.CurrentScopeVariable; // inner locals: ScopeBuilder scope = new ScopeBuilder(); MSA.Expression scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyScope)); gen.EnterModuleDefinition( scope, selfVariable, scopeVariable, IsSingletonDeclaration ); // first, transform locals defined within the module body: DefinedScope.TransformLocals(scope); // second, 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 = AstFactory.Block( gen.DebugMarker(debugString), Ast.Assign(selfVariable, definition), scope.CreateScope( Ast.Block( Ast.Assign(scopeVariable, Methods.CreateModuleScope.OpCall(scope.VisibleVariables(), parentScope, rfcVariable, selfVariable)), Ast.Assign(resultVariable, transformedBody), Ast.Empty() ) ), gen.DebugMarker("END OF " + debugString), resultVariable ); gen.LeaveModuleDefinition(); return(result); }
private ScopeBuilder /*!*/ DefineLocals(out AstParameters /*!*/ parameters) { parameters = new AstParameters( HiddenParameterCount + (_parameters.Mandatory != null ? _parameters.Mandatory.Count : 0) + (_parameters.Optional != null ? _parameters.Optional.Count : 0) + (_parameters.Array != null ? 1 : 0) ); int closureIndex = 0; int firstClosureParam = 1; parameters.Add(Ast.Parameter(typeof(object), "#self")); if (_parameters.Block != null) { parameters.Add(Ast.Parameter(typeof(Proc), _parameters.Block.Name)); _parameters.Block.SetClosureIndex(closureIndex++); } else { parameters.Add(Ast.Parameter(typeof(Proc), "#block")); firstClosureParam++; } if (_parameters.Mandatory != null) { foreach (var param in _parameters.Mandatory) { parameters.Add(Ast.Parameter(typeof(object), param.Name)); param.SetClosureIndex(closureIndex++); } } if (_parameters.Optional != null) { foreach (var lvalue in _parameters.Optional) { var param = (LocalVariable)lvalue.Left; parameters.Add(Ast.Parameter(typeof(object), param.Name)); param.SetClosureIndex(closureIndex++); } } if (_parameters.Array != null) { parameters.Add(Ast.Parameter(typeof(object), _parameters.Array.Name)); _parameters.Array.SetClosureIndex(closureIndex++); } // allocate closure slots for locals: int localCount = DefinedScope.AllocateClosureSlotsForLocals(closureIndex); return(new ScopeBuilder(parameters, firstClosureParam, localCount, null, DefinedScope)); }
private MSA.ParameterExpression[] /*!*/ DefineParameters(AstGenerator /*!*/ gen, ScopeBuilder /*!*/ scope) { // user defined locals/args: MSA.ParameterExpression[] parameters = DefinedScope.TransformParameters(_parameters, HiddenParameterCount); scope.AddVisibleParameters(parameters, HiddenParameterCount); parameters[0] = Ast.Parameter(typeof(object), "#self"); if (_parameters.Block != null) { // map user defined proc parameter to the special param #1: parameters[1] = _parameters.Block.TransformBlockParameterDefinition(); } else { parameters[1] = Ast.Parameter(typeof(Proc), "#block"); } return(parameters); }
private ScopeBuilder /*!*/ DefineLocals(out AstParameters /*!*/ parameters) { // Method signature: // <self>, &<block>, <leading-mandatory>, <trailing-mandatory>, <optional>, *<unsplat> parameters = new AstParameters( HiddenParameterCount + _parameters.Mandatory.Length + _parameters.Optional.Length + (_parameters.Unsplat != null ? 1 : 0) ); int closureIndex = 0; int firstClosureParam = 1; parameters.Add(Ast.Parameter(typeof(object), "#self")); if (_parameters.Block != null) { parameters.Add(Ast.Parameter(typeof(Proc), _parameters.Block.Name)); _parameters.Block.SetClosureIndex(closureIndex++); } else { parameters.Add(Ast.Parameter(typeof(Proc), "#block")); firstClosureParam++; } foreach (LeftValue lvalue in _parameters.Mandatory) { var param = lvalue as LocalVariable; if (param != null) { parameters.Add(Ast.Parameter(typeof(object), param.Name)); param.SetClosureIndex(closureIndex++); } else { // TODO: throw new NotSupportedException("TODO: compound parameters"); } } foreach (var lvalue in _parameters.Optional) { var param = (LocalVariable)lvalue.Left; parameters.Add(Ast.Parameter(typeof(object), param.Name)); param.SetClosureIndex(closureIndex++); } if (_parameters.Unsplat != null) { var unsplatLocal = (LocalVariable)_parameters.Unsplat; parameters.Add(Ast.Parameter(typeof(object), unsplatLocal.Name)); unsplatLocal.SetClosureIndex(closureIndex++); } // allocate closure slots for locals: int localCount = DefinedScope.AllocateClosureSlotsForLocals(closureIndex); return(new ScopeBuilder(parameters, firstClosureParam, localCount, null, DefinedScope)); }
private ScopeBuilder /*!*/ DefineLocals() { return(new ScopeBuilder(DefinedScope.AllocateClosureSlotsForLocals(0), null, DefinedScope)); }
private MSA.Expression /*!*/ TransformBody(AstGenerator /*!*/ gen, MSA.Expression /*!*/ methodDefinitionVariable) { string encodedName = gen.EncodeMethodName(_name, Location); ScopeBuilder scope = new ScopeBuilder(); MSA.Expression parentScope = gen.CurrentScopeVariable; MSA.ParameterExpression[] parameters = DefineParameters(gen, scope); MSA.Expression currentMethodVariable = scope.DefineHiddenVariable("#method", typeof(RubyMethodInfo)); MSA.Expression rfcVariable = scope.DefineHiddenVariable("#rfc", typeof(RuntimeFlowControl)); MSA.Expression scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyMethodScope)); MSA.Expression selfParameter = parameters[0]; MSA.Expression blockParameter = parameters[1]; gen.EnterMethodDefinition( scope, selfParameter, scopeVariable, blockParameter, rfcVariable, currentMethodVariable, _name, _parameters ); DefinedScope.TransformLocals(scope); MSA.ParameterExpression unwinder = scope.DefineHiddenVariable("#unwinder", typeof(MethodUnwinder)); MSA.Expression body = AstFactory.MakeUserMethodBody( gen, Location.End.Line, blockParameter, rfcVariable, unwinder, Ast.Block( Ast.Assign(currentMethodVariable, methodDefinitionVariable), Ast.Assign(scopeVariable, Methods.CreateMethodScope.OpCall( scope.VisibleVariables(), parentScope, currentMethodVariable, rfcVariable, selfParameter, blockParameter) ), _parameters.TransformOptionalsInitialization(gen), gen.TraceEnabled ? Methods.TraceMethodCall.OpCall(scopeVariable, Ast.Convert(Ast.Constant(gen.SourceUnit.Path), typeof(string)), Ast.Constant(Location.Start.Line)) : Ast.Empty(), Body.TransformResult(gen, ResultOperation.Return), Ast.Empty() ), ResultOperation.Return, (gen.Profiler != null) ? gen.Profiler.GetTickIndex(encodedName) : -1, (gen.Profiler != null) ? scope.DefineHiddenVariable("#stamp", typeof(long)) : null, gen.ReturnLabel ); body = gen.AddReturnTarget(scope.CreateScope(body)); gen.LeaveMethodDefinition(); return(CreateLambda( encodedName, parameters, body )); }