public static Type CastTypes(Type a, Type b, Type preferredType = null)
        {
            if (a.ID == TypeID.Array || b.ID == TypeID.Array)
            {
                return(null);
            }

            //Types the same
            if (a.ID == b.ID && a.GetBase() == b.GetBase())
            {
                return(a);
            }

            //Types the same, but different base
            if (a.ID == b.ID && a.GetBase() != b.GetBase())
            {
                //Cast to bigger type
                return(a.GetBase() > b.GetBase() ? a : b);
            }

            //if we prefer something
            if (preferredType != null)
            {
                var type = CastTypes(a, b, null);

                if (type == null)
                {
                    return(null);
                }
                return(CastTypes(type, preferredType, null));
            }
            else
            {
                //We cant cast string and array to anything else
                if (a.ID == TypeID.String || b.ID == TypeID.String)
                {
                    return(null);
                }

                //Cast integers to float
                if (a.ID == TypeID.Float && b.ID != TypeID.Float)
                {
                    return(a);
                }
                if (b.ID == TypeID.Float && a.ID != TypeID.Float)
                {
                    return(b);
                }

                //choose best option
                var resultSigned = a.ID == TypeID.UInteger || b.ID == TypeID.UInteger;
                var resultBase   = Math.Max(a.GetBase(), b.GetBase());

                return(GetNumericType(resultSigned, resultBase));
            }
        }
        public static bool CanCastAssignment(Type dest, Type src)
        {
            if (dest.ID == TypeID.String || src.ID == TypeID.String)
            {
                return(false);
            }

            if (dest.ID == TypeID.Array && src.ID == TypeID.Array)
            {
                return(dest == src);
            }

            return(dest.GetBase() >= src.GetBase() && (dest.ID != TypeID.Integer && dest.ID != TypeID.UInteger || src.ID != TypeID.Float));
        }