summaryrefslogtreecommitdiff
path: root/src/runtime/dotNet/Expr/Literal.cs
blob: daf515c6376c65660cad9b3774caf2c7b105d2a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace PGFSharp
{
    public class LiteralStringExpr : LiteralExpr
    {
        internal LiteralStringExpr(IntPtr expr, NativeGU.NativeMemoryPool pool) : base(expr, pool) { }
        public LiteralStringExpr(string s) : base()
        {
            _pool = new NativeGU.NativeMemoryPool();

            var exprTag = (byte)(int)PgfExprTag.PGF_EXPR_LIT;
            IntPtr litPtr = NativeGU.gu_alloc_variant(exprTag,
                (UIntPtr)Marshal.SizeOf<NativePgfExprLit>(), UIntPtr.Zero, ref _ptr, _pool.Ptr);

            Native.EditStruct<NativePgfExprLit>(litPtr, (ref NativePgfExprLit lit) => {
                MkStringVariant((byte)PgfLiteralTag.PGF_LITERAL_STR, s, ref lit.lit);
            });
        }

        public override R Accept<R>(IVisitor<R> visitor)
        {
            return visitor.VisitLiteralString(Value);
        }

        public string Value => Native.NativeString.StringFromNativeUtf8(LitDataPtr);
    }

    public class LiteralIntExpr : LiteralExpr
    {
        internal LiteralIntExpr(IntPtr expr, NativeGU.NativeMemoryPool pool) : base(expr, pool) { }
        public LiteralIntExpr(int val) : base()
        {
            Initialize<NativePgfLiteralInt>(PgfLiteralTag.PGF_LITERAL_INT,
                (ref NativePgfLiteralInt ilit) => ilit.val = val);
        }

        public override R Accept<R>(IVisitor<R> visitor)
        {
            return visitor.VisitLiteralInt(Value);
        }

        public int Value => Marshal.PtrToStructure<NativePgfLiteralInt>(LitDataPtr).val;
        
		[StructLayout(LayoutKind.Sequential)]
		private struct NativePgfLiteralInt { public int val;    }
    }

    public class LiteralFloatExpr : LiteralExpr
    {
        internal LiteralFloatExpr(IntPtr expr, NativeGU.NativeMemoryPool pool) : base(expr, pool) { }
        public LiteralFloatExpr(double val) : base()
        {
            Initialize<NativePgfLiteralFlt>(PgfLiteralTag.PGF_LITERAL_FLT,
                (ref NativePgfLiteralFlt flit) => flit.val = val);
        }

        public override R Accept<R>(IVisitor<R> visitor)
        {
            return visitor.VisitLiteralFloat(Value);
        }

        public double Value => Marshal.PtrToStructure<NativePgfLiteralFlt>(LitDataPtr).val;
        
   		[StructLayout(LayoutKind.Sequential)]
		private struct NativePgfLiteralFlt { public double val; }
    }

	public abstract class LiteralExpr : Expr
    {
        internal LiteralExpr(IntPtr expr, NativeGU.NativeMemoryPool pool) : base(expr, pool) { }
        internal LiteralExpr() { }

        internal new static Expr FromPtr(IntPtr expr, NativeGU.NativeMemoryPool pool)
        {
            var dataPtr = NativeGU.gu_variant_open(expr).Data; // PgfExprLit* 
            var data = Marshal.PtrToStructure<NativePgfExprLit>(dataPtr);
            var literalTag = (PgfLiteralTag)NativeGU.gu_variant_open(data.lit).Tag;

            switch(literalTag)
            {
                case PgfLiteralTag.PGF_LITERAL_STR:
                    return new LiteralStringExpr(expr, pool);
                case PgfLiteralTag.PGF_LITERAL_INT:
                    return new LiteralIntExpr(expr, pool);
                case PgfLiteralTag.PGF_LITERAL_FLT:
                    return new LiteralFloatExpr(expr, pool);
                default:
                    throw new ArgumentException();
            }
        }

        internal void Initialize<TNative>(PgfLiteralTag litTag, Native.StructAction<TNative> setValue, UIntPtr? size = null) {
            _pool = new NativeGU.NativeMemoryPool();

            var exprTag = (byte)(int)PgfExprTag.PGF_EXPR_LIT;
			IntPtr litPtr = NativeGU.gu_alloc_variant ( exprTag,
				(UIntPtr)Marshal.SizeOf<NativePgfExprLit>(), UIntPtr.Zero, ref _ptr, _pool.Ptr);

			Native.EditStruct<NativePgfExprLit> (litPtr, (ref NativePgfExprLit lit) => {
				IntPtr ilitPtr = NativeGU.gu_alloc_variant ((byte)litTag,
					(UIntPtr)Marshal.SizeOf<TNative> (), UIntPtr.Zero, ref lit.lit, _pool.Ptr);

				Native.EditStruct<TNative>(ilitPtr, setValue); 
			});
		}

		// Deref DatPtr to det PgfExprLit.
		private NativePgfExprLit Data => Marshal.PtrToStructure<NativePgfExprLit>(DataPtr);

		private PgfLiteralTag LiteralTag => (PgfLiteralTag) NativeGU.gu_variant_open(Data.lit).Tag;
		internal IntPtr LitDataPtr => NativeGU.gu_variant_open(Data.lit).Data;

		internal enum PgfLiteralTag {
			PGF_LITERAL_STR,
			PGF_LITERAL_INT,
			PGF_LITERAL_FLT,
			PGF_LITERAL_NUM_TAGS
		}

		[StructLayout(LayoutKind.Sequential)]
		internal struct NativePgfExprLit    { public IntPtr lit; }
	}
}