Esempio n. 1
0
 // when <expr>
 //   generates into:
 //   RubyOps.IsTrue(<expr>) if the case has no value, otherise:
 //   RubyOps.IsTrue(Call("===", <expr>, <value>))
 private static MSA.Expression /*!*/ MakeTest(AstGenerator /*!*/ gen, MSA.Expression /*!*/ expr, MSA.Expression value)
 {
     if (value != null)
     {
         expr = CallSiteBuilder.InvokeMethod(gen.Context, "===", RubyCallSignature.WithScope(1),
                                             gen.CurrentScopeVariable,
                                             expr,
                                             value
                                             );
     }
     return(AstFactory.IsTrue(expr));
 }
Esempio n. 2
0
 // when <expr>
 //   generates into:
 //   RubyOps.IsTrue(<expr>) if the case has no value, otherise:
 //   RubyOps.IsTrue(InvokeMember("===", <expr>, <value>))
 private static MSA.Expression /*!*/ MakeTest(AstGenerator /*!*/ gen, MSA.Expression /*!*/ expr, MSA.Expression /*!*/ value)
 {
     if (value != null)
     {
         // InvokeMember("===", <expr>, <value>)
         expr = Ast.Dynamic(RubyCallAction.Make("===", RubyCallSignature.WithScope(1)), typeof(object),
                            gen.CurrentScopeVariable,
                            expr,
                            value
                            );
     }
     return(AstFactory.IsTrue(expr));
 }
        public void OverloadResolution_Block()
        {
            var t = GetType();

            var gse   = new GlobalScopeExtension(Context, new Scope(), new object(), true);
            var scope = new RubyTopLevelScope(gse, null, new SymbolDictionary());
            var proc  = new Proc(ProcKind.Proc, null, scope, new BlockDispatcher0((x, y) => null, BlockSignatureAttributes.None));

            var scopeArg    = new MetaObject(Ast.Constant(proc.LocalScope), Restrictions.Empty, proc.LocalScope);
            var contextArg  = new MetaObject(Ast.Constant(Context), Restrictions.Empty, Context);
            var instanceInt = new MetaObject(Ast.Constant(1), Restrictions.Empty, 1);
            var str         = "foo";
            var instanceStr = new MetaObject(Ast.Constant(str), Restrictions.Empty, str);
            var procArg     = new MetaObject(Ast.Constant(proc), Restrictions.Empty, proc);
            var nullArg     = new MetaObject(Ast.Constant(Ast.Constant(null)), Restrictions.Empty, null);

            var arguments = new[] {
                // 1.times
                new CallArguments(scopeArg, instanceInt, new MetaObject[0], RubyCallSignature.WithScope(0)),
                // 1.times &nil
                new CallArguments(scopeArg, instanceInt, new[] { nullArg }, RubyCallSignature.WithScopeAndBlock(0)),
                // 1.times &p
                new CallArguments(contextArg, instanceInt, new[] { procArg }, RubyCallSignature.WithBlock(0)),
                // obj.times &p
                new CallArguments(contextArg, instanceStr, new[] { procArg }, RubyCallSignature.WithBlock(0)),
            };

            var results = new[] {
                "Times2",
                "Times1",
                "Times3",
                "Times4",
            };

            for (int i = 0; i < arguments.Length; i++)
            {
                var bindingTarget = RubyMethodGroupInfo.ResolveOverload("times", new[] {
                    t.GetMethod("Times1"),
                    t.GetMethod("Times2"),
                    t.GetMethod("Times3"),
                    t.GetMethod("Times4"),
                }, arguments[i], true, false);

                Assert(bindingTarget.Success);
                Assert(bindingTarget.Method.Name == results[i]);
            }
        }
        public void OverloadResolution_Block1()
        {
            var scope = Context.EmptyScope;
            var proc  = new Proc(ProcKind.Proc, null, scope, new BlockDispatcher0(BlockSignatureAttributes.None, null, 0).
                                 SetMethod(new BlockCallTarget0((x, y) => null)));

            var arguments = new[] {
                // 1.times
                new CallArguments(Context, MO(scope), new[] { MO(1) }, RubyCallSignature.WithScope(0)),
                // 1.times &nil
                new CallArguments(Context, MO(scope), new[] { MO(1), MO(null) }, RubyCallSignature.WithScopeAndBlock(0)),
                // 1.times &p
                new CallArguments(Context, MO(1), new[] { MO(proc) }, RubyCallSignature.WithBlock(0)),
                // obj.times &p
                new CallArguments(Context, MO("foo"), new[] { MO(proc) }, RubyCallSignature.WithBlock(0)),
            };

            var results = new[] {
                "Times2",
                "Times1",
                "Times3",
                "Times4",
            };

            var metaBuilder = new MetaObjectBuilder(null);

            for (int i = 0; i < arguments.Length; i++)
            {
                RubyOverloadResolver resolver;

                var methods = GetStaticMethodsStartingWith(typeof(OverloadsWithBlock), "Times");

                var bindingTarget = RubyMethodGroupInfo.ResolveOverload(
                    metaBuilder, arguments[i], "times", methods, SelfCallConvention.SelfIsParameter,
                    false, out resolver
                    );

                Assert(bindingTarget.Success);
                Assert(bindingTarget.Overload.Name == results[i]);
            }
        }
Esempio n. 5
0
 // when <expr>
 //   generates into:
 //   RubyOps.IsTrue(<expr>) if the case has no value, otherise:
 //   RubyOps.IsTrue(Call("===", <expr>, <value>))
 private static MSA.Expression /*!*/ MakeTest(AstGenerator /*!*/ gen, Expression /*!*/ expr, MSA.Expression value)
 {
     MSA.Expression transformedExpr = expr.TransformRead(gen);
     if (expr is SplattedArgument)
     {
         if (value != null)
         {
             return(Methods.ExistsUnsplatCompare.OpCall(
                        Ast.Constant(CallSite <Func <CallSite, object, object, object> > .Create(
                                         RubyCallAction.Make(gen.Context, "===", RubyCallSignature.WithImplicitSelf(2))
                                         )),
                        AstUtils.LightDynamic(ExplicitTrySplatAction.Make(gen.Context), transformedExpr),
                        AstUtils.Box(value)
                        ));
         }
         else
         {
             return(Methods.ExistsUnsplat.OpCall(
                        AstUtils.LightDynamic(ExplicitTrySplatAction.Make(gen.Context), transformedExpr)
                        ));
         }
     }
     else
     {
         if (value != null)
         {
             return(AstFactory.IsTrue(
                        CallSiteBuilder.InvokeMethod(gen.Context, "===", RubyCallSignature.WithScope(1),
                                                     gen.CurrentScopeVariable,
                                                     transformedExpr,
                                                     value
                                                     )
                        ));
         }
         else
         {
             return(AstFactory.IsTrue(transformedExpr));
         }
     }
 }
Esempio n. 6
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
                       ));
        }
Esempio n. 7
0
        internal MSA.Expression <T> /*!*/ Transform <T>(AstGenerator /*!*/ gen)
        {
            Debug.Assert(gen != null);

            ScopeBuilder scope = DefineLocals();

            MSA.ParameterExpression[] parameters;
            MSA.ParameterExpression   selfVariable;
            MSA.ParameterExpression   runtimeScopeVariable;
            MSA.ParameterExpression   blockParameter;

            if (gen.CompilerOptions.FactoryKind == TopScopeFactoryKind.None ||
                gen.CompilerOptions.FactoryKind == TopScopeFactoryKind.ModuleEval)
            {
                parameters = new MSA.ParameterExpression[4];

                runtimeScopeVariable = 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");
            }
            else
            {
                parameters = new MSA.ParameterExpression[2];

                runtimeScopeVariable = parameters[0] = Ast.Parameter(typeof(RubyScope), "#scope");
                selfVariable         = parameters[1] = Ast.Parameter(typeof(object), "#self");

                blockParameter = null;
            }

            gen.EnterSourceUnit(
                scope,
                selfVariable,
                runtimeScopeVariable,
                blockParameter,
                gen.CompilerOptions.TopLevelMethodName, // method name for blocks
                null                                    // parameters for super calls
                );

            MSA.Expression body;

            if (_statements.Count > 0)
            {
                if (gen.PrintInteractiveResult)
                {
                    var resultVariable = scope.DefineHiddenVariable("#result", typeof(object));

                    var epilogue = Methods.PrintInteractiveResult.OpCall(runtimeScopeVariable,
                                                                         AstUtils.LightDynamic(ConvertToSAction.Make(gen.Context), typeof(MutableString),
                                                                                               CallSiteBuilder.InvokeMethod(gen.Context, "inspect", RubyCallSignature.WithScope(0),
                                                                                                                            gen.CurrentScopeVariable, resultVariable
                                                                                                                            )
                                                                                               )
                                                                         );

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

                // TODO:
                var exceptionVariable = Ast.Parameter(typeof(Exception), "#exception");
                body = AstUtils.Try(
                    body
                    ).Filter(exceptionVariable, Methods.TraceTopLevelCodeFrame.OpCall(runtimeScopeVariable, exceptionVariable),
                             Ast.Empty()
                             );
            }
            else
            {
                body = AstUtils.Constant(null);
            }

            // scope initialization:
            MSA.Expression prologue;
            switch (gen.CompilerOptions.FactoryKind)
            {
            case TopScopeFactoryKind.None:
            case TopScopeFactoryKind.ModuleEval:
                prologue = Methods.InitializeScopeNoLocals.OpCall(runtimeScopeVariable, EnterInterpretedFrameExpression.Instance);
                break;

            case TopScopeFactoryKind.Hosted:
            case TopScopeFactoryKind.File:
            case TopScopeFactoryKind.WrappedFile:
                prologue = Methods.InitializeScope.OpCall(
                    runtimeScopeVariable, scope.MakeLocalsStorage(), scope.GetVariableNamesExpression(),
                    EnterInterpretedFrameExpression.Instance
                    );
                break;

            case TopScopeFactoryKind.Main:
                prologue = Methods.InitializeScope.OpCall(
                    runtimeScopeVariable, scope.MakeLocalsStorage(), scope.GetVariableNamesExpression(),
                    EnterInterpretedFrameExpression.Instance
                    );
                if (_dataOffset >= 0)
                {
                    prologue = Ast.Block(
                        prologue,
                        Methods.SetDataConstant.OpCall(
                            runtimeScopeVariable,
                            gen.SourcePathConstant,
                            AstUtils.Constant(_dataOffset)
                            )
                        );
                }
                break;

            default:
                throw Assert.Unreachable;
            }

            // BEGIN blocks:
            if (gen.FileInitializers != null)
            {
                var b = new AstBlock();
                b.Add(prologue);
                b.Add(gen.FileInitializers);
                b.Add(body);
                body = b;
            }

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

            gen.LeaveSourceUnit();

            return(Ast.Lambda <T>(body, GetEncodedName(gen), parameters));
        }