static public void AddPrologTermRecomposer(Type type, string module, string obj2r, string r2obj, string functorWrapper, int arityWrapper) { PrologTermRecomposer layout = new PrologTermRecomposer(); layout.obj2r = obj2r; layout.module = module; layout.r2obj = r2obj; layout.Name = functorWrapper; layout.Arity = arityWrapper; layout.ToType = type; lock (FunctorToRecomposer) { FunctorToRecomposer[functorWrapper + "/" + arityWrapper] = layout; TypeToRecomposer[type] = layout; } }
public static int UnifyToPrologImmediate(object o, PlTerm term) { uint TermRef = term.TermRef; if (o is PlTerm) { return libpl.PL_unify(TermRef, ((PlTerm)o).TermRef); } if (o is string) { string s = (string)o; switch (VMStringsAsAtoms) { case libpl.CVT_STRING: { try { return libpl.PL_unify_string_chars(TermRef, (string)o); } catch (Exception) { return UnifyAtom(TermRef, s); } } case libpl.CVT_ATOM: try { return libpl.PL_unify_atom_chars(TermRef, (string)o); } catch (Exception) { return UnifyAtom(TermRef, s); } case libpl.CVT_LIST: return libpl.PL_unify_list_chars(TermRef, (string)o); default: Warn("UNKNOWN VMStringsAsAtoms {0}", VMStringsAsAtoms); return libpl.PL_fail; } } if (o == null) { return AddTagged(TermRef, "null"); } if (o is Type || o is Type) { if (true) { //lock (ToFromConvertLock) { var tag = object_to_tag(o); AddTagged(TermRef, tag); return libpl.PL_succeed; } } return PlSucceedOrFail(term.Unify(typeToSpec((Type)o))); } Type t = o.GetType(); if (t == typeof(void)) { return AddTagged(TermRef, "void"); } if (o is ValueType) { if (o is bool) { bool tf = (bool)o; return AddTagged(TermRef, tf ? "true" : "false"); } if (o is char) { try { char ch = (char)o; string cs = new string(ch, 1); switch (VMStringsAsAtoms) { case libpl.CVT_STRING: return libpl.PL_unify_atom_chars(TermRef, cs); case libpl.CVT_ATOM: return libpl.PL_unify_atom_chars(TermRef, cs); case libpl.CVT_LIST: return libpl.PL_unify_integer(TermRef, (int)ch); default: Warn("UNKNOWN VMStringsAsAtoms {0}", VMStringsAsAtoms); return libpl.PL_fail; } } catch (Exception e) { Warn("@TODO unmappable errors? {0} type {1}", o, t); // } } if (t.IsEnum) { int res = FromEnum(TermRef, o, t); ///term.ToString(); return res; } if (t.IsPrimitive) { try { int res = ToVMNumber(o, term); if (res == libpl.PL_succeed) return res; if (res == libpl.PL_fail) return res; if (res != -1) { // Warn("@TODO Missing code for ToVmNumber? " + o + " type " + t); return res; } if (t.IsPrimitive) { Warn("@TODO Missing code for primitive? {0} type {1}", o, t); } } catch (Exception e) { Warn("@TODO unmappable errors? {0} type {1}", o, t); } } } lock (FunctorToLayout) { PrologTermLayout layout; if (TypeToLayout.TryGetValue(t, out layout)) { MemberInfo[] tGetFields = layout.FieldInfos;// GetStructFormat(t); int len = tGetFields.Length; PlTermV tv = NewPlTermV(len); for (int i = 0; i < len; i++) { object v = GetMemberValue(tGetFields[i], o); tv[i].FromObject((v)); } return PlSucceedOrFail(term.Unify(PlC(layout.Name, tv))); } } lock (FunctorToRecomposer) { PrologTermRecomposer layout = GetTypeMap(t, TypeToRecomposer); if (layout != null) { lock (ToFromConvertLock) { var tag = object_to_tag(o); uint newref = libpl.PL_new_term_refs(2); AddTagged(newref, tag); PlTerm into = new PlTerm(newref); PlTerm outto = new PlTerm(newref + 1); var ret = PlQuery.PlCall(layout.module, layout.obj2r, new PlTermV(into, outto)); if (ret) { return term.Unify(outto) ? libpl.PL_succeed : libpl.PL_fail; } } } } if (o is IList) { } if (IsStructRecomposable(t)) { return ToFieldLayout("struct", typeToName(t), o, t, term, false, false); } if (o is EventArgs) { return ToFieldLayout("event", typeToName(t), o, t, term, false, false); } if (t.IsArray) { Array al = (Array) o; if (false && al.Length > 0 && al.Length < 1024) { Type et = t.GetElementType(); object firstNonNull = null; foreach (var ele in al) { if (ele!=null) { firstNonNull = ele; } } var needMake = firstNonNull != null; if (needMake) { PlTerm newVar = PlTerm.PlVar(); needMake = NeedsToMakeRef(firstNonNull, newVar); } if (!needMake) { return PlSucceedOrFail(unifyArrayToTerm(al, term)); } } } return PlObject(TermRef, o); }