using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace PGFSharp
{
///
/// A class for types in the abstract syntax of a grammar.
///
public class Type
{
private IntPtr _ptr;
internal IntPtr Ptr => _ptr;
private NativeGU.NativeMemoryPool _pool;
private Type() { }
internal static Type FromPtr(IntPtr type, NativeGU.NativeMemoryPool pool)
{
var t = new Type();
t._ptr = type;
t._pool = pool;
return t;
}
public override string ToString() =>
Native.ReadString((output,exn) => Native.pgf_print_type(_ptr, IntPtr.Zero, 0, output, exn.Ptr));
private PgfType Data => Marshal.PtrToStructure(_ptr);
///
/// Read type from string.
///
///
///
public static Type ReadType(string typeStr)
{
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(typeStr))
{
var in_ = NativeGU.gu_data_in(strNative.Ptr, strNative.Size, tmp_pool.Ptr);
var typ = Native.pgf_read_type(in_, result_pool.Ptr, tmp_pool.Ptr, exn.Ptr);
if (exn.IsRaised || typ == IntPtr.Zero)
{
throw new PGFError();
}
else
{
return Type.FromPtr(typ, result_pool);
}
}
}
///
/// Get the hypotheses of a type (function argument types).
///
public IEnumerable Hypotheses
{
get
{
var n_hypos = NativeGU.SeqLength(Data.hypos);
for (int i = 0; i < n_hypos; i++)
{
var hypo = NativeGU.gu_seq_index(Data.hypos, i);
var type = Type.FromPtr(hypo.type, this._pool);
yield return type;
}
}
}
[StructLayout(LayoutKind.Sequential)]
internal struct PgfType
{
public IntPtr hypos; // GuSeq of PgfHypo
public IntPtr cid;
public UIntPtr n_exprs;
public IntPtr exprs;
}
[StructLayout(LayoutKind.Sequential)]
private struct PgfHypo
{
public int pgfBindType; // enum
public IntPtr cid; // PgfCId (string)
public IntPtr type; // PgfType*
}
}
}