Esempio n. 1
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
     );
 }
Esempio n. 2
0
        /// <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))
                       ));
        }
Esempio n. 3
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
                ));
 }
Esempio n. 4
0
        /// <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);
            }
Esempio n. 8
0
        /// <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));
        }