Example #1
0
 /// <summary>
 /// Backwards compatible Convert for the old sites that need to flow CodeContext
 /// </summary>
 public static Expression/*!*/ Convert(Expression/*!*/ codeContext, BinderState/*!*/ binder, Type/*!*/ type, ConversionResultKind resultKind, Expression/*!*/ target) {
     return Ast.Dynamic(
         binder.Convert(type, resultKind),
         type,
         target
     );
 }
Example #2
0
 public static DynamicMetaObjectBinder/*!*/ BinaryOperationRetType(BinderState/*!*/ state, PythonOperationKind operatorName, Type retType) {
     return new ComboBinder(
         new BinderMappingInfo(
             BinaryOperationBinder(state, operatorName),
             ParameterMappingInfo.Parameter(0),
             ParameterMappingInfo.Parameter(1)
         ),
         new BinderMappingInfo(
             state.Convert(retType, ConversionResultKind.ExplicitCast),
             ParameterMappingInfo.Action(0)
         )
     );
 }
Example #3
0
        /// <summary>
        /// Used for conversions to bool
        /// </summary>
        private static Expression/*!*/ GetConvertByLengthBody(BinderState/*!*/ 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));
        }
 private static DynamicExpression/*!*/ HashConvertToInt(BinderState/*!*/ state, Expression/*!*/ expression) {
     return Ast.Dynamic(
         state.Convert(
             typeof(int),
             ConversionResultKind.ExplicitCast
         ),
         typeof(int),
         expression
     );
 }
            public override DynamicMetaObject/*!*/ MakeRule(BinderState/*!*/ 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(
                                Ast.Dynamic(
                                    binder.Convert(
                                        typeof(int),
                                        ConversionResultKind.ExplicitCast
                                    ),
                                    typeof(int),
                                    Ast.Dynamic(
                                        binder.InvokeNone,
                                        typeof(object),
                                        AstUtils.Constant(binder.Context),
                                        Binders.Get(
                                            AstUtils.Constant(binder.Context),
                                            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(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(args, null);
            }
Example #6
0
        public static DynamicMetaObjectBinder/*!*/ InvokeAndConvert(BinderState/*!*/ state, int argCount, Type retType) {
            // +2 for the target object and CodeContext which InvokeBinder recevies
            ParameterMappingInfo[] args = new ParameterMappingInfo[argCount + 2];   
            for (int i = 0; i < argCount + 2; i++) {
                args[i] = ParameterMappingInfo.Parameter(i);
            }

            return new ComboBinder(
                new BinderMappingInfo(
                    state.Invoke(
                        new CallSignature(argCount)
                    ),
                    args
                ),
                new BinderMappingInfo(
                    state.Convert(retType, ConversionResultKind.ExplicitCast),
                    ParameterMappingInfo.Action(0)
                )
            );
        }
            public override DynamicMetaObject/*!*/ MakeRule(BinderState/*!*/ binder, DynamicMetaObject/*!*/[]/*!*/ args) {
                DynamicMetaObject[] tupleArgs = Callable.GetTupleArguments(args);
                return Callable.CompleteRuleTarget(tupleArgs, delegate() {
                    PythonTypeSlot indexSlot;
                    if (args[1].GetLimitType() != typeof(Slice) && GetTypeAt(1).TryResolveSlot(binder.Context, Symbols.Index, out indexSlot)) {
                        args[1] = new DynamicMetaObject(
                            Ast.Dynamic(
                                binder.Convert(
                                    typeof(int),
                                    ConversionResultKind.ExplicitCast
                                ),
                                typeof(int),
                                Ast.Dynamic(
                                    binder.InvokeNone,
                                    typeof(object),
                                    AstUtils.Constant(binder.Context),
                                    Binders.Get(
                                        AstUtils.Constant(binder.Context),
                                        binder,
                                        typeof(object),
                                        "__index__",
                                        args[1].Expression
                                    )
                                )
                            ),
                            BindingRestrictions.Empty
                        );

                        return Callable.CompleteRuleTarget(tupleArgs, null);
                    }
                    return null;
                });
            }