using System; using System.Collections.Generic; using System.Linq; using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; using System.Security; using System.Text; using PorygonSharp.DiagnosticHandling; namespace PorygonSharp { [StructLayout(LayoutKind.Sequential)] internal struct InternalScript { private readonly IntPtr _evaluator; private readonly IntPtr _scriptVariables; private readonly IntPtr _boundScript; private readonly SharedPointer _returnValue; internal readonly IntPtr Diagnostics; } [StructLayout(LayoutKind.Sequential)] internal struct SharedPointer { private IntPtr _pointer; private int _references; } public class Script : IDisposable { private readonly IntPtr _internalScriptHandle; private readonly InternalScript _internalScript; private Diagnostics _diagnostics; public Diagnostics Diagnostics => _diagnostics ?? (_diagnostics = new Diagnostics(_internalScript.Diagnostics)); public Script(string s) { _internalScriptHandle = Create(s); _internalScript = Marshal.PtrToStructure(_internalScriptHandle); } public void Dispose() { Marshal.FreeHGlobal(_internalScriptHandle); Diagnostics.Dispose(); } public void Evaluate() { Evaluate(_internalScriptHandle); } public EvalValue GetLastValue() { var ptr = GetLastValue(_internalScriptHandle); return new EvalValue(ptr); } public bool HasVariable(string key) { return HasVariable(_internalScriptHandle, key); } public EvalValue GetVariable(string key) { var ptr = GetVariable(_internalScriptHandle, key); return new EvalValue(ptr); } public bool HasFunction(string key) { return HasFunction(_internalScriptHandle, key); } public EvalValue CallFunction(string key, params object[] parameters) { var scriptParameters = parameters.Select(x => new EvalValue(x).GetPointer()).ToArray(); var ptr = CallFunction(_internalScriptHandle, key, scriptParameters, scriptParameters.Length); return new EvalValue(ptr); } [DllImport("libPorygonLang", EntryPoint = "CreateScript", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr Create([MarshalAs(UnmanagedType.LPWStr)]string s); [DllImport("libPorygonLang", EntryPoint = "EvaluateScript", CallingConvention = CallingConvention.Cdecl)] private static extern void Evaluate(IntPtr script); [DllImport("libPorygonLang", EntryPoint = "GetLastValue", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr GetLastValue(IntPtr script); [DllImport("libPorygonLang", EntryPoint = "HasVariable", CallingConvention = CallingConvention.Cdecl)] private static extern bool HasVariable(IntPtr script, [MarshalAs(UnmanagedType.LPWStr)]string key); [DllImport("libPorygonLang", EntryPoint = "GetVariable", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr GetVariable(IntPtr script, [MarshalAs(UnmanagedType.LPWStr)]string key); [DllImport("libPorygonLang", EntryPoint = "HasFunction", CallingConvention = CallingConvention.Cdecl)] private static extern bool HasFunction(IntPtr script, [MarshalAs(UnmanagedType.LPWStr)]string key); [DllImport("libPorygonLang", EntryPoint = "CallFunction", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr CallFunction(IntPtr script, [MarshalAs(UnmanagedType.LPWStr)]string key, IntPtr[] parameters, int parameterCount); } }