Beispiel #1
0
        /*
         *
         * jpl_is_ref(@(Y)) :-
         * atom(Y),        % presumably a (garbage-collectable) tag
         * Y \== void,     % not a ref
         * Y \== false,    % not a ref
         * Y \== true.     % not a ref
         *
         */
        private static object CastCompoundTerm(string name, int arity, PlTerm arg1, PlTerm orig, Type pt)
        {
            string key = name + "/" + arity;

            lock (FunctorToLayout)
            {
                PrologTermLayout pltl;
                if (FunctorToLayout.TryGetValue(key, out pltl))
                {
                    Type         type   = pltl.ObjectType;
                    MemberInfo[] fis    = pltl.FieldInfos;
                    MemberInfo   toType = pltl.ToType;
                    if (toType != null)
                    {
                        return(GetMemberValue(toType, CastTerm(arg1, argOneType(toType))));
                    }
                    return(CreateInstance(type, fis, orig, 1));
                }
            }
            lock (FunctorToRecomposer)
            {
                PrologTermRecomposer layout;
                if (FunctorToRecomposer.TryGetValue(key, out layout))
                {
                    Type   type   = layout.ToType;
                    uint   newref = libpl.PL_new_term_ref();
                    PlTerm outto  = new PlTerm(newref);
                    var    ret    = PlQuery.PlCall(layout.module, layout.r2obj, new PlTermV(orig, outto));
                    if (ret)
                    {
                        object o = CastTerm(outto, type);
                        if (!pt.IsInstanceOfType(o))
                        {
                            Warn(type + " (" + o + ") is not " + pt);
                        }
                        return(o);
                    }
                }
            }
            if (key == "[]/0")
            {
                if (pt != null)
                {
                    if (pt.IsArray)
                    {
                        return(Array.CreateInstance(pt.GetElementType(), 0));
                    }
                    return(MakeDefaultInstance(pt));
                }
                Warn("Not sure what to convert `[]` too");
                return(null);
            }
            if (key == "static/1")
            {
                return(null);
            }
            if (key == "delegate/1")
            {
                return(CastTerm0(arg1, pt));
            }
            if (key == "delegate/2")
            {
                return(cliNewDelegateTerm(pt, orig, false));
            }
            if (key == "{}/1")
            {
                return(arg1);
            }
            if (pt == typeof(object))
            {
                pt = null;
            }
            //{T}
            //@(_Tag)
            if (key == "@/1" && arg1.IsAtom)
            {
                name = arg1.Name;
                switch (name)
                {
                case "true":
                {
                    return(true);
                }

                case "false":
                {
                    return(false);
                }

                case "null":
                {
                    if (pt != null && pt.IsValueType)
                    {
                        return(MakeDefaultInstance(pt));
                    }
                    return(null);
                }

                case "void":
                {
#if USE_IKVM
                    if (pt == typeof(void))
                    {
                        return(JPL.JVOID);
                    }
#endif
                    return(null);
                }

                default:
                {
                    {
                        object o = tag_to_object(name);
                        if (o == null)
                        {
                            Warn("Null from tag " + name);
                        }
                        return(o);

#if plvar_pins
                        lock (ToFromConvertLock) lock (atomToPlRef)
                            {
                                PlRef oldValue;
                                if (!atomToPlRef.TryGetValue(name, out oldValue))
                                {
                                    //Warn("no value for tag=" + name);
                                    if (pt != null && pt.IsInstanceOfType(o))
                                    {
                                        return(o);
                                    }
                                    return(o);
                                }
                                var v = oldValue.Value;
                                if (pt != null && pt.IsInstanceOfType(v))
                                {
                                    return(v);
                                }
                                return(v);
                            }
#endif
                    }
                }
                }
            }
#if plvar_pins
            if (name == "$cli_object")
            {
                lock (ToFromConvertLock)
                {
                    lock (termToObjectPins)
                    {
                        PlRef oldValue;
                        Int64 ohandle = (long)arg1;
                        if (!termToObjectPins.TryGetValue(ohandle, out oldValue))
                        {
                            Warn("no value for ohandle=" + ohandle);
                        }
                        return(oldValue.Value);
                    }
                }
            }
#endif
            if (key == "enum/2")
            {
                Type   type  = GetType(arg1);
                PlTerm arg2  = orig.Arg(1);
                object value = Enum.Parse(type, arg2.Name, true);
                if (value == null)
                {
                    Warn("cant parse enum: {0} for type {1}", arg2, type);
                }
                return(value);
            }
            if (key == "array/2")
            {
                Type type = GetType(arg1);
                return(CreateArrayOfTypeRankOneFilled(orig.Arg(1), type.MakeArrayType()));
            }
            if (key == "array/3")
            {
                Type type = GetType(arg1);
                var  ar   = CreateArrayOfType(ToTermArray(orig.Arg(1)), type);
                FillArray(ToTermArray(orig.Arg(2)), type.GetElementType(), ar);
                return(ar);
            }
            if (name == "values")
            {
                Warn("Values array");
            }
            if (name == "struct" || name == "event" || name == "object")
            {
                Type         type = GetType(arg1);
                MemberInfo[] fis  = GetStructFormat(type);
                return(CreateInstance(type, fis, orig, 2));
            }
            if (orig.IsList)
            {
                if (arg1.IsInteger || arg1.IsAtom)
                {
                    Debug("maybe this is a string {0}", orig);
                }
                if (pt == null)
                {
                    var o1 = GetInstance(arg1);
                    if (false && o1 != null && IsTaggedObject(arg1) && arg1.IsCompound && !o1.GetType().IsPrimitive)
                    {
                        Warn(" send a list into cliGet0 ", orig);
                        bool found;
                        var  res = cliGet0(arg1, orig.Arg(1), o1.GetType(), out found,
                                           BindingFlagsALL3 | BindingFlagsALL);
                        if (found)
                        {
                            return(res);
                        }
                    }
                    Debug("Return as array of object[]?", orig);
                    var o = CreateArrayNarrowest(ToObjectArray(ToTermArray(orig)));
                    return(o);
                }
                else
                {
                    if (pt.IsArray)
                    {
                        return(CreateArrayOfTypeRankOneFilled(orig, pt));
                    }
                    if (!typeof(IEnumerable).IsAssignableFrom(pt))
                    {
                        Warn("Return as collection?", orig);
                    }
                    return(CreateCollectionOfType(orig, pt));
                }
            }
            if (pt != null && pt.IsArray)
            {
                return(CreateArrayOfTypeRankOneFilled(orig, pt));
            }
            Type t = ResolveType(name);
            if (t == null)
            {
                WarnMissing(String.Format("Cant GetInstance from {0}", orig));
                return(orig);
            }
            if (pt == null || pt.IsAssignableFrom(t))
            {
                if (arity == 1)
                {
                    return(CastTerm(arg1, t));
                }
                foreach (var m in t.GetConstructors())
                {
                    ParameterInfo[] mGetParameters = m.GetParameters();
                    if (mGetParameters.Length == arity)
                    {
                        Action postCallHook;
                        try
                        {
                            WarnMissing("using contructor {0}", m);
                            var values = PlListToCastedArray(orig, mGetParameters, out postCallHook);
                            var retval = m.Invoke(values);
                            CommitPostCall(postCallHook);
                            return(retval);
                        }
                        catch (Exception)
                        {
                        }
                    }
                }
            }
            // Debug("Get Instance fallthru");
            MemberInfo[] ofs = GetStructFormat(t);
            return(CreateInstance(t, ofs, orig, 1));
        }
Beispiel #2
0
        public static Class GetType(PlTerm clazzSpec, bool canBeObjects)
        {
            if (clazzSpec.IsVar)
            {
                Error("GetType IsVar {0}", clazzSpec);
                return(null);
            }
            if (IsTaggedObject(clazzSpec))
            {
                object tagObj = tag_to_object(clazzSpec[1].Name);
                var    r      = tagObj as Type;
                if (r != null)
                {
                    return(r);
                }
                if (!canBeObjects)
                {
                    Warn("cant find tagged object as class: {0}=>{1}", clazzSpec, tagObj);
                }
                if (tagObj != null)
                {
                    return(tagObj.GetType());
                }
                return(null);
            }
            Type type = null;

            if (clazzSpec.IsAtom || clazzSpec.IsString)
            {
                if (canBeObjects)
                {
                    return(typeof(string));
                }
                string name = (string)clazzSpec;
                type = ResolveType(name);
                if (type != null)
                {
                    return(type);
                }
                if (!canBeObjects)
                {
                    Warn("cant find atom/string as class: {0}", clazzSpec);
                    type = ResolveType(name);
                }
                return(null);
            }
            if (clazzSpec.IsCompound)
            {
                string clazzName = clazzSpec.Name;
                int    arity     = clazzSpec.Arity;
                if (clazzName == "arrayOf")
                {
                    if (arity != 1)
                    {
                        return(GetType(clazzSpec[1]).MakeArrayType(clazzSpec[2].intValue()));
                    }
                    return(GetType(clazzSpec[1]).MakeArrayType());
                }
                if (clazzName == "type")
                {
                    return((GetInstance(clazzSpec[1]) ?? NEW_OBJECTFORTYPE).GetType());
                }
                if (clazzName == "static" || clazzName == "typeof")
                {
                    return(GetType(clazzSpec[1]));
                }
                if (clazzName == "{}")
                {
                    return(typeof(PlTerm));
                }
                if (clazzName == "pointer")
                {
                    return(GetType(clazzSpec[1]).MakePointerType());
                }
                if (clazzName == "byref")
                {
                    return(GetType(clazzSpec[1]).MakeByRefType());
                }
                if (clazzName == "nullable")
                {
                    return(typeof(Nullable <>).MakeGenericType(new[] { GetType(clazzSpec[1]) }));
                }
                type = ResolveType(clazzName + "`" + arity);
                if (type != null)
                {
                    // 'Dictionary'('Int32','string').
                    if (type.IsGenericType)
                    {
                        Type[] genr  = type.GetGenericArguments();
                        Type[] genrc = null;
                        Type   genrb = null;
                        try
                        {
                            if (type.IsGenericParameter)
                            {
                                genrc = type.GetGenericParameterConstraints();
                            }
                        }
                        catch (Exception e)
                        {
                            Warn("GetGenericParameterConstraints: {0}", e);
                        }
                        try
                        {
                            genrb = type.GetGenericTypeDefinition();
                        }
                        catch (Exception e)
                        {
                            Warn("GetGenericTypeDefinition: {0}", e);
                        }

                        if (arity == genr.Length)
                        {
                            var vt = GetParamSpec(ToTermArray(clazzSpec), false);
                            return(type.MakeGenericType(vt));
                        }
                    }
                    //  return type;
                }
                string key = clazzName + "/" + arity;
                lock (FunctorToLayout)
                {
                    PrologTermLayout pltl;
                    if (FunctorToLayout.TryGetValue(key, out pltl))
                    {
                        return(pltl.ObjectType);
                    }
                }
                lock (FunctorToRecomposer)
                {
                    PrologTermRecomposer layout;
                    if (FunctorToRecomposer.TryGetValue(key, out layout))
                    {
                        return(layout.ToType);
                    }
                }
                WarnMissing("cant find compound as class: " + clazzSpec);
            }
            object toObject = GetInstance(clazzSpec);

            if (toObject is Type)
            {
                return((Type)toObject);
            }
            if (toObject != null)
            {
                return(toObject.GetType());
            }
            Warn("@TODO cant figure type from {0}", clazzSpec);
            return(typeof(object));
            //return null;
        }