Beispiel #1
0
 private static int PredicateArity(PlTerm term)
 {
     if (term.Name == "{}")
     {
         if (term.Arity == 1)
         {
             return(PredicateArity(term.Arg(0)));
         }
     }
     if (term.Name == ":")
     {
         if (term.Arity == 2)
         {
             return(PredicateArity(term.Arg(1)));
         }
     }
     if (term.Name == "/")
     {
         if (term.Arity == 2)
         {
             return(term.Arg(1).intValue());
         }
     }
     return(term.Arity);
 }
Beispiel #2
0
 private static string PredicateName(PlTerm term)
 {
     if (term.Name == "{}")
     {
         if (term.Arity == 1)
         {
             return(PredicateName(term.Arg(0)));
         }
     }
     if (term.Name == ":")
     {
         if (term.Arity == 2)
         {
             return(PredicateName(term.Arg(1)));
         }
     }
     if (term.Name == "/")
     {
         if (term.Arity == 2)
         {
             return(PredicateName(term.Arg(0)));
         }
     }
     return(term.Name);
 }
Beispiel #3
0
        static public bool cliAddLayout(PlTerm clazzSpec, PlTerm memberSpec)
        {
            Type   type  = GetType(clazzSpec);
            string name  = memberSpec.Name;
            int    arity = memberSpec.Arity;

            MemberInfo[] fieldInfos = new MemberInfo[arity];
            for (int i = 0; i < arity; i++)
            {
                var arg = memberSpec.Arg(i);
                fieldInfos[i] = findMember(arg, type);
            }
            AddPrologTermLayout(type, name, fieldInfos, null);
            return(true);
        }
Beispiel #4
0
 public static PlTerm[] ToTermArray(IEnumerable <PlTerm> enumerable)
 {
     if (enumerable is PlTerm[])
     {
         return((PlTerm[])enumerable);
     }
     if (enumerable is PlTermV)
     {
         PlTermV tv = (PlTermV)enumerable;
         return(tv.ToArray());
     }
     if (enumerable is PlTerm)
     {
         // I guess IsList makes a copy
         PlTerm tlist = (PlTerm)enumerable;
         if (tlist.IsVar)
         {
             return new PlTerm[] { tlist }
         }
         ;
         if (tlist.IsList)
         {
             enumerable = tlist.Copy();
         }
         if (tlist.Name == "{}")
         {
             var t     = tlist.Arg(0);
             var terms = new List <PlTerm>();
             while (t.Arity == 2)
             {
                 terms.Add(t.Arg(0));
                 t = t.Arg(1);
             }
             // last Item
             terms.Add(t);
             return(terms.ToArray());
         }
         if (tlist.IsAtomic)
         {
             if (tlist.IsAtom && tlist.Name == "[]")
             {
                 return(new PlTerm[0]);
             }
             return(new PlTerm[] { tlist });
         }
     }
     return(enumerable.ToArray());
 }
Beispiel #5
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));
        }