/// <summary> /// Backwards compatible Convert for the old sites that need to flow CodeContext /// </summary> public static Expression/*!*/ Convert(Expression/*!*/ codeContext, PythonContext/*!*/ binder, Type/*!*/ type, ConversionResultKind resultKind, Expression/*!*/ target) { return Ast.Dynamic( binder.Convert(type, resultKind), type, target ); }
/// <summary> /// Used for conversions to bool /// </summary> private static Expression /*!*/ GetConvertByLengthBody(PythonContext /*!*/ state, Expression /*!*/ call) { Assert.NotNull(state, call); Expression callAsInt = call; if (call.Type != typeof(int)) { callAsInt = DynamicExpression.Dynamic( state.Convert(typeof(int), ConversionResultKind.ExplicitCast), typeof(int), call ); } var res = Expression.Parameter(typeof(int)); return(Ast.Block( new[] { res }, Ast.Assign(res, callAsInt), Ast.IfThen(Ast.LessThan(res, Ast.Constant(0)), Ast.Throw( Ast.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.ValueError)), Ast.Constant("__len__() should return >= 0"), Ast.NewArrayInit(typeof(object)) ) ) ), Ast.NotEqual(res, Ast.Constant(0)) )); }
/// <summary> /// Backwards compatible Convert for the old sites that need to flow CodeContext /// </summary> public static Expression /*!*/ Convert(Expression /*!*/ codeContext, PythonContext /*!*/ binder, Type /*!*/ type, ConversionResultKind resultKind, Expression /*!*/ target) { return(Ast.Dynamic( binder.Convert(type, resultKind), type, target )); }
/// <summary> /// Used for conversions to bool /// </summary> private static Expression /*!*/ GetConvertByLengthBody(PythonContext /*!*/ state, Expression /*!*/ call) { Assert.NotNull(state, call); Expression callAsInt = call; if (call.Type != typeof(int)) { callAsInt = DynamicExpression.Dynamic( state.Convert(typeof(int), ConversionResultKind.ExplicitCast), typeof(int), call ); } return(Ast.NotEqual(callAsInt, AstUtils.Constant(0))); }
private static DynamicExpression/*!*/ HashConvertToInt(PythonContext/*!*/ state, Expression/*!*/ expression) { return DynamicExpression.Dynamic( state.Convert( typeof(int), ConversionResultKind.ExplicitCast ), typeof(int), expression ); }
public override DynamicMetaObject/*!*/ MakeRule(DynamicMetaObjectBinder/*!*/ metaBinder, PythonContext/*!*/ binder, DynamicMetaObject/*!*/[]/*!*/ args) { DynamicMetaObject[] tupleArgs = Callable.GetTupleArguments(args); return Callable.CompleteRuleTarget(metaBinder, tupleArgs, delegate() { PythonTypeSlot indexSlot; if (args[1].GetLimitType() != typeof(Slice) && GetTypeAt(1).TryResolveSlot(binder.SharedContext, "__index__", out indexSlot)) { args[1] = new DynamicMetaObject( DynamicExpression.Dynamic( binder.Convert( typeof(int), ConversionResultKind.ExplicitCast ), typeof(int), DynamicExpression.Dynamic( binder.InvokeNone, typeof(object), AstUtils.Constant(binder.SharedContext), Binders.Get( AstUtils.Constant(binder.SharedContext), binder, typeof(object), "__index__", args[1].Expression ) ) ), BindingRestrictions.Empty ); return Callable.CompleteRuleTarget(metaBinder, tupleArgs, null); } return null; }); }
public override DynamicMetaObject/*!*/ MakeRule(DynamicMetaObjectBinder/*!*/ metaBinder, PythonContext/*!*/ binder, DynamicMetaObject/*!*/[]/*!*/ args) { // the semantics of simple slicing state that if the value // is less than 0 then the length is added to it. The default // for unprovided parameters are 0 and maxint. The callee // is responsible for ignoring out of range values but slicing // is responsible for doing this initial transformation. Debug.Assert(args.Length > 2); // index 1 and 2 should be our slice indexes, we might have another arg if we're a setter args = ArrayUtils.Copy(args); for (int i = 1; i < 3; i++) { args[i] = args[i].Restrict(args[i].GetLimitType()); if (args[i].GetLimitType() == typeof(MissingParameter)) { switch (i) { case 1: args[i] = new DynamicMetaObject(AstUtils.Constant(0), args[i].Restrictions); break; case 2: args[i] = new DynamicMetaObject(AstUtils.Constant(Int32.MaxValue), args[i].Restrictions); break; } } else if (args[i].GetLimitType() == typeof(int)) { args[i] = MakeIntTest(args[0], args[i]); } else if (args[i].GetLimitType().IsSubclassOf(typeof(Extensible<int>))) { args[i] = MakeIntTest( args[0], new DynamicMetaObject( Ast.Property( args[i].Expression, args[i].GetLimitType().GetProperty("Value") ), args[i].Restrictions ) ); } else if (args[i].GetLimitType() == typeof(BigInteger)) { args[i] = MakeBigIntTest(args[0], args[i]); } else if (args[i].GetLimitType().IsSubclassOf(typeof(Extensible<BigInteger>))) { args[i] = MakeBigIntTest(args[0], new DynamicMetaObject(Ast.Property(args[i].Expression, args[i].GetLimitType().GetProperty("Value")), args[i].Restrictions)); } else if (args[i].GetLimitType() == typeof(bool)) { args[i] = new DynamicMetaObject( Ast.Condition(args[i].Expression, AstUtils.Constant(1), AstUtils.Constant(0)), args[i].Restrictions ); } else { // this type defines __index__, otherwise we'd have an ItemBuilder constructing a slice args[i] = MakeIntTest(args[0], new DynamicMetaObject( DynamicExpression.Dynamic( binder.Convert( typeof(int), ConversionResultKind.ExplicitCast ), typeof(int), DynamicExpression.Dynamic( binder.InvokeNone, typeof(object), AstUtils.Constant(binder.SharedContext), Binders.Get( AstUtils.Constant(binder.SharedContext), binder, typeof(object), "__index__", Ast.Convert( args[i].Expression, typeof(object) ) ) ) ), args[i].Restrictions ) ); } } if (_lengthVar != null) { // we need the length which we should only calculate once, calculate and // store it in a temporary. Note we only calculate the length if we'll DynamicMetaObject res = Callable.CompleteRuleTarget(metaBinder, args, null); return new DynamicMetaObject( Ast.Block( new ParameterExpression[] { _lengthVar }, Ast.Assign(_lengthVar, AstUtils.Constant(null, _lengthVar.Type)), res.Expression ), res.Restrictions ); } return Callable.CompleteRuleTarget(metaBinder, args, null); }
/// <summary> /// Used for conversions to bool /// </summary> private static Expression/*!*/ GetConvertByLengthBody(PythonContext/*!*/ state, Expression/*!*/ call) { Assert.NotNull(state, call); Expression callAsInt = call; if (call.Type != typeof(int)) { callAsInt = Ast.Dynamic( state.Convert(typeof(int), ConversionResultKind.ExplicitCast), typeof(int), call ); } return Ast.NotEqual(callAsInt, AstUtils.Constant(0)); }