summaryrefslogtreecommitdiff
path: root/src/runtime/dotNet/Native.cs
diff options
context:
space:
mode:
authorkrasimir <krasimir@chalmers.se>2017-05-31 13:48:36 +0000
committerkrasimir <krasimir@chalmers.se>2017-05-31 13:48:36 +0000
commite1cec06f7483ea913885a7918728a1c3f8ece650 (patch)
treea79d46b37747a60d285090e22572ea4f3810814d /src/runtime/dotNet/Native.cs
parent2a8d2806e4612d320de0155d8cdbbd68cd1d1995 (diff)
.NET binding to GF by Bjørnar Luteberget
Diffstat (limited to 'src/runtime/dotNet/Native.cs')
-rw-r--r--src/runtime/dotNet/Native.cs306
1 files changed, 306 insertions, 0 deletions
diff --git a/src/runtime/dotNet/Native.cs b/src/runtime/dotNet/Native.cs
new file mode 100644
index 000000000..346f85905
--- /dev/null
+++ b/src/runtime/dotNet/Native.cs
@@ -0,0 +1,306 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+/// <summary>
+/// Portable grammar format PInvoke functions.
+/// </summary>
+namespace PGFSharp
+{
+ internal static class Native
+ {
+
+ internal class NativeString : IDisposable
+ {
+ public IntPtr Ptr { get; private set; }
+ public int Size { get; private set; }
+
+ public NativeString(string s)
+ {
+ Ptr = NativeUtf8FromString(s);
+ Size = Encoding.UTF8.GetByteCount(s);
+ }
+
+ public void Dispose()
+ {
+ Marshal.FreeHGlobal(Ptr);
+ Ptr = IntPtr.Zero;
+ }
+
+ public static IntPtr NativeUtf8FromString(string managedString)
+ {
+ int len = Encoding.UTF8.GetByteCount(managedString);
+ IntPtr nativeUtf8 = Marshal.AllocHGlobal(len + 1);
+ CopyToPreallocated(managedString, nativeUtf8, len);
+ return nativeUtf8;
+ }
+
+ public static void CopyToPreallocated(string managedString, IntPtr ptr, int? len = null)
+ {
+ if (len == null) len = Encoding.UTF8.GetByteCount(managedString);
+ byte[] buffer = new byte[len.Value + 1];
+ Encoding.UTF8.GetBytes(managedString, 0, managedString.Length, buffer, 0);
+ Marshal.Copy(buffer, 0, ptr, buffer.Length);
+ }
+
+ public static string StringFromNativeUtf8(IntPtr nativeUtf8)
+ {
+ int len = 0;
+ while (Marshal.ReadByte(nativeUtf8, len) != 0) ++len;
+ byte[] buffer = new byte[len];
+ Marshal.Copy(nativeUtf8, buffer, 0, buffer.Length);
+ return Encoding.UTF8.GetString(buffer);
+ }
+ }
+
+ public delegate void StructAction<T>(ref T st);
+ public static void EditStruct<T>(IntPtr ptr, StructAction<T> f)
+ {
+ var str = Marshal.PtrToStructure<T>(ptr);
+ f(ref str);
+ Marshal.StructureToPtr<T>(str, ptr, false);
+ }
+
+ const string LIBNAME = "pgf.dll";
+ const CallingConvention CC = CallingConvention.Cdecl;
+
+
+ #region Basic
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern IntPtr pgf_read([MarshalAs(UnmanagedType.LPStr)] string fpath, IntPtr pool, IntPtr err);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern IntPtr pgf_read_in(IntPtr in_, IntPtr pool, IntPtr tmp_pool, IntPtr err);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern void pgf_concrete_load(IntPtr concr, IntPtr in_, IntPtr err);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern IntPtr pgf_abstract_name(IntPtr pgf);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern IntPtr pgf_concrete_name(IntPtr concr);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern IntPtr pgf_start_cat(IntPtr pgf, IntPtr pool);
+
+ #endregion
+
+ #region Linearization
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern void pgf_linearize(IntPtr concr, IntPtr expr, IntPtr out_, IntPtr err);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern IntPtr pgf_lzr_concretize(IntPtr concr, IntPtr expr, IntPtr err, IntPtr tmp_pool);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern IntPtr pgf_lzr_wrap_linref(IntPtr ctree, IntPtr tmp_pool);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern void pgf_lzr_linearize(IntPtr concr, IntPtr ctree, int lin_idx, ref IntPtr funcs, IntPtr tmp_pool);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern void pgf_lzr_linearize_simple(IntPtr concr, IntPtr ctree, int lin_idx, IntPtr out_, IntPtr exn, IntPtr tmp_pool);
+ #endregion
+
+
+ #region Iteration
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern void pgf_iter_languages(IntPtr pgf, ref GuMapItor itor, IntPtr err);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern void pgf_iter_categories(IntPtr pgf, ref GuMapItor itor, IntPtr err);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern void pgf_iter_functions(IntPtr pgf, ref GuMapItor itor, IntPtr err);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern void pgf_iter_functions_by_cat(IntPtr pgf, IntPtr catNameStr, ref GuMapItor itor, IntPtr err);
+
+ #endregion
+
+ #region Type
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern IntPtr pgf_function_type(IntPtr pgf, IntPtr funNameStr);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern IntPtr pgf_read_type(IntPtr in_, IntPtr pool, IntPtr err);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern void pgf_print_type(IntPtr expr, IntPtr ctxt, int prec, IntPtr output, IntPtr err);
+ #endregion
+
+ #region Expression
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern void pgf_print_expr(IntPtr expr, IntPtr ctxt, int prec, IntPtr output, IntPtr err);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern IntPtr pgf_read_expr(IntPtr in_, IntPtr pool, IntPtr err);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern IntPtr pgf_compute(IntPtr pgf, IntPtr expr, IntPtr err, IntPtr tmp_pool, IntPtr res_pool);
+
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern IntPtr pgf_generate_all(IntPtr pgf, IntPtr type, IntPtr err, IntPtr iter_pool, IntPtr out_pool);
+ #endregion
+
+ #region Concrete
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern IntPtr pgf_parse_with_heuristics(IntPtr concr, IntPtr cat, IntPtr sentence,
+ double heuristics, IntPtr callbacks, IntPtr exn,
+ IntPtr parsePl, IntPtr exprPl);
+ #endregion
+
+ #region Callbacks
+ [DllImport(LIBNAME, CallingConvention = CC)]
+ public static extern IntPtr pgf_new_callbacks_map(IntPtr concr, IntPtr pool);
+ #endregion
+
+ //public delegate void GuMapItorFn(IntPtr self, [MarshalAs(UnmanagedType.LPStr)] string key, IntPtr value, IntPtr err);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void GuMapItorFn(IntPtr self, IntPtr key, IntPtr value, IntPtr err);
+
+
+ /*
+ public delegate void GuFinalizerFn(IntPtr self);
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct GuFinalizer
+ {
+ [MarshalAs(UnmanagedType.FunctionPtr)]
+ public GuFinalizerFn fn;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct PgfConcr
+ {
+ public IntPtr name, abstr, cflags, printnames,
+ ccats, fun_indices, coerce_idx, cncfuns,
+ sequences, cnccats;
+ public int total_cats;
+ public IntPtr pool;
+ GuFinalizer fin;
+ }*/
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct GuMapItor
+ {
+ [MarshalAs(UnmanagedType.FunctionPtr)]
+ public GuMapItorFn fn;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct PgfExprProb
+ {
+ public float prob;
+ public IntPtr expr; // PgfExpr type (not pointer, but typedef PgfExpr -> GuVariant -> uintptr_t)
+ }
+
+
+ #region Linearization callbacks
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void LinFuncSymbolToken(IntPtr self, IntPtr token);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void LinFuncBeginPhrase(IntPtr self, IntPtr cat, int fid, int lindex, IntPtr fun);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void LinFuncEndPhrase(IntPtr self, IntPtr cat, int fid, int lindex, IntPtr fun);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void LinFuncSymbolNonexistant(IntPtr self);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void LinFuncSymbolBinding(IntPtr self);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void LinFuncSymbolCapitalization(IntPtr self);
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct PgfLinFuncs
+ {
+ [MarshalAs(UnmanagedType.FunctionPtr)]
+ public LinFuncSymbolToken symbol_token;
+
+ [MarshalAs(UnmanagedType.FunctionPtr)]
+ public LinFuncBeginPhrase begin_prase;
+
+ [MarshalAs(UnmanagedType.FunctionPtr)]
+ public LinFuncEndPhrase end_phrase;
+
+ [MarshalAs(UnmanagedType.FunctionPtr)]
+ public LinFuncSymbolNonexistant symbol_ne;
+
+ [MarshalAs(UnmanagedType.FunctionPtr)]
+ public LinFuncSymbolBinding symbol_bind;
+
+ [MarshalAs(UnmanagedType.FunctionPtr)]
+ public LinFuncSymbolCapitalization symbol_capit;
+ }
+
+ #endregion
+
+
+ /*
+ [StructLayout(LayoutKind.Sequential)]
+ public struct PGFClosure
+ {
+ public GuMapItor fn;
+ public IntPtr grammar;
+ public IntPtr obj;
+ }*/
+
+ public static string ReadString(Action<IntPtr, NativeGU.NativeExceptionContext> f)
+ {
+ var pool = new NativeGU.NativeMemoryPool();
+ var exn = new NativeGU.NativeExceptionContext(pool);
+ var sbuf = NativeGU.gu_new_string_buf(pool.Ptr);
+ var output = NativeGU.gu_string_buf_out(sbuf);
+ f(output, exn);
+ if (exn.IsRaised) throw new Exception();
+ var strPtr = NativeGU.gu_string_buf_freeze(sbuf, pool.Ptr);
+ var str = Native.NativeString.StringFromNativeUtf8(strPtr);
+ return str;
+ }
+
+ public delegate void MapIterFunc(IntPtr pgf, ref GuMapItor fn, IntPtr err);
+ public delegate void IterNameFunc(IntPtr pgf, IntPtr name, ref GuMapItor fn, IntPtr err);
+
+ public class IterFuncCurryName
+ {
+ private IntPtr name;
+ private IterNameFunc func;
+ public IterFuncCurryName(IterNameFunc f, IntPtr name)
+ {
+ this.func = f;
+ this.name = name;
+ }
+
+ public void IterFunc(IntPtr pgf, ref GuMapItor fn, IntPtr err)
+ {
+ func(pgf, name, ref fn, err);
+ }
+ }
+
+ public static void MapIter(MapIterFunc iter, IntPtr _pgf, Action<string, IntPtr> action)
+ {
+ var pool = new NativeGU.NativeMemoryPool();
+ var exn = new NativeGU.NativeExceptionContext(pool);
+ var f = new GuMapItor()
+ {
+ fn = (self, key, value, _err) =>
+ {
+ action(Native.NativeString.StringFromNativeUtf8(key), value);
+ if (exn.IsRaised) throw new Exception();
+ }
+ };
+
+ iter(_pgf, ref f, exn.Ptr);
+ }
+ }
+}