Implements new handling of exceptions

This commit is contained in:
Deukhoofd 2019-07-27 19:45:39 +02:00
parent d452a740f0
commit 4a42254b62
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
6 changed files with 101 additions and 32 deletions

View File

@ -8,14 +8,14 @@ namespace PorygonSharp
public static Action<string> Print = Console.WriteLine;
private delegate void InternalPrintDelegate(IntPtr ptr);
private static InternalPrintDelegate InternalPrint = PrintFunc;
private static readonly InternalPrintDelegate InternalPrint = PrintFunc;
static CoreSetup()
{
SetPrintFunc();
}
internal static void SetPrintFunc()
private static void SetPrintFunc()
{
var funcPtr = Marshal.GetFunctionPointerForDelegate(InternalPrint);
InternalSetPrintFunc(funcPtr);

View File

@ -0,0 +1,47 @@
using System;
using System.Runtime.InteropServices;
namespace PorygonSharp
{
internal struct EvaluateResult : IDisposable
{
[StructLayout(LayoutKind.Sequential)]
private struct EvaluateResultInternal
{
public readonly IntPtr Value;
public readonly byte Result;
}
private readonly IntPtr _ptr;
private readonly EvaluateResultInternal _internal;
public EvaluateResult(IntPtr ptr)
{
_ptr = ptr;
_internal = Marshal.PtrToStructure<EvaluateResultInternal>(ptr);
}
public EvalValue GetValue()
{
return !IsSuccess() ? null : new EvalValue(_internal.Value);
}
public bool IsSuccess()
{
return _internal.Result == 0;
}
public string GetError()
{
return GetErrorMessage(_ptr);
}
public void Dispose()
{
Marshal.FreeHGlobal(_ptr);
}
[DllImport("libPorygonLang", EntryPoint = "GetResultError", CallingConvention = CallingConvention.Cdecl)]
private static extern string GetErrorMessage(IntPtr ptr);
}
}

View File

@ -0,0 +1,12 @@
using System;
namespace PorygonSharp
{
public class EvaluationException : Exception
{
public EvaluationException(string message) : base(message)
{
}
}
}

View File

@ -1,7 +1,9 @@
using System;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Security;
using PorygonSharp.DiagnosticHandling;
namespace PorygonSharp
@ -56,18 +58,20 @@ namespace PorygonSharp
{
Marshal.FreeHGlobal(_internalScriptHandle);
}
public void Evaluate()
public EvalValue Evaluate()
{
Evaluate(_internalScriptHandle);
var ptr = Evaluate(_internalScriptHandle);
using (var result = new EvaluateResult(ptr))
{
if (result.IsSuccess())
{
return result.GetValue();
}
throw new EvaluationException(result.GetError());
}
}
public EvalValue GetLastValue()
{
var ptr = GetLastValue(_internalScriptHandle);
return new EvalValue(ptr);
}
public bool HasVariable(string key)
{
return HasVariable(_internalScriptHandle, key);
@ -94,9 +98,7 @@ namespace PorygonSharp
[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);
private static extern IntPtr Evaluate(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)]

View File

@ -36,10 +36,9 @@ namespace PorygonSharpTests
{
using (var script = new Script("1+10"))
{
script.Evaluate();
var lastVal = script.GetLastValue();
Assert.AreEqual(TypeClass.Number, lastVal.GetTypeClass());
var val = lastVal.EvaluateInteger();
var result = script.Evaluate();
Assert.AreEqual(TypeClass.Number, result.GetTypeClass());
var val = result.EvaluateInteger();
Assert.AreEqual(11, val);
}
}
@ -49,10 +48,9 @@ namespace PorygonSharpTests
{
using (var script = new Script("1+10.24"))
{
script.Evaluate();
var lastVal = script.GetLastValue();
Assert.AreEqual(TypeClass.Number, lastVal.GetTypeClass());
var val = lastVal.EvaluateFloat();
var result = script.Evaluate();
Assert.AreEqual(TypeClass.Number, result.GetTypeClass());
var val = result.EvaluateFloat();
Assert.AreEqual(11.24d, val, 5);
}
}
@ -62,10 +60,9 @@ namespace PorygonSharpTests
{
using (var script = new Script("true and true"))
{
script.Evaluate();
var lastVal = script.GetLastValue();
Assert.AreEqual(TypeClass.Bool, lastVal.GetTypeClass());
var val = lastVal.EvaluateBool();
var result = script.Evaluate();
Assert.AreEqual(TypeClass.Bool, result.GetTypeClass());
var val = result.EvaluateBool();
Assert.AreEqual(true, val);
}
}
@ -75,10 +72,9 @@ namespace PorygonSharpTests
{
using (var script = new Script("'foo' + 'bar'"))
{
script.Evaluate();
var lastVal = script.GetLastValue();
Assert.AreEqual(TypeClass.String, lastVal.GetTypeClass());
var val = lastVal.EvaluateString();
var result = script.Evaluate();
Assert.AreEqual(TypeClass.String, result.GetTypeClass());
var val = result.EvaluateString();
Assert.AreEqual("foobar", val);
}
}
@ -102,7 +98,9 @@ namespace PorygonSharpTests
using (var script = new Script("function add(number a, number b) result = a + b end"))
{
script.Evaluate();
Assert.That(script.HasFunction("add"));
script.CallFunction("add", 100, 50);
var variable = script.GetVariable("result");
Assert.AreEqual(TypeClass.Number, variable.GetTypeClass());
var val = variable.EvaluateInteger();
@ -139,6 +137,16 @@ namespace PorygonSharpTests
}
}
[Test]
public void TestExceptions()
{
using (var script = new Script("error('test')"))
{
Assert.Throws<EvaluationException>(() => script.Evaluate());
}
}
[Test]
public void TestHash()
{

Binary file not shown.