Example #1
0
        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);
        }
Example #2
0
    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);
    }