Exemplo n.º 1
0
        internal MSA.Expression <T> /*!*/ Transform <T>(AstGenerator /*!*/ gen)
        {
            Debug.Assert(gen != null);

            ScopeBuilder scope = new ScopeBuilder();

            MSA.ParameterExpression[] parameters;
            MSA.Expression            selfVariable;
            MSA.Expression            rfcVariable;
            MSA.Expression            parentScope;
            MSA.Expression            language;
            MSA.Expression            runtimeScopeVariable;
            MSA.Expression            moduleVariable;
            MSA.Expression            blockParameter;
            MSA.Expression            currentMethodVariable;

            if (gen.CompilerOptions.IsEval)
            {
                parameters = new MSA.ParameterExpression[6];

                parameters[0]         = Ast.Parameter(typeof(RubyScope), "#scope");
                selfVariable          = parameters[1] = Ast.Parameter(typeof(object), "#self");
                parameters[2]         = Ast.Parameter(typeof(RubyModule), "#module");
                blockParameter        = parameters[3] = Ast.Parameter(typeof(Proc), "#block");
                currentMethodVariable = parameters[4] = Ast.Parameter(typeof(RubyMethodInfo), "#method");
                rfcVariable           = parameters[5] = Ast.Parameter(typeof(RuntimeFlowControl), "#rfc");

                if (gen.CompilerOptions.IsModuleEval)
                {
                    runtimeScopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyScope));
                    parentScope          = parameters[0];
                    moduleVariable       = parameters[2];
                }
                else
                {
                    runtimeScopeVariable = parameters[0];
                    moduleVariable       = null;
                    parentScope          = null;
                }

                language = null;
            }
            else
            {
                parameters  = new MSA.ParameterExpression[2];
                parentScope = parameters[0] = Ast.Parameter(typeof(Scope), "#globalScope");
                language    = parameters[1] = Ast.Parameter(typeof(LanguageContext), "#language");

                selfVariable          = scope.DefineHiddenVariable("#self", typeof(object));
                rfcVariable           = scope.DefineHiddenVariable("#rfc", typeof(RuntimeFlowControl));
                runtimeScopeVariable  = scope.DefineHiddenVariable("#scope", typeof(RubyScope));
                blockParameter        = null;
                currentMethodVariable = null;
                moduleVariable        = null;
            }

            gen.EnterSourceUnit(
                scope,
                selfVariable,
                runtimeScopeVariable,
                blockParameter,
                rfcVariable,
                currentMethodVariable,
                gen.CompilerOptions.TopLevelMethodName, // method name
                null                                    // parameters
                );

            _definedScope.TransformLocals(scope);

            MSA.Expression scopeFactoryCall;

            if (gen.CompilerOptions.IsEval)
            {
                if (gen.CompilerOptions.IsModuleEval)
                {
                    scopeFactoryCall = Methods.CreateModuleEvalScope.OpCall(
                        scope.VisibleVariables(), parentScope, selfVariable, moduleVariable
                        );
                }
                else
                {
                    scopeFactoryCall = null;
                }
            }
            else if (!gen.CompilerOptions.IsIncluded)
            {
                scopeFactoryCall = Methods.CreateMainTopLevelScope.OpCall(scope.VisibleVariables(), parentScope, language, selfVariable, rfcVariable,
                                                                          Ast.Constant(gen.SourceUnit.Path, typeof(string)), Ast.Constant(_dataOffset));
            }
            else if (gen.CompilerOptions.IsWrapped)
            {
                scopeFactoryCall = Methods.CreateWrappedTopLevelScope.OpCall(scope.VisibleVariables(), parentScope, language, selfVariable, rfcVariable);
            }
            else
            {
                scopeFactoryCall = Methods.CreateTopLevelScope.OpCall(scope.VisibleVariables(), parentScope, language, selfVariable, rfcVariable);
            }

            MSA.Expression prologue, body;

            if (scopeFactoryCall != null)
            {
                prologue = Ast.Assign(runtimeScopeVariable, scopeFactoryCall);
            }
            else
            {
                prologue = null;
            }

            if (gen.SourceUnit.Kind == SourceCodeKind.InteractiveCode)
            {
                var resultVariable = scope.DefineHiddenVariable("#result", typeof(object));

                var epilogue = Methods.PrintInteractiveResult.OpCall(runtimeScopeVariable,
                                                                     Ast.Dynamic(ConvertToSAction.Instance, typeof(MutableString), gen.CurrentScopeVariable,
                                                                                 Ast.Dynamic(RubyCallAction.Make("inspect", RubyCallSignature.WithScope(0)), typeof(object),
                                                                                             gen.CurrentScopeVariable, resultVariable
                                                                                             )
                                                                                 )
                                                                     );

                body = gen.TransformStatements(prologue, _statements, epilogue, ResultOperation.Store(resultVariable));
            }
            else
            {
                body = gen.TransformStatements(prologue, _statements, ResultOperation.Return);
            }

            body = gen.AddReturnTarget(scope.CreateScope(body));
            gen.LeaveSourceUnit();

            return(Ast.Lambda <T>(
                       body,
                       RubyExceptionData.TopLevelMethodName,
                       parameters
                       ));
        }
Exemplo n.º 2
0
        internal override MSA.Expression /*!*/ Transform(AstGenerator /*!*/ gen)
        {
            MSA.Expression parentScope = gen.CurrentScopeVariable;
            ScopeBuilder   scope       = new ScopeBuilder();

            // define hidden parameters and RHS-placeholders (#1..#n will be used as RHS of a parallel assignment):
            MSA.Expression            blockParameter, selfParameter;
            MSA.ParameterExpression[] parameters = DefineParameters(out selfParameter, out blockParameter);

            MSA.Expression  scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyBlockScope));
            MSA.LabelTarget redoLabel     = Ast.Label();

            gen.EnterBlockDefinition(
                scope,
                blockParameter,
                selfParameter,
                scopeVariable,
                redoLabel
                );

            if (_definedScope != null)
            {
                _definedScope.TransformLocals(scope);
            }

            MSA.Expression          paramInit     = MakeParametersInitialization(gen, parameters);
            MSA.ParameterExpression blockUnwinder = scope.DefineHiddenVariable("#unwinder", typeof(BlockUnwinder));

            MSA.Expression loop = AstFactory.Infinite(null, redoLabel,
                                                      AstUtils.Try(
                                                          gen.TransformStatements(_body, ResultOperation.Return)
                                                          ).Catch(blockUnwinder,
                                                                  // redo:
                                                                  AstUtils.IfThen(Ast.Field(blockUnwinder, BlockUnwinder.IsRedoField), Ast.Continue(redoLabel)),

                                                                  // next:
                                                                  gen.Return(Ast.Field(blockUnwinder, BlockUnwinder.ReturnValueField))
                                                                  )
                                                      );

            if (gen.TraceEnabled)
            {
                int firstStatementLine = _body.Count > 0 ? _body[0].Location.Start.Line : Location.End.Line;
                int lastStatementLine  = _body.Count > 0 ? _body[_body.Count - 1].Location.End.Line : Location.End.Line;

                loop = Ast.TryFinally(
                    Ast.Block(
                        Methods.TraceBlockCall.OpCall(scopeVariable, blockParameter, Ast.Convert(Ast.Constant(gen.SourceUnit.Path), typeof(string)), Ast.Constant(firstStatementLine)),
                        loop
                        ),
                    Methods.TraceBlockReturn.OpCall(scopeVariable, blockParameter, Ast.Convert(Ast.Constant(gen.SourceUnit.Path), typeof(string)), Ast.Constant(lastStatementLine))
                    );
            }

            MSA.Expression body = Ast.Block(
                Ast.Assign(scopeVariable,
                           Methods.CreateBlockScope.OpCall(scope.VisibleVariables(), parentScope, blockParameter, selfParameter)
                           ),

                paramInit,

                loop,

                Ast.Empty()
                );

            body = gen.AddReturnTarget(scope.CreateScope(body));
            gen.LeaveBlockDefinition();

            int parameterCount = _parameters.LeftValues.Count;

            var attributes = _parameters.GetBlockSignatureAttributes();

            return(Methods.DefineBlock.OpCall(
                       gen.CurrentScopeVariable,
                       gen.CurrentRfcVariable,
                       gen.CurrentSelfVariable,
                       Ast.Lambda(
                           BlockDispatcher.GetDelegateType(parameterCount, attributes),
                           body,
                           gen.EncodeMethodName(gen.CurrentMethod.MethodName, Location),
                           new ReadOnlyCollection <MSA.ParameterExpression>(parameters)
                           ),
                       Ast.Constant(parameterCount),
                       Ast.Constant(attributes)
                       ));
        }