/* $Id$ * * Project: Swicli.Library - Two Way Interface for .NET and MONO to SWI-Prolog * Author: Douglas R. Miles * E-mail: logicmoo@gmail.com * WWW: http://www.logicmoo.org * Copyright (C): 2010-2012 LogicMOO Developement * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * *********************************************************/ #if USE_MUSHDLR using MushDLR223.Utilities; #endif #if USE_IKVM using JavaClass = java.lang.Class; #endif using System; using System.Collections; using System.Collections.Generic; //using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Threading; using SbsSW.SwiPlCs; using PlTerm = SbsSW.SwiPlCs.PlTerm; namespace Swicli.Library { public partial class PrologCLR { protected string ClientPrefix { get; set; } private string _clientModule = null; protected string ClientModule { get { return _clientModule; } set { if (value != "user") _clientModule = value; } } private static PrologCLR _singleInstance; public static PrologCLR SingleInstance { get { if (_singleInstance == null) _singleInstance = new PrologCLR(); return _singleInstance; } } public PrologCLR() { _singleInstance = this; ClientModule = null; ClientPrefix = "cli_"; PrologCLR.SetupProlog(); } public readonly static Type[] ZERO_TYPES = new Type[0]; public readonly static Object[] ZERO_OBJECTS = new Object[0]; public static readonly Type[] ONE_STRING = new[] {typeof (string)}; public static BindingFlags BindingFlagsJustStatic = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.FlattenHierarchy; public static BindingFlags BindingFlagsInstance = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy; public static BindingFlags BindingFlagsALL = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.IgnoreReturn | BindingFlags.FlattenHierarchy; public static BindingFlags InstanceFields = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy; public static BindingFlags BindingFlagsALLNC = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.IgnoreReturn | BindingFlags.FlattenHierarchy; public static BindingFlags BindingFlagsALL3 = BindingFlags.InvokeMethod | BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.SetField | BindingFlags.SetProperty; public static BindingFlags ICASE = BindingFlags.IgnoreCase; private static readonly BindingFlags[] BindingFlags_SEARCHIS = new[] { BindingFlagsInstance, BindingFlagsJustStatic, BindingFlagsInstance | ICASE, BindingFlagsJustStatic | ICASE, }; private static readonly BindingFlags[] BindingFlags_SEARCHS = new[] { BindingFlagsALL3 | BindingFlagsJustStatic, BindingFlagsALL3 | BindingFlagsJustStatic | ICASE, }; [PrologVisible] public static bool cliThrow(PlTerm ex) { throw (Exception) CastTerm(ex, typeof (Exception)); } [PrologVisible] public static bool cliBreak(PlTerm ex) { Trace(); return Embedded.WarnMissing(ToString(ex)) || true; } private static void Trace() { //throw new NotImplementedException(); } private static object ToFort(object o) { return ToProlog(o); } public static int PlSucceedOrFail(bool p) { return p ? libpl.PL_succeed : libpl.PL_fail; } public static bool PlSucceedOrFailOrError(int p) { return p != libpl.PL_fail; } private static string ToString(object o) { try { return ToString0(o); } catch (Exception) { return "" + o; } } private static string ToString0(object o) { if (o == null) return "null"; if (o is IConvertible || o is PlTerm || o is ValueType) return o.ToString(); if (o is IEnumerable) { var oc = (IEnumerable)o; int count = 0; string ret = "["; foreach (var o1 in oc) { if (count > 1) ret += ","; count++; ret += ToString0(o1); } return ret + "]"; } return o.ToString(); } /// /// 1 ?- cliToString(-1,X). /// X = "4294967295". /// /// /// /// [PrologVisible] public static bool cliToStrRaw(PlTerm obj, PlTerm str) { try { if (!str.IsVar) { var plvar = PlTerm.PlVar(); return cliToStrRaw(obj, plvar) && SpecialUnify(str, plvar); } if (obj.IsString) return str.Unify(obj); if (obj.IsVar) return str.Unify((string)obj); object o = GetInstance(obj); if (o == null) return str.FromObject("" + obj); return str.FromObject(ToString(o)); } catch (Exception e) { Embedded.Warn("cliToString: {0}", e); object o = GetInstance(obj); if (o == null) return str.FromObject("" + obj); return str.FromObject(ToString(o)); } } [IKVMBased] [PrologVisible] static public bool cliJavaToString(PlTerm paramIn, PlTerm valueOut) { if (!valueOut.IsVar) { var plvar = PlTerm.PlVar(); return cliJavaToString(paramIn, plvar) && SpecialUnify(valueOut, plvar); } object getInstance = GetInstance(paramIn); if (getInstance == null) return valueOut.Unify(PlTerm.PlString("null")); #if USE_IKVM //object val = getInstance as java.lang.Object; /* if (val == null) { JClass c = ikvm.runtime.Util.getClassFromObject(getInstance); string s = (string)c.getMethod("toString", new JClass[0]).invoke(getInstance, ZERO_OBJECTS); return valueOut.Unify(PlTerm.PlString(s)); }*/ return valueOut.Unify(PlTerm.PlString(ikvm.extensions.ExtensionMethods.instancehelper_toString(getInstance))); #else object val = getInstance; return valueOut.Unify(PlTerm.PlString(val.ToString())); #endif } private static bool CheckBound(params PlTerm[] terms) { foreach (PlTerm term in terms) { if (term.IsVar) { return Embedded.Error("Is var {0}", term); } } return true; } private static bool IsCompatTypes(Type[] supplied, Type[] required) { int len = supplied.Length; if (required.Length != len) return false; int considered = 0; foreach (Type type in required) { Type consider = supplied[considered]; if (!IsCompatType(consider,type)) { return false; } considered++; } return true; } private static bool IsCompatType(Type consider, Type type) { if (consider == null || type == null) return true; if (consider == typeof(object) || type == typeof(object)) return true; if (type.IsAssignableFrom(consider)) return true; if (typeof(IConvertible).IsAssignableFrom(type) && typeof(IConvertible).IsAssignableFrom(consider)) return true; return false; } [PrologVisible] static public bool cliLockEnter(PlTerm lockObj) { object getInstance = GetInstance(lockObj); Monitor.Enter(getInstance); return true; } [PrologVisible] static public bool cliLockExit(PlTerm lockObj) { object getInstance = GetInstance(lockObj); Monitor.Exit(getInstance); return true; } private static bool GetInstanceAndType(PlTerm clazzOrInstance, out object getInstance, out Type c) { if (clazzOrInstance.IsVar) { c = null; getInstance = null; return Embedded.Error("Cant find instance {0}", clazzOrInstance); } getInstance = GetInstance(clazzOrInstance); c = GetTypeFromInstance(getInstance, clazzOrInstance); if (getInstance == null && c == null) { return Embedded.Error("Cant find instance or type {0}", clazzOrInstance); } return true; } } }