summaryrefslogtreecommitdiff
path: root/src/runtime/dotNet/Expr.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/Expr.cs
parent2a8d2806e4612d320de0155d8cdbbd68cd1d1995 (diff)
.NET binding to GF by Bjørnar Luteberget
Diffstat (limited to 'src/runtime/dotNet/Expr.cs')
-rw-r--r--src/runtime/dotNet/Expr.cs133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/runtime/dotNet/Expr.cs b/src/runtime/dotNet/Expr.cs
new file mode 100644
index 000000000..a65b281bf
--- /dev/null
+++ b/src/runtime/dotNet/Expr.cs
@@ -0,0 +1,133 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PGFSharp
+{
+ internal class UnsupportedExpr : Expr
+ {
+ internal UnsupportedExpr(IntPtr expr, NativeGU.NativeMemoryPool pool) : base(expr, pool) { }
+ public override R Accept<R>(IVisitor<R> visitor)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public abstract class Expr
+ {
+ internal IntPtr DataPtr => NativeGU.gu_variant_open(_ptr).Data; // PgfExprLit*
+ internal PgfExprTag Tag => (PgfExprTag)NativeGU.gu_variant_open(_ptr).Tag;
+
+ internal IntPtr MkStringVariant(byte tag, string s, ref IntPtr out_)
+ {
+ var size = Encoding.UTF8.GetByteCount(s);
+ IntPtr slitPtr = NativeGU.gu_alloc_variant(tag,
+ (UIntPtr)(size + 1), UIntPtr.Zero, ref out_, _pool.Ptr);
+ Native.NativeString.CopyToPreallocated(s, slitPtr);
+ return slitPtr;
+ }
+
+ /// <summary>
+ /// Read expression from string.
+ /// </summary>
+ /// <param name="exprStr"></param>
+ /// <returns></returns>
+ public Expr ReadExpr(string exprStr)
+ {
+ var tmp_pool = new NativeGU.NativeMemoryPool();
+ var exn = new NativeGU.NativeExceptionContext(tmp_pool);
+ var result_pool = new NativeGU.NativeMemoryPool();
+ using (var strNative = new Native.NativeString(exprStr))
+ {
+ var in_ = NativeGU.gu_data_in(strNative.Ptr, strNative.Size, tmp_pool.Ptr);
+ var expr = Native.pgf_read_expr(in_, result_pool.Ptr, exn.Ptr);
+ if (exn.IsRaised || expr == IntPtr.Zero)
+ {
+ throw new PGFError();
+ }
+ else
+ {
+ return Expr.FromPtr(expr, result_pool);
+ }
+ }
+ }
+
+ internal enum PgfExprTag
+ {
+ PGF_EXPR_ABS,
+ PGF_EXPR_APP,
+ PGF_EXPR_LIT,
+ PGF_EXPR_META,
+ PGF_EXPR_FUN,
+ PGF_EXPR_VAR,
+ PGF_EXPR_TYPED,
+ PGF_EXPR_IMPL_ARG,
+ PGF_EXPR_NUM_TAGS // not used
+ };
+
+ public interface IVisitor<R>
+ {
+ R VisitLiteralInt(int value);
+ R VisitLiteralFloat(double value);
+ R VisitLiteralString(string value);
+ R VisitApplication(string fname, Expr[] args);
+
+ //R VisitMetaVariable (int id); Dont' care about this for now...
+
+ // Remove this, Function objects use VisitApplication with empty args instead.
+ //R VisitFunction (string fname); // Will this be used?
+ }
+
+ public class Visitor<R> : IVisitor<R>
+ {
+ public Func<int, R> fVisitLiteralInt { get; set; } = null;
+ public R VisitLiteralInt(int x1) => fVisitLiteralInt(x1);
+ public Func<double, R> fVisitLiteralFlt { get; set; } = null;
+ public R VisitLiteralFloat(double x1) => fVisitLiteralFlt(x1);
+ public Func<string, R> fVisitLiteralStr { get; set; } = null;
+ public R VisitLiteralString(string x1) => fVisitLiteralStr(x1);
+ public Func<string, Expr[], R> fVisitApplication { get; set; } = null;
+ public R VisitApplication(string x1, Expr[] x2) => fVisitApplication(x1, x2);
+ }
+
+ public abstract R Accept<R>(IVisitor<R> visitor);
+
+ internal IntPtr _ptr = IntPtr.Zero;
+ internal NativeGU.NativeMemoryPool _pool;
+ internal IntPtr Ptr => _ptr;
+
+ internal Expr() { }
+ internal Expr(IntPtr ptr, NativeGU.NativeMemoryPool pool)
+ {
+ _ptr = ptr; _pool = pool;
+ }
+
+ // Factories
+ private static Dictionary<PgfExprTag, Func<IntPtr, NativeGU.NativeMemoryPool, Expr>> factories =
+ new Dictionary<PgfExprTag, Func<IntPtr, NativeGU.NativeMemoryPool, Expr>>{
+
+ { PgfExprTag.PGF_EXPR_LIT, (e, p) => LiteralExpr.FromPtr (e, p) },
+ { PgfExprTag.PGF_EXPR_APP, (e, p) => new ApplicationExpr (e, p) },
+ { PgfExprTag.PGF_EXPR_FUN, (e, p) => new FunctionExpr (e, p) },
+ { PgfExprTag.PGF_EXPR_META, (e, p) => new MetaVariableExpr (e, p) }
+ };
+
+ internal static Expr FromPtr(IntPtr expr, NativeGU.NativeMemoryPool pool)
+ {
+ var Tag = (PgfExprTag)NativeGU.gu_variant_open(expr).Tag;
+ if (factories.ContainsKey(Tag))
+ {
+ return factories[Tag](expr, pool);
+ }
+ else
+ return new UnsupportedExpr(expr, pool);
+ }
+
+ public override string ToString() =>
+ Native.ReadString((output,exn) => Native.pgf_print_expr(_ptr, IntPtr.Zero, 0, output, exn.Ptr));
+
+ }
+}