// 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)); }
// 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]); } }
// 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)); } } }
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 )); }
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)); }