/* * * 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)); }
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; }