public DyObject Assert(ExecutionContext ctx, DyObject expected, DyObject got) { if (!Eq(expected?.ToObject(), got?.ToObject())) { return(ctx.AssertFailed($"Expected {expected?.ToString(ctx)}, got {got?.ToString(ctx)}")); } return(DyNil.Instance); }
public static bool TryConvert(DyObject obj, Type type, out object?result) { result = default; long i8; double r8; string str; if (obj.TypeId == Dy.Interop) { var interop = (DyInterop)obj; if (BCL.Type.IsAssignableFrom(interop.Type)) //We have a type info here { if (BCL.Type.IsAssignableFrom(type)) //Type info is what we need { result = interop.Object; return(true); } else { return(false); } } else { try { result = Convert.ChangeType(interop.Object, type); return(true); } catch (Exception) { return(false); } } } if (type == BCL.DyObject) { result = obj; return(true); } else if (type == BCL.Object) { result = obj.ToObject(); return(true); } else if (BCL.DyObject.IsAssignableFrom(type)) { result = Convert.ChangeType(obj, type); return(true); } switch (Type.GetTypeCode(type)) { case TypeCode.Boolean: result = obj.IsTrue(); return(true); case TypeCode.Byte: if (TryGetInteger(obj, out i8)) { result = (byte)i8; return(true); } return(false); case TypeCode.Int16: if (TryGetInteger(obj, out i8)) { result = (short)i8; return(true); } return(false); case TypeCode.Int32: if (TryGetInteger(obj, out i8)) { result = (int)i8; return(true); } return(false); case TypeCode.Int64: if (TryGetInteger(obj, out i8)) { result = i8; return(true); } return(false); case TypeCode.SByte: if (TryGetInteger(obj, out i8)) { result = (sbyte)i8; return(true); } return(false); case TypeCode.UInt16: if (TryGetInteger(obj, out i8)) { result = (ushort)i8; return(true); } return(false); case TypeCode.UInt32: if (TryGetInteger(obj, out i8)) { result = (uint)i8; return(true); } return(false); case TypeCode.UInt64: if (TryGetInteger(obj, out i8)) { result = (ulong)i8; return(true); } return(false); case TypeCode.String: if (TryGetString(obj, out str)) { result = str; return(true); } return(false); case TypeCode.Char: if (TryGetString(obj, out str)) { result = string.IsNullOrEmpty(str) ? '\0' : str[0]; return(true); } return(false); case TypeCode.Single: if (TryGetFloat(obj, out r8)) { result = (float)r8; return(true); } return(false); case TypeCode.Double: if (TryGetFloat(obj, out r8)) { result = r8; return(true); } return(false); case TypeCode.Decimal: if (TryGetFloat(obj, out r8)) { result = (decimal)r8; return(true); } return(false); case TypeCode.Empty: result = null; return(true); default: if (obj is DyDictionary map) { if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { var genargs = type.GetGenericArguments(); var(keyType, valueType) = (genargs[0], genargs[1]); var targetType = typeof(Dictionary <,>).MakeGenericType(keyType, valueType); var ret = (IDictionary)Activator.CreateInstance(targetType) !; foreach (var kv in map.Dictionary) { ret[kv.Key.ToObject()] = kv.Value.ToObject(); } result = ret; return(true); } else if (type == typeof(Hashtable)) { var ret = new Hashtable(); foreach (var kv in map.Dictionary) { ret[kv.Key.ToObject()] = kv.Value.ToObject(); } result = ret; return(true); } } else if (obj is DyEnumerable enu) { if (type.IsArray) { var et = type.GetElementType(); if (!TryCreateTypedArray(enu.ToArray(), et !, out var res)) { return(false); } result = res; return(true); } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { var et = type.GetGenericArguments()[0]; if (!TryCreateTypedArray(enu.ToArray(), et !, out var res)) { return(false); } result = res; return(true); } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List <>)) { var et = type.GetGenericArguments()[0]; if (!TryCreateTypedArray(enu.ToArray(), et !, out var arr)) { return(false); } var targetType = typeof(List <>).MakeGenericType(et !); result = Activator.CreateInstance(targetType, arr); return(true); } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(HashSet <>)) { var et = type.GetGenericArguments()[0]; if (!TryCreateTypedArray(enu.ToArray(), et !, out var arr)) { return(false); } var targetType = typeof(HashSet <>).MakeGenericType(et !); result = Activator.CreateInstance(targetType, arr); return(true); } } break; } return(false); }