From e1cec06f7483ea913885a7918728a1c3f8ece650 Mon Sep 17 00:00:00 2001 From: krasimir Date: Wed, 31 May 2017 13:48:36 +0000 Subject: .NET binding to GF by Bjørnar Luteberget MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/runtime/dotNet/PGF.cs | 157 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 src/runtime/dotNet/PGF.cs (limited to 'src/runtime/dotNet/PGF.cs') diff --git a/src/runtime/dotNet/PGF.cs b/src/runtime/dotNet/PGF.cs new file mode 100644 index 000000000..e6efae1d5 --- /dev/null +++ b/src/runtime/dotNet/PGF.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace PGFSharp +{ + /// + /// Grammatical Framework grammar. + /// + public class PGF + { + private PGF() { } + + IntPtr _ptr; + NativeGU.NativeMemoryPool pool; + + /// + /// Read grammar from PGF file. + /// + /// filename + /// + public static PGF ReadPGF(string fn) + { + var obj = new PGF(); + var exn = new NativeGU.NativeExceptionContext(new NativeGU.NativeMemoryPool()); + obj.pool = new NativeGU.NativeMemoryPool(); + obj._ptr = Native.pgf_read(fn, obj.pool.Ptr, exn.Ptr); + if (exn.IsRaised) + { + throw new PGFError($"Could not read PGF from file {fn}. ({System.IO.Directory.GetCurrentDirectory()})"); + } + return obj; + } + + public override string ToString() => $"Grammar:{Name}, {String.Join(", ", Languages.Keys)}"; + + /// + /// Name of the abstract grammar. + /// + public string Name => Native.NativeString.StringFromNativeUtf8(Native.pgf_abstract_name(_ptr)); + + /// + /// Default category of the grammar. + /// + public Type StartCat => Type.FromPtr(Native.pgf_start_cat(_ptr, pool.Ptr), pool); + + /// + /// All concrete grammars in the language. + /// + public Dictionary Languages + { + get + { + var dict = new Dictionary(); + Native.MapIter(Native.pgf_iter_languages, _ptr, (k, v) => dict[k] = Concr.FromPtr(this, dereference(v))); + return dict; + } + } + + private IntPtr dereference(IntPtr ptr) + { + return (IntPtr)Marshal.PtrToStructure(ptr, typeof(IntPtr)); + } + + /// + /// All categories in the abstract grammar. + /// + public IEnumerable Categories => GetStringList(Native.pgf_iter_categories); + + /// + /// All functions in the abstract grammar. + /// + public IEnumerable Functions => GetStringList(Native.pgf_iter_functions); + + /// + /// All functions producing the given category name. + /// + /// + /// + public IEnumerable FunctionByCategory(string catName) + { + using (var str = new Native.NativeString(catName)) + { + return GetStringList(new Native.IterFuncCurryName(Native.pgf_iter_functions_by_cat, str.Ptr).IterFunc); + } + } + + /// + /// Get type from function name. + /// + /// + /// + public Type FunctionType(string funName) + { + using (var str = new Native.NativeString(funName)) + { + var typePtr = Native.pgf_function_type(_ptr, str.Ptr); + if (typePtr == IntPtr.Zero) throw new NullReferenceException(); + return Type.FromPtr(typePtr, pool); + } + } + + /// + /// Reduce expression. + /// + /// + /// + public Expr Compute(Expr expr) + { + var tmp_pool = new NativeGU.NativeMemoryPool(); + var exn = new NativeGU.NativeExceptionContext(tmp_pool); + var result_pool = new NativeGU.NativeMemoryPool(); + var newExpr = Native.pgf_compute(_ptr, expr.Ptr, exn.Ptr, pool.Ptr, result_pool.Ptr); + + if (exn.IsRaised || newExpr == IntPtr.Zero) + { + throw new PGFError("Could not reduce expression."); + } + else + { + return Expr.FromPtr(newExpr, result_pool); + } + } + + /// + /// Enumerate all expressions in the given category. + /// + /// + /// + public IEnumerable GenerateAll(Type cat = null) + { + cat = cat ?? StartCat; + var tmp_pool = new NativeGU.NativeMemoryPool(); + var exn = new NativeGU.NativeExceptionContext(tmp_pool); + var result_pool = new NativeGU.NativeMemoryPool(); + IntPtr ptr = IntPtr.Zero; + var iterator = Native.pgf_generate_all(this._ptr, cat.Ptr, exn.Ptr, tmp_pool.Ptr, result_pool.Ptr); + + return NativeGU.IteratorToIEnumerable(iterator, tmp_pool.Ptr).Select(p => + { + var exprProb = Marshal.PtrToStructure(ptr); + return Expr.FromPtr(exprProb.expr, result_pool); + + }); + } + + private IEnumerable GetStringList(Native.MapIterFunc f) + { + var c = new List(); + Native.MapIter(f, _ptr, (k, v) => c.Add(k)); + return c; + } + } +} -- cgit v1.2.3