PorygonSharp/PorygonSharp/Script.cs

100 lines
3.8 KiB
C#

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<InternalScript>(_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);
}
}