Beispiel #1
0
        internal static object DCArg(Variable v)
        {
            P6any o = v.Fetch();
            var   s = o.mo.setting;

            if (o is BoxObject <object> )
            {
                return(Kernel.UnboxAny <object>(o));
            }
            else if (o.IsDefined())
            {
                if (o.Isa(s.StrMO))
                {
                    return((string)o.mo.mro_raw_Str.Get(v));
                }
                else if (o.Isa(s.BoolMO))
                {
                    return((bool)o.mo.mro_raw_Bool.Get(v));
                }
                else if (o.Isa(s.NumMO))
                {
                    double d = Kernel.UnboxAny <double>(o);
                    if ((d % 1) == 0 && d <= int.MaxValue && d >= int.MinValue)
                    {
                        return((object)(int)d);
                    }
                    return((object)d);
                }
                else if (o.Isa(s.ListMO))
                {
                    VarDeque it = o.mo.mro_raw_iterator.Get(v);
                    var      lo = new List <object>();
                    while (Kernel.IterHasFlat(it, true))
                    {
                        lo.Add(DCArg(it.Shift()));
                    }
                    return(lo.ToArray());
                }
                else
                {
                    return((int)o.mo.mro_raw_Numeric.Get(v));
                }
            }
            else
            {
                return(null);
            }
        }
Beispiel #2
0
        internal static object DCArg(Variable v)
        {
            P6any o = v.Fetch();

            if (o is BoxObject <object> )
            {
                return(Kernel.UnboxAny <object>(o));
            }
            else if (o.IsDefined())
            {
                if (o.Isa(Kernel.StrMO))
                {
                    return((string)o.mo.mro_raw_Str.Get(v));
                }
                else if (o.Isa(Kernel.BoolMO))
                {
                    return((bool)o.mo.mro_raw_Bool.Get(v));
                }
                else if (o.Isa(Kernel.ListMO))
                {
                    VarDeque it = o.mo.mro_raw_iterator.Get(v);
                    var      lo = new List <object>();
                    while (Kernel.IterHasFlat(it, true))
                    {
                        lo.Add(DCArg(it.Shift()));
                    }
                    return(lo.ToArray());
                }
                else
                {
                    return((int)o.mo.mro_raw_Numeric.Get(v));
                }
            }
            else
            {
                return(null);
            }
        }
Beispiel #3
0
        internal static void SerializeNam(Variable v, StringBuilder sb,
                                          List <object> refs)
        {
            P6any o = v.Fetch();

            if (o is BoxObject <int> ) /* includes bool */
            {
                sb.Append(Kernel.UnboxAny <int>(o));
            }
            else if (o is BoxObject <double> )
            {
                sb.Append(Utils.N2S(Kernel.UnboxAny <double>(o)));
            }
            else if (o is BoxObject <string> )
            {
                string s = Kernel.UnboxAny <string>(o);
                sb.Append('"');
                foreach (char c in s)
                {
                    if (c >= ' ' && c <= '~' && c != '\\' && c != '"')
                    {
                        sb.Append(c);
                    }
                    else
                    {
                        sb.Append("\\u");
                        sb.AppendFormat("{0:X4}", (int)c);
                    }
                }
                sb.Append('"');
            }
            else if (!o.IsDefined())
            {
                sb.Append("null");
            }
            else if (o.Isa(o.mo.setting.ListMO))
            {
                VarDeque d     = o.mo.mro_raw_iterator.Get(v);
                bool     comma = false;
                sb.Append('[');
                while (Kernel.IterHasFlat(d, true))
                {
                    if (comma)
                    {
                        sb.Append(',');
                    }
                    SerializeNam(d.Shift(), sb, refs);
                    comma = true;
                }
                sb.Append(']');
            }
            else if (o is BoxObject <object> )
            {
                sb.Append('!');
                sb.Append(refs.Count);
                refs.Add(Kernel.UnboxAny <object>(o));
            }
            else
            {
                throw new NieczaException("weird object in sub_finish " + o.mo.name);
            }
        }
Beispiel #4
0
        public static bool CoerceArgument(out object clr, Type ty, Variable var)
        {
            P6any obj = var.Fetch();

            clr = null;

            // type objects are typed nulls
            if (!obj.IsDefined())
            {
                if (obj is BoxObject <object> )
                {
                    Type t = obj.mo.box_type;
                    // is this enough?
                    return(ty.IsAssignableFrom(t) && !ty.IsValueType &&
                           ty != typeof(void));
                }
                else if (obj.mo == Kernel.MuMO || obj.mo == Kernel.AnyMO)
                {
                    // untyped-ish null
                    return(!ty.IsValueType && ty != typeof(void));
                }
                else
                {
                    // we'll pass this by value anyway
                    clr = obj;
                    return(ty.IsAssignableFrom(obj.GetType()));
                }
            }
            // in all other cases we're definitely passing a non-null value

            // Boolean values marshal to bool
            if (obj.Does(Kernel.BoolMO))
            {
                clr = Kernel.UnboxAny <int>(obj) != 0;
            }
            // note, Bool ~~ Int ~~ Integral
            else if (obj.Does(Kernel.IntegralMO))
            {
                // important type directed case!
                int        small;
                BigInteger big;
                bool       use_big = Builtins.GetAsInteger(var, out small, out big);

                if (ty == typeof(sbyte))
                {
                    clr = (!use_big && small >= sbyte.MinValue && small <= sbyte.MaxValue) ? (object)(sbyte)small : null;
                }
                else if (ty == typeof(byte))
                {
                    clr = (!use_big && small >= byte.MinValue && small <= byte.MaxValue) ? (object)(byte)small : null;
                }
                else if (ty == typeof(short))
                {
                    clr = (!use_big && small >= short.MinValue && small <= short.MaxValue) ? (object)(short)small : null;
                }
                else if (ty == typeof(ushort))
                {
                    clr = (!use_big && small >= ushort.MinValue && small <= ushort.MaxValue) ? (object)(ushort)small : null;
                }
                else
                {
                    big = use_big ? big : (BigInteger)small;

                    if (ty == typeof(int))
                    {
                        clr = (big >= int.MinValue && big <= int.MaxValue) ? (object)(int)big : null;
                    }
                    else if (ty == typeof(uint))
                    {
                        clr = (big >= uint.MinValue && big <= uint.MaxValue) ? (object)(uint)big : null;
                    }
                    else if (ty == typeof(long))
                    {
                        clr = (big >= long.MinValue && big <= long.MaxValue) ? (object)(long)big : null;
                    }
                    else if (ty == typeof(ulong))
                    {
                        clr = (big >= ulong.MinValue && big <= ulong.MaxValue) ? (object)(ulong)big : null;
                    }

                    else if (ty == typeof(float))
                    {
                        clr = (object)(float)big;
                    }
                    else if (ty == typeof(double))
                    {
                        clr = (object)(double)big;
                    }
                    else if (ty == typeof(decimal))
                    {
                        clr = big.GetWords().Length <= 3 ? (object)(decimal)big : null;
                    }
                    else if (ty == typeof(object))
                    {
                        clr = use_big ? null : (object)small;
                    }
                    else
                    {
                        clr = obj;
                    }
                }
            }
            else if (obj.Does(Kernel.RealMO))
            {
                // fractional value

                if (ty == typeof(decimal))
                {
                    // decimal is for people who care about exactness
                    int        rk;
                    P6any      n = Builtins.GetNumber(var, obj, out rk);
                    BigInteger num, den;
                    if (rk == Builtins.NR_FATRAT)
                    {
                        FatRat r = Kernel.UnboxAny <FatRat>(n);
                        num = r.num; den = r.den;
                    }
                    else if (rk == Builtins.NR_FIXRAT)
                    {
                        Rat r = Kernel.UnboxAny <Rat>(n);
                        num = r.num; den = r.den;
                    }
                    else if (rk == Builtins.NR_BIGINT)
                    {
                        num = Kernel.UnboxAny <BigInteger>(n); den = BigInteger.One;
                    }
                    else if (rk == Builtins.NR_FIXINT)
                    {
                        num = Kernel.UnboxAny <int>(n); den = BigInteger.One;
                    }
                    else
                    {
                        return(false);
                    }
                    BigInteger div, rem;
                    int        scale = 0;
                    while (true)
                    {
                        div = BigInteger.DivRem(den, 10, out rem);
                        if (rem.Sign != 0)
                        {
                            break;
                        }
                        den = div;
                        scale++;
                    }
                    while (true)
                    {
                        div = BigInteger.DivRem(den, 5, out rem);
                        if (rem.Sign != 0)
                        {
                            break;
                        }
                        den  = div;
                        num *= 2;
                        scale++;
                    }
                    while (true)
                    {
                        div = BigInteger.DivRem(den, 2, out rem);
                        if (rem.Sign != 0)
                        {
                            break;
                        }
                        den  = div;
                        num *= 5;
                        scale++;
                    }
                    if (den != BigInteger.One)
                    {
                        return(false);
                    }
                    if (scale > 28)
                    {
                        return(false);
                    }
                    int[] bits = decimal.GetBits((decimal)num);
                    bits[3] = scale << 16;
                    clr     = new decimal(bits);
                }
                else
                {
                    double val = obj.mo.mro_raw_Numeric.Get(var);
                    if (ty == typeof(float))
                    {
                        clr = (object)(float)val;
                    }
                    else if (ty == typeof(double) || ty == typeof(object))
                    {
                        clr = (object)val;
                    }
                }
            }
            else if (obj.Does(Kernel.StrMO))
            {
                string s = Kernel.UnboxAny <string>(obj);
                if (ty == typeof(char) && s.Length == 1)
                {
                    clr = s[0];
                }
                else if (ty == typeof(string))
                {
                    clr = s;
                }
                else if (ty == typeof(object))
                {
                    clr = s;
                }
                else
                {
                    clr = obj;
                }
            }
            // "Callable"
            else if (typeof(Delegate).IsAssignableFrom(ty))
            {
                MethodInfo      needed = ty.GetMethod("Invoke");
                ParameterInfo[] pi     = needed.GetParameters();

                if (pi.Length >= 10)
                {
                    clr = null;
                }
                else if (needed.ReturnType != typeof(void))
                {
                    Type[] args = new Type[pi.Length + 1];
                    args[0] = needed.ReturnType;
                    for (int i = 0; i < pi.Length; i++)
                    {
                        args[i + 1] = pi[i].ParameterType;
                    }
                    MethodInfo compat = delegate_methods[pi.Length * 2 + 1].
                                        MakeGenericMethod(args);
                    clr = Delegate.CreateDelegate(ty, obj, compat);
                }
                else
                {
                    Type[] args = new Type[pi.Length];
                    for (int i = 0; i < pi.Length; i++)
                    {
                        args[i] = pi[i].ParameterType;
                    }
                    MethodInfo compat = delegate_methods[pi.Length * 2];
                    if (args.Length != 0)
                    {
                        compat = compat.MakeGenericMethod(args);
                    }
                    clr = Delegate.CreateDelegate(ty, obj, compat);
                }
            }
            else if (obj is BoxObject <object> )
            {
                clr = Kernel.UnboxAny <object>(obj);
            }
            else
            {
                clr = obj;
            }

            return(clr != null && ty.IsAssignableFrom(clr.GetType()));
        }