summaryrefslogtreecommitdiff
path: root/src/runtime/dotNet/PGF.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/dotNet/PGF.cs')
-rw-r--r--src/runtime/dotNet/PGF.cs53
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;
+ }
+ }
}
}