diff options
| author | Krasimir Angelov <kr.angelov@gmail.com> | 2017-08-30 11:18:03 +0200 |
|---|---|---|
| committer | Krasimir Angelov <kr.angelov@gmail.com> | 2017-08-30 11:18:03 +0200 |
| commit | dd8a9ed587ef4f30fd8dba67abce6d348362e2e3 (patch) | |
| tree | 6c63511176f579e3d4de2637343b65dee40ee8a8 /src/runtime/dotNet/PGF.cs | |
| parent | 14f1fedfe4b9e12343327956607ac5839e8bbdce (diff) | |
Embedded grammars in C#
Diffstat (limited to 'src/runtime/dotNet/PGF.cs')
| -rw-r--r-- | src/runtime/dotNet/PGF.cs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/runtime/dotNet/PGF.cs b/src/runtime/dotNet/PGF.cs index 6fb7bad65..ef10d8f9f 100644 --- a/src/runtime/dotNet/PGF.cs +++ b/src/runtime/dotNet/PGF.cs @@ -1,4 +1,5 @@ using System; +using System.Dynamic; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; @@ -154,5 +155,57 @@ namespace PGFSharp Native.MapIter(f, _ptr, (k, v) => c.Add(k)); return c; } + + public dynamic Embed() { + return new GrammarEmbedding(this); + } + + private class GrammarEmbedding : DynamicObject { + private PGF gr; + + public GrammarEmbedding(PGF gr) { + this.gr = gr; + } + + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + result = null; + + using (var str = new Native.NativeString(binder.Name)) + { + var typePtr = Native.pgf_function_type(gr._ptr, str.Ptr); + if (typePtr == IntPtr.Zero) + return false; + } + + result = new ApplicationExpr(binder.Name, new Expr[0]); + return true; + } + + public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { + result = null; + + uint n_hypos = 0; + using (var str = new Native.NativeString(binder.Name)) + { + var typePtr = Native.pgf_function_type(gr._ptr, str.Ptr); + if (typePtr == IntPtr.Zero) + return false; + n_hypos = NativeGU.SeqLength(Marshal.PtrToStructure<Type.PgfType>(typePtr).hypos); + } + + if (args.Length != n_hypos) + return false; + + Expr[] exprs = new Expr[args.Length]; + for (var i = 0; i < args.Length; i++) { + exprs[i] = args[i] as Expr; + if (exprs[i] == null) + return false; + } + result = new ApplicationExpr(binder.Name, exprs); + return true; + } + } } } |
