diff --git a/PorygonSharp/CoreSetup.cs b/PorygonSharp/CoreSetup.cs index db15171..f764f4d 100644 --- a/PorygonSharp/CoreSetup.cs +++ b/PorygonSharp/CoreSetup.cs @@ -8,14 +8,14 @@ namespace PorygonSharp public static Action 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); diff --git a/PorygonSharp/EvaluateResult.cs b/PorygonSharp/EvaluateResult.cs new file mode 100644 index 0000000..d63afe2 --- /dev/null +++ b/PorygonSharp/EvaluateResult.cs @@ -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(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); + + } +} \ No newline at end of file diff --git a/PorygonSharp/EvaluationException.cs b/PorygonSharp/EvaluationException.cs new file mode 100644 index 0000000..a9baaf1 --- /dev/null +++ b/PorygonSharp/EvaluationException.cs @@ -0,0 +1,12 @@ +using System; + +namespace PorygonSharp +{ + public class EvaluationException : Exception + { + public EvaluationException(string message) : base(message) + { + + } + } +} \ No newline at end of file diff --git a/PorygonSharp/Script.cs b/PorygonSharp/Script.cs index ed2f395..54f843b 100644 --- a/PorygonSharp/Script.cs +++ b/PorygonSharp/Script.cs @@ -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)] diff --git a/PorygonSharpTests/UnitTest1.cs b/PorygonSharpTests/UnitTest1.cs index eaf080e..418ef74 100644 --- a/PorygonSharpTests/UnitTest1.cs +++ b/PorygonSharpTests/UnitTest1.cs @@ -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(() => script.Evaluate()); + } + } + + [Test] public void TestHash() { diff --git a/libPorygonLang.so b/libPorygonLang.so index b155a2b..5b3bc89 100755 Binary files a/libPorygonLang.so and b/libPorygonLang.so differ