diff options
| author | krasimir <krasimir@chalmers.se> | 2017-05-31 13:48:36 +0000 |
|---|---|---|
| committer | krasimir <krasimir@chalmers.se> | 2017-05-31 13:48:36 +0000 |
| commit | e1cec06f7483ea913885a7918728a1c3f8ece650 (patch) | |
| tree | a79d46b37747a60d285090e22572ea4f3810814d /src/runtime/dotNet/Expr.cs | |
| parent | 2a8d2806e4612d320de0155d8cdbbd68cd1d1995 (diff) | |
.NET binding to GF by Bjørnar Luteberget
Diffstat (limited to 'src/runtime/dotNet/Expr.cs')
| -rw-r--r-- | src/runtime/dotNet/Expr.cs | 133 |
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)); + + } +} |
