public PythonStructureMember(StructureMember member, PythonType type, PythonStructure structure) : base(member) { _member = member; _type = type; _structure = structure; _containedInStructure = member.Parent.Implementation as PythonStructure; }
public override bool IsValid(PythonType type) { return(true); }
public FastSlotGet(Type type, PythonTypeSlot slot, PythonType owner) { _type = type; _slot = slot; _owner = owner; }
/// <summary> /// Tries to get a MethodBinder associated with the slot for the specified type. /// /// If a method is found the binder is set and true is returned. /// If nothing is found binder is null and true is returned. /// If something other than a method is found false is returned. /// /// TODO: Remove rop /// </summary> internal static bool TryGetBinder(PythonContext /*!*/ state, DynamicMetaObject /*!*/[] /*!*/ types, string op, string rop, out SlotOrFunction /*!*/ res, out PythonType declaringType) { declaringType = null; DynamicMetaObject xType = types[0]; BuiltinFunction xBf; if (!BindingHelpers.TryGetStaticFunction(state, op, xType, out xBf)) { res = SlotOrFunction.Empty; return(false); } xBf = CheckAlwaysNotImplemented(xBf); BindingTarget bt; DynamicMetaObject binder; DynamicMetaObject yType = null; BuiltinFunction yBf = null; if (types.Length > 1) { yType = types[1]; if (!BindingHelpers.IsSubclassOf(xType, yType) && !BindingHelpers.TryGetStaticFunction(state, rop, yType, out yBf)) { res = SlotOrFunction.Empty; return(false); } yBf = CheckAlwaysNotImplemented(yBf); } if (yBf == xBf) { yBf = null; } else if (yBf != null && BindingHelpers.IsSubclassOf(yType, xType)) { xBf = null; } var mc = new PythonOverloadResolver( state.Binder, types, new CallSignature(types.Length), AstUtils.Constant(state.SharedContext) ); if (xBf == null) { if (yBf == null) { binder = null; bt = null; } else { declaringType = DynamicHelpers.GetPythonTypeFromType(yBf.DeclaringType); binder = state.Binder.CallMethod(mc, yBf.Targets, BindingRestrictions.Empty, null, PythonNarrowing.None, PythonNarrowing.BinaryOperator, out bt); } } else { if (yBf == null) { declaringType = DynamicHelpers.GetPythonTypeFromType(xBf.DeclaringType); binder = state.Binder.CallMethod(mc, xBf.Targets, BindingRestrictions.Empty, null, PythonNarrowing.None, PythonNarrowing.BinaryOperator, out bt); } else { List <MethodBase> targets = new List <MethodBase>(); targets.AddRange(xBf.Targets); foreach (MethodBase mb in yBf.Targets) { if (!ContainsMethodSignature(targets, mb)) { targets.Add(mb); } } binder = state.Binder.CallMethod(mc, targets.ToArray(), BindingRestrictions.Empty, null, PythonNarrowing.None, PythonNarrowing.BinaryOperator, out bt); foreach (MethodBase mb in yBf.Targets) { if (bt.Overload.ReflectionInfo == mb) { declaringType = DynamicHelpers.GetPythonTypeFromType(yBf.DeclaringType); break; } } if (declaringType == null) { declaringType = DynamicHelpers.GetPythonTypeFromType(xBf.DeclaringType); } } } if (binder != null) { res = new SlotOrFunction(bt, binder); } else { res = SlotOrFunction.Empty; } Debug.Assert(res != null); return(true); }
public static object CreateCFunction(IntPtr address, PythonType type) { return(type.CreateInstance(type.Context.SharedContext, address)); }
private static bool IsPointer(PythonType pt) { SimpleType simpleType; return(pt is PointerType || ((simpleType = pt as SimpleType) != null && (simpleType._type == SimpleTypeKind.Pointer || simpleType._type == SimpleTypeKind.CharPointer || simpleType._type == SimpleTypeKind.WCharPointer))); }
public static object OverloadedNewClsKW(CodeContext context, BuiltinFunction overloads\u00F8, PythonType type\u00F8, [ParamDictionary] IDictionary <object, object> kwargs\u00F8, params object[] args\u00F8) { if (type\u00F8 == null) { throw PythonOps.TypeError("__new__ expected type object, got {0}", PythonOps.Repr(context, DynamicHelpers.GetPythonType(type\u00F8))); } if (args\u00F8 == null) { args\u00F8 = new object[1]; } return(overloads\u00F8.Call(context, null, null, args\u00F8, kwargs\u00F8)); }
internal static void CheckNewArgs(CodeContext context, IDictionary <object, object> dict, object[] args, PythonType pt) { if (((args != null && args.Length > 0) || (dict != null && dict.Count > 0))) { bool hasObjectInit = pt.HasObjectInit(context); bool hasObjectNew = pt.HasObjectNew(context); if (hasObjectInit) { throw PythonOps.TypeError(ObjectNewNoParameters); } else if (!hasObjectNew && !hasObjectInit) { PythonOps.Warn(context, PythonExceptions.DeprecationWarning, ObjectNewNoParameters); } } }
public static object classmeth(PythonType cls, [ParamDictionary] IDictionary <object, object> dict, params object[] args) { return(PythonTuple.MakeTuple(cls, PythonTuple.MakeTuple(args), dict)); }
public static object __new__(CodeContext context, PythonType cls, object x) { Extensible <string> es; if (x is string) { return(ReturnObject(context, cls, ParseBigIntegerSign((string)x, 10))); } else if ((es = x as Extensible <string>) != null) { object value; if (PythonTypeOps.TryInvokeUnaryOperator(context, x, "__long__", out value)) { return(ReturnObject(context, cls, (BigInteger)value)); } return(ReturnObject(context, cls, ParseBigIntegerSign(es.Value, 10))); } if (x is double) { return(ReturnObject(context, cls, DoubleOps.__long__((double)x))); } if (x is int) { return(ReturnObject(context, cls, (BigInteger)(int)x)); } if (x is BigInteger) { return(ReturnObject(context, cls, x)); } if (x is Complex) { throw PythonOps.TypeError("can't convert complex to long; use long(abs(z))"); } if (x is decimal) { return(ReturnObject(context, cls, (BigInteger)(decimal)x)); } object result; int intRes; BigInteger bigintRes; if (PythonTypeOps.TryInvokeUnaryOperator(context, x, "__long__", out result) && !Object.ReferenceEquals(result, NotImplementedType.Value)) { if (result is int || result is BigInteger || result is Extensible <int> || result is Extensible <BigInteger> ) { return(ReturnObject(context, cls, result)); } else { throw PythonOps.TypeError("__long__ returned non-long (type {0})", PythonTypeOps.GetName(result)); } } else if (PythonOps.TryGetBoundAttr(context, x, "__trunc__", out result)) { result = PythonOps.CallWithContext(context, result); if (Converter.TryConvertToInt32(result, out intRes)) { return(ReturnObject(context, cls, (BigInteger)intRes)); } else if (Converter.TryConvertToBigInteger(result, out bigintRes)) { return(ReturnObject(context, cls, bigintRes)); } else { throw PythonOps.TypeError("__trunc__ returned non-Integral (type {0})", PythonTypeOps.GetName(result)); } } throw PythonOps.TypeError("long() argument must be a string or a number, not '{0}'", DynamicHelpers.GetPythonType(x).Name); }
internal static DynamicMetaObject FallbackWorker(PythonContext context, DynamicMetaObject /*!*/ self, DynamicMetaObject /*!*/ codeContext, string name, GetMemberOptions options, DynamicMetaObjectBinder action, DynamicMetaObject errorSuggestion) { if (self.NeedsDeferral()) { return(action.Defer(self)); } PythonOverloadResolverFactory resolverFactory = new PythonOverloadResolverFactory(context.Binder, codeContext.Expression); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "FallbackGet"); bool isNoThrow = ((options & GetMemberOptions.IsNoThrow) != 0) ? true : false; Type limitType = self.GetLimitType(); if (limitType == typeof(DynamicNull) || PythonBinder.IsPythonType(limitType)) { // look up in the PythonType so that we can // get our custom method names (e.g. string.startswith) PythonType argType = DynamicHelpers.GetPythonTypeFromType(limitType); // if the name is defined in the CLS context but not the normal context then // we will hide it. if (argType.IsHiddenMember(name)) { DynamicMetaObject baseRes = PythonContext.GetPythonContext(action).Binder.GetMember( name, self, resolverFactory, isNoThrow, errorSuggestion ); Expression failure = GetFailureExpression(limitType, self, name, isNoThrow, action); return(BindingHelpers.FilterShowCls(codeContext, action, baseRes, failure)); } } var res = context.Binder.GetMember(name, self, resolverFactory, isNoThrow, errorSuggestion); if (res is ErrorMetaObject) { // see if we can bind to any extension methods... var codeCtx = (CodeContext)codeContext.Value; var extMethods = codeCtx.ModuleContext.ExtensionMethods; if (extMethods != null) { // try again w/ the extension method binder res = extMethods.GetBinder(context).GetMember(name, self, resolverFactory, isNoThrow, errorSuggestion); } // and add any restrictions (we need an empty restriction even if it's an error so later adds work) res = new DynamicMetaObject( res.Expression, res.Restrictions.Merge(extMethods.GetRestriction(codeContext.Expression)) ); } // Default binder can return something typed to boolean or int. // If that happens, we need to apply Python's boxing rules. if (res.Expression.Type.IsValueType()) { res = new DynamicMetaObject( AstUtils.Convert(res.Expression, typeof(object)), res.Restrictions ); } return(res); }
internal static ValidationInfo /*!*/ GetValidationInfo(DynamicMetaObject /*!*/ tested, PythonType type) { return(new ValidationInfo( Ast.AndAlso( Ast.TypeEqual(tested.Expression, type.UnderlyingSystemType), CheckTypeVersion( AstUtils.Convert(tested.Expression, type.UnderlyingSystemType), type.Version ) ) )); }
public static object __new__(CodeContext context, PythonType cls, [Optional] object?real, [Optional] object?imag) { if (real == null) { throw PythonOps.TypeError($"complex() first argument must be a string or a number, not '{PythonTypeOps.GetName(real)}'"); } if (imag == null) { throw PythonOps.TypeError($"complex() second argument must be a number, not '{PythonTypeOps.GetName(real)}'"); } Complex imag2; if (imag is Missing) { imag2 = Complex.Zero; } else { if (real is string) { throw PythonOps.TypeError("complex() can't take second arg if first is a string"); } if (imag is string) { throw PythonOps.TypeError("complex() second arg can't be a string"); } if (!Converter.TryConvertToComplex(imag, out imag2)) { throw PythonOps.TypeError($"complex() second argument must be a number, not '{PythonTypeOps.GetName(real)}'"); } } Complex real2; if (real is Missing) { real2 = Complex.Zero; } else if (real is string) { real2 = LiteralParser.ParseComplex((string)real); } else if (real is Extensible <string> ) { real2 = LiteralParser.ParseComplex(((Extensible <string>)real).Value); } else if (real is Complex) { if (imag is Missing && cls == TypeCache.Complex) { return(real); } else { real2 = (Complex)real; } } else if (!Converter.TryConvertToComplex(real, out real2)) { throw PythonOps.TypeError($"complex() first argument must be a string or a number, not '{PythonTypeOps.GetName(real)}'"); } double real3 = real2.Real - imag2.Imaginary; double imag3 = real2.Imaginary + imag2.Real; if (cls == TypeCache.Complex) { return(new Complex(real3, imag3)); } else { return(cls.CreateInstance(context, real3, imag3)); } }
internal static DynamicMetaObject Call(DynamicMetaObjectBinder /*!*/ call, DynamicMetaObject target, DynamicMetaObject /*!*/[] /*!*/ args) { Assert.NotNull(call, args); Assert.NotNullItems(args); if (target.NeedsDeferral()) { return(call.Defer(ArrayUtils.Insert(target, args))); } foreach (DynamicMetaObject mo in args) { if (mo.NeedsDeferral()) { RestrictTypes(args); return(call.Defer( ArrayUtils.Insert(target, args) )); } } DynamicMetaObject self = target.Restrict(target.GetLimitType()); ValidationInfo valInfo = BindingHelpers.GetValidationInfo(target); PythonType pt = DynamicHelpers.GetPythonType(target.Value); PythonContext pyContext = PythonContext.GetPythonContext(call); // look for __call__, if it's present dispatch to it. Otherwise fall back to the // default binder PythonTypeSlot callSlot; if (!typeof(Delegate).IsAssignableFrom(target.GetLimitType()) && pt.TryResolveSlot(pyContext.SharedContext, "__call__", out callSlot)) { ConditionalBuilder cb = new ConditionalBuilder(call); Expression body; callSlot.MakeGetExpression( pyContext.Binder, PythonContext.GetCodeContext(call), self, GetPythonType(self), cb ); if (!cb.IsFinal) { cb.FinishCondition(GetCallError(call, self)); } Expression[] callArgs = ArrayUtils.Insert( PythonContext.GetCodeContext(call), cb.GetMetaObject().Expression, DynamicUtils.GetExpressions(args) ); body = Ast.Dynamic( PythonContext.GetPythonContext(call).Invoke( BindingHelpers.GetCallSignature(call) ), typeof(object), callArgs ); body = Ast.TryFinally( Ast.Block( Ast.Call(typeof(PythonOps).GetMethod("FunctionPushFrame"), Ast.Constant(pyContext)), body ), Ast.Call(typeof(PythonOps).GetMethod("FunctionPopFrame")) ); return(BindingHelpers.AddDynamicTestAndDefer( call, new DynamicMetaObject(body, self.Restrictions.Merge(BindingRestrictions.Combine(args))), args, valInfo )); } return(null); }
public static timedelta __new__(CodeContext context, PythonType cls, [DefaultParameterValue(0D)] double days, [DefaultParameterValue(0D)] double seconds, [DefaultParameterValue(0D)] double microseconds, [DefaultParameterValue(0D)] double milliseconds, [DefaultParameterValue(0D)] double minutes, [DefaultParameterValue(0D)] double hours, [DefaultParameterValue(0D)] double weeks) { if (cls == DynamicHelpers.GetPythonTypeFromType(typeof(timedelta))) { return new timedelta(days, seconds, microseconds, milliseconds, minutes, hours, weeks); } else { timedelta delta = cls.CreateInstance(context, days, seconds, microseconds, milliseconds, minutes, hours, weeks) as timedelta; if (delta == null) throw PythonOps.TypeError("{0} is not a subclass of datetime.timedelta", cls); return delta; } }
public MetaGetAttributeDelegate(CodeContext context, PythonTypeSlot slot, PythonType metaType, string name) { _name = name; if (metaType.IsSystemType) { _metaType = metaType; _slot = slot; } else { _weakMetaType = metaType.GetSharedWeakReference(); _weakSlot = new WeakReference(slot); } _invokeSite = CallSite <Func <CallSite, CodeContext, object, string, object> > .Create(context.LanguageContext.InvokeOne); }
private static void InitModuleExceptions(PythonContext context, PythonDictionary dict) { Error = context.EnsureModuleException("csv.Error", PythonExceptions.Exception, dict, "Error", "_csv"); }
public static object OverloadedNewBasic(CodeContext context, SiteLocalStorage <CallSite <Func <CallSite, CodeContext, object, object[], object> > > storage, BuiltinFunction overloads\u00F8, PythonType type\u00F8, params object[] args\u00F8) { if (type\u00F8 == null) { throw PythonOps.TypeError("__new__ expected type object, got {0}", PythonOps.Repr(context, DynamicHelpers.GetPythonType(type\u00F8))); } if (args\u00F8 == null) { args\u00F8 = new object[1]; } return(overloads\u00F8.Call(context, storage, null, args\u00F8)); }
private static Exception CreateThrowable(PythonType type, params object[] args) { return(PythonOps.CreateThrowable(type, args)); }
public static string FancyRepr(object self) { PythonType pt = (PythonType)DynamicHelpers.GetPythonType(self); // we can't call ToString on a UserType because we'll stack overflow, so // only do FancyRepr for reflected types. if (pt.IsSystemType) { string toStr = self.ToString(); if (toStr == null) { toStr = String.Empty; } // get the type name to display (CLI name or Python name) Type type = pt.UnderlyingSystemType; string typeName = type.FullName; // Get the underlying .ToString() representation. Truncate multiple // lines, and don't display it if it's object's default representation (type name) // skip initial empty lines: int i = 0; while (i < toStr.Length && (toStr[i] == '\r' || toStr[i] == '\n')) { i++; } // read the first non-empty line: int j = i; while (j < toStr.Length && toStr[j] != '\r' && toStr[j] != '\n') { j++; } // skip following empty lines: int k = j; while (k < toStr.Length && (toStr[k] == '\r' || toStr[k] == '\n')) { k++; } if (j > i) { string first_non_empty_line = toStr.Substring(i, j - i); bool has_multiple_non_empty_lines = k < toStr.Length; return(String.Format("<{0} object at {1} [{2}{3}]>", typeName, PythonOps.HexId(self), first_non_empty_line, has_multiple_non_empty_lines ? "..." : String.Empty)); } else { return(String.Format("<{0} object at {1}>", typeName, PythonOps.HexId(self))); } } return(SimpleRepr(self)); }
internal BuiltinInstanceInfo GetInstance(PythonType type) { return(GetBuiltinType(type).Instance); }
/// <summary> /// Returns a pointer instance for the given CData /// </summary> public static Pointer pointer(CodeContext /*!*/ context, CData data) { PythonType ptrType = POINTER(context, DynamicHelpers.GetPythonType(data)); return((Pointer)ptrType.CreateInstance(context, data)); }
internal BuiltinClassInfo GetBuiltinType(PythonType type) { return(GetCached(type, () => new BuiltinClassInfo(type, this))); }
internal static PythonType MakeSystemType(Type underlyingSystemType) { return(PythonType.SetPythonType(underlyingSystemType, new SimpleType(underlyingSystemType))); }
void IPythonObject.SetPythonType(PythonType newType) { (GetObject() as IPythonObject).SetPythonType(newType); }
public override bool IsValid(PythonType type) { // only used for built-in types, we never become invalid. return(true); }
public SlotWrapper(string slotName, PythonType targetType) { _name = slotName; _type = targetType; }
private Func <CallSite, TSelfType, CodeContext, object> MakeGetMemberTarget <TSelfType>(string name, object target) { Type type = CompilerHelpers.GetType(target); // needed for GetMember call until DynamicAction goes away if (typeof(TypeTracker).IsAssignableFrom(type)) { // no fast path for TypeTrackers PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast TypeTracker"); return(null); } MemberGroup members = Context.Binder.GetMember(MemberRequestKind.Get, type, name); if (members.Count == 0 && type.IsInterface) { // all interfaces have object members type = typeof(object); members = Context.Binder.GetMember(MemberRequestKind.Get, type, name); } if (members.Count == 0 && typeof(IStrongBox).IsAssignableFrom(type)) { // no fast path for strong box access PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast StrongBox"); return(null); } MethodInfo getMem = Context.Binder.GetMethod(type, "GetCustomMember"); if (getMem != null && getMem.IsSpecialName) { // no fast path for custom member access PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast GetCustomMember " + type); return(null); } Expression error; TrackerTypes memberType = Context.Binder.GetMemberType(members, out error); if (error == null) { PythonType argType = DynamicHelpers.GetPythonTypeFromType(type); bool isHidden = argType.IsHiddenMember(name); if (isHidden) { PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast FilteredMember " + memberType); return(null); } switch (memberType) { case TrackerTypes.TypeGroup: case TrackerTypes.Type: object typeObj; if (members.Count == 1) { typeObj = DynamicHelpers.GetPythonTypeFromType(((TypeTracker)members[0]).Type); } else { TypeTracker typeTracker = (TypeTracker)members[0]; for (int i = 1; i < members.Count; i++) { typeTracker = TypeGroup.UpdateTypeEntity(typeTracker, (TypeTracker)members[i]); } typeObj = typeTracker; } return(new FastTypeGet <TSelfType>(type, typeObj).GetTypeObject); case TrackerTypes.Method: PythonTypeSlot slot = PythonTypeOps.GetSlot(members, name, _context.DomainManager.Configuration.PrivateBinding); if (slot is BuiltinMethodDescriptor) { return(new FastMethodGet <TSelfType>(type, (BuiltinMethodDescriptor)slot).GetMethod); } else if (slot is BuiltinFunction) { return(new FastSlotGet <TSelfType>(type, slot, DynamicHelpers.GetPythonTypeFromType(type)).GetRetSlot); } return(new FastSlotGet <TSelfType>(type, slot, DynamicHelpers.GetPythonTypeFromType(type)).GetBindSlot); case TrackerTypes.Event: if (members.Count == 1 && !((EventTracker)members[0]).IsStatic) { slot = PythonTypeOps.GetSlot(members, name, _context.DomainManager.Configuration.PrivateBinding); return(new FastSlotGet <TSelfType>(type, slot, DynamicHelpers.GetPythonTypeFromType(((EventTracker)members[0]).DeclaringType)).GetBindSlot); } PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast Event " + members.Count + " " + ((EventTracker)members[0]).IsStatic); return(null); case TrackerTypes.Property: if (members.Count == 1) { PropertyTracker pt = (PropertyTracker)members[0]; if (!pt.IsStatic && pt.GetIndexParameters().Length == 0) { MethodInfo prop = pt.GetGetMethod(); ParameterInfo[] parameters; if (prop != null && (parameters = prop.GetParameters()).Length == 0) { if (prop.ReturnType == typeof(bool)) { return(new FastPropertyGet <TSelfType>(type, CallInstruction.Create(prop, parameters).Invoke).GetPropertyBool); } else if (prop.ReturnType == typeof(int)) { return(new FastPropertyGet <TSelfType>(type, CallInstruction.Create(prop, parameters).Invoke).GetPropertyInt); } else { return(new FastPropertyGet <TSelfType>(type, CallInstruction.Create(prop, parameters).Invoke).GetProperty); } } } } PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast Property " + members.Count + " " + ((PropertyTracker)members[0]).IsStatic); return(null); case TrackerTypes.All: getMem = Context.Binder.GetMethod(type, "GetBoundMember"); if (getMem != null && getMem.IsSpecialName) { PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast GetBoundMember " + type); return(null); } if (IsNoThrow) { return(new FastErrorGet <TSelfType>(type, name).GetErrorNoThrow); } else { return(new FastErrorGet <TSelfType>(type, name).GetError); } default: PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast " + memberType); return(null); } } else { StringBuilder sb = new StringBuilder(); foreach (MemberTracker mi in members) { if (sb.Length != 0) { sb.Append(", "); } sb.Append(mi.MemberType); sb.Append(" : "); sb.Append(mi.ToString()); } return(new FastErrorGet <TSelfType>(type, sb.ToString()).GetAmbiguous); } }
public static object __new__( CodeContext context, PythonType cls, [DefaultParameterValue(null)] object real, [DefaultParameterValue(null)] object imag ) { Complex real2, imag2; real2 = imag2 = new Complex(); if (real == null && imag == null && cls == TypeCache.Complex) { throw PythonOps.TypeError("argument must be a string or a number"); } if (imag != null) { if (real is string) { throw PythonOps.TypeError("complex() can't take second arg if first is a string"); } if (imag is string) { throw PythonOps.TypeError("complex() second arg can't be a string"); } imag2 = Converter.ConvertToComplex(imag); } if (real != null) { if (real is string) { real2 = LiteralParser.ParseComplex((string)real); } else if (real is Extensible <string> ) { real2 = LiteralParser.ParseComplex(((Extensible <string>)real).Value); } else if (real is Complex) { if (imag == null && cls == TypeCache.Complex) { return(real); } else { real2 = (Complex)real; } } else { real2 = Converter.ConvertToComplex(real); } } double real3 = real2.Real - imag2.Imaginary(); double imag3 = real2.Imaginary() + imag2.Real; if (cls == TypeCache.Complex) { return(new Complex(real3, imag3)); } else { return(cls.CreateInstance(context, real3, imag3)); } }
public ObjectException(PythonType type, object instance) { _instance = instance; _type = type; }
public static object fromhex(CodeContext /*!*/ context, PythonType /*!*/ cls, string self) { if (String.IsNullOrEmpty(self)) { throw PythonOps.ValueError("expected non empty string"); } self = self.Trim(_whitespace); // look for inf, infinity, nan, etc... double?specialRes = TryParseSpecialFloat(self); if (specialRes != null) { return(specialRes.Value); } // nothing special, parse the hex... if (_fromHexRegex == null) { _fromHexRegex = new Regex("\\A\\s*(?<sign>[-+])?(?:0[xX])?(?<integer>[0-9a-fA-F]+)?(?<fraction>\\.[0-9a-fA-F]*)?(?<exponent>[pP][-+]?[0-9]+)?\\s*\\z"); } Match match = _fromHexRegex.Match(self); if (!match.Success) { throw InvalidHexString(); } var sign = match.Groups["sign"]; var integer = match.Groups["integer"]; var fraction = match.Groups["fraction"]; var exponent = match.Groups["exponent"]; bool isNegative = sign.Success && sign.Value == "-"; BigInteger intVal; if (integer.Success) { intVal = LiteralParser.ParseBigInteger(integer.Value, 16); } else { intVal = BigInteger.Zero; } // combine the integer and fractional parts into one big int BigInteger finalBits; int decimalPointBit = 0; // the number of bits of fractions that we have if (fraction.Success) { BigInteger fractionVal = 0; // add the fractional bits to the integer value for (int i = 1; i < fraction.Value.Length; i++) { char chr = fraction.Value[i]; int val; if (chr >= '0' && chr <= '9') { val = chr - '0'; } else if (chr >= 'a' && chr <= 'f') { val = 10 + chr - 'a'; } else if (chr >= 'A' && chr <= 'Z') { val = 10 + chr - 'A'; } else { // unreachable due to the regex throw new InvalidOperationException(); } fractionVal = (fractionVal << 4) | val; decimalPointBit += 4; } finalBits = (intVal << decimalPointBit) | fractionVal; } else { // we only have the integer value finalBits = intVal; } if (exponent.Success) { int exponentVal = 0; if (!Int32.TryParse(exponent.Value.Substring(1), out exponentVal)) { if (exponent.Value.ToLowerAsciiTriggered().StartsWith("p-") || finalBits == BigInteger.Zero) { double zeroRes = isNegative ? NegativeZero : PositiveZero; if (cls == TypeCache.Double) { return(zeroRes); } return(PythonCalls.Call(cls, zeroRes)); } // integer value is too big, no way we're fitting this in. throw HexStringOverflow(); } // update the bits to truly reflect the exponent if (exponentVal > 0) { finalBits = finalBits << exponentVal; } else if (exponentVal < 0) { decimalPointBit -= exponentVal; } } if ((!exponent.Success && !fraction.Success && !integer.Success) || (!integer.Success && fraction.Length == 1)) { throw PythonOps.ValueError("invalid hexidecimal floating point string '{0}'", self); } if (finalBits == BigInteger.Zero) { if (isNegative) { return(NegativeZero); } else { return(PositiveZero); } } int highBit = finalBits.GetBitCount(); // minus 1 because we'll discard the high bit as it's implicit int finalExponent = highBit - decimalPointBit - 1; while (finalExponent < -1023) { // if we have a number with a very negative exponent // we'll throw away all of the insignificant bits even // if it takes the number down to zero. highBit++; finalExponent++; } if (finalExponent == -1023) { // the exponent bits will be all zero, we're going to be a denormalized number, so // we need to keep the most significant bit. highBit++; } // we have 52 bits to store the exponent. In a normalized number the mantissa has an // implied 1 bit, in denormalized mode it doesn't. int lostBits = highBit - 53; bool rounded = false; if (lostBits > 0) { // we have more bits then we can stick in the double, we need to truncate or round the value. BigInteger finalBitsAndRoundingBit = finalBits >> (lostBits - 1); // check if we need to round up (round half even aka bankers rounding) if ((finalBitsAndRoundingBit & BigInteger.One) != BigInteger.Zero) { // grab the bits we need and the least significant bit which we care about for rounding BigInteger discardedBits = finalBits & ((BigInteger.One << (lostBits - 1)) - 1); if (discardedBits != BigInteger.Zero || // not exactly .5 ((finalBits >> lostBits) & BigInteger.One) != BigInteger.Zero) // or we're exactly .5 and odd and need to round up // round the value up by adding 1 { BigInteger roundedBits = finalBitsAndRoundingBit + 1; // now remove the least significant bit we kept for rounding finalBits = (roundedBits >> 1) & 0xfffffffffffff; // check to see if we overflowed into the next bit (e.g. we had a pattern like ffffff rounding to 1000000) if (roundedBits.GetBitCount() != finalBitsAndRoundingBit.GetBitCount()) { if (finalExponent != -1023) { // we overflowed and we're a normalized number. Discard the new least significant bit so we have // the correct number of bits. We need to raise the exponent to account for this division by 2. finalBits = finalBits >> 1; finalExponent++; } else if (finalBits == BigInteger.Zero) { // we overflowed and we're a denormalized number == 0. Increase the exponent making us a normalized // number. Don't adjust the bits because we're now gaining an implicit 1 bit. finalExponent++; } } rounded = true; } } } if (!rounded) { // no rounding is necessary, just shift the bits to get the mantissa finalBits = (finalBits >> (highBit - 53)) & 0xfffffffffffff; } if (finalExponent > 1023) { throw HexStringOverflow(); } // finally assemble the bits long bits = (long)finalBits; bits |= (((long)finalExponent) + 1023) << 52; if (isNegative) { bits |= unchecked ((long)0x8000000000000000); } double res = BitConverter.Int64BitsToDouble(bits); if (cls == TypeCache.Double) { return(res); } return(PythonCalls.Call(cls, res)); }
public DateTimeConstructor(PythonType pythontype) { this.pythontype = pythontype; }
protected override void AddMetaGetAttribute(PythonType metaType, PythonTypeSlot pts) { _gets.Add(new MetaGetAttributeDelegate(_context, pts, metaType, _binder.Name).Target); }