summaryrefslogtreecommitdiff
path: root/src/runtime/dotNet
diff options
context:
space:
mode:
authorKrasimir Angelov <kr.angelov@gmail.com>2017-08-30 11:18:03 +0200
committerKrasimir Angelov <kr.angelov@gmail.com>2017-08-30 11:18:03 +0200
commitdd8a9ed587ef4f30fd8dba67abce6d348362e2e3 (patch)
tree6c63511176f579e3d4de2637343b65dee40ee8a8 /src/runtime/dotNet
parent14f1fedfe4b9e12343327956607ac5839e8bbdce (diff)
Embedded grammars in C#
Diffstat (limited to 'src/runtime/dotNet')
-rw-r--r--src/runtime/dotNet/PGF.cs53
-rw-r--r--src/runtime/dotNet/Type.cs2
2 files changed, 54 insertions, 1 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;
+ }
+ }
}
}
diff --git a/src/runtime/dotNet/Type.cs b/src/runtime/dotNet/Type.cs
index f60ab7cf1..bf31f8117 100644
--- a/src/runtime/dotNet/Type.cs
+++ b/src/runtime/dotNet/Type.cs
@@ -73,7 +73,7 @@ namespace PGFSharp
}
[StructLayout(LayoutKind.Sequential)]
- private struct PgfType
+ internal struct PgfType
{
public IntPtr hypos; // GuSeq of PgfHypo
public IntPtr cid;