diff --git a/PorygonSharp/CoreSetup.cs b/PorygonSharp/CoreSetup.cs index f764f4d..83297bc 100644 --- a/PorygonSharp/CoreSetup.cs +++ b/PorygonSharp/CoreSetup.cs @@ -27,7 +27,7 @@ namespace PorygonSharp Print(message); } - [DllImport("libPorygonLang", EntryPoint = "SetPrintFunc", CallingConvention = CallingConvention.Cdecl)] + [DllImport("libPorygonLang", EntryPoint = "SetDefaultPrintFunc", CallingConvention = CallingConvention.Cdecl)] private static extern double InternalSetPrintFunc(IntPtr ptr); } } \ No newline at end of file diff --git a/PorygonSharp/EvalValue.cs b/PorygonSharp/EvalValues/EvalValue.cs similarity index 55% rename from PorygonSharp/EvalValue.cs rename to PorygonSharp/EvalValues/EvalValue.cs index 97394ac..e9289c6 100644 --- a/PorygonSharp/EvalValue.cs +++ b/PorygonSharp/EvalValues/EvalValue.cs @@ -1,9 +1,8 @@ using System; using System.Runtime.InteropServices; using System.Text; -using PorygonSharp.UserData; -namespace PorygonSharp +namespace PorygonSharp.EvalValues { public class EvalValue : IDisposable { @@ -14,48 +13,7 @@ namespace PorygonSharp _handle = handle; } - public static EvalValue CreateValue(object o) - { - var type = o.GetType(); - var typeCode = Type.GetTypeCode(type); - switch (typeCode) - { - case TypeCode.Boolean: - return new EvalValue(CreateBoolEvalValue((bool)o)); - case TypeCode.Byte: - case TypeCode.SByte: - case TypeCode.Int16: - case TypeCode.Int32: - case TypeCode.Int64: - case TypeCode.UInt16: - case TypeCode.UInt32: - case TypeCode.UInt64: - return new EvalValue(CreateIntegerEvalValue(Convert.ToInt64(o))); - case TypeCode.Char: - case TypeCode.String: - return new EvalValue(CreateStringEvalValue(o.ToString())); - case TypeCode.Decimal: - case TypeCode.Double: - case TypeCode.Single: - return new EvalValue(CreateFloatEvalValue(Convert.ToDouble(o))); - case TypeCode.Object: - var typeHash = UserDataHandler.GetTypeId(type); - var handle = GCHandle.Alloc(o, GCHandleType.WeakTrackResurrection); - return new EvalValue(CreateUserDataEvalValue(typeHash, GCHandle.ToIntPtr(handle))); - case TypeCode.DateTime: - case TypeCode.DBNull: - case TypeCode.Empty: - default: - throw new Exception($"Type {type} is not currently available as EvalValue"); - } - } - - public static EvalValue FunctionEvalValue(IntPtr func, IntPtr parent) - { - return new EvalValue(CreateFunctionEvalValue(func, parent)); - } - - + public void Dispose() { if (_handle != IntPtr.Zero) @@ -119,9 +77,6 @@ namespace PorygonSharp return EvaluateString(); case TypeClass.UserData: return EvaluateGenericObject(); - case TypeClass.Function: - case TypeClass.Table: - case TypeClass.Error: default: throw new ArgumentOutOfRangeException(); } @@ -150,19 +105,5 @@ namespace PorygonSharp [DllImport("libPorygonLang", EntryPoint = "EvaluateUserDataObj",CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr EvaluateUserDataObj(IntPtr ptr); - [DllImport("libPorygonLang", EntryPoint = "CreateIntegerEvalValue",CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr CreateIntegerEvalValue(long l); - [DllImport("libPorygonLang", EntryPoint = "CreateFloatEvalValue",CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr CreateFloatEvalValue(double d); - [DllImport("libPorygonLang", EntryPoint = "CreateBoolEvalValue",CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr CreateBoolEvalValue(bool b); - [DllImport("libPorygonLang", EntryPoint = "CreateStringEvalValue",CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr CreateStringEvalValue(string s); - [DllImport("libPorygonLang", EntryPoint = "CreateUserDataEvalValue",CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr CreateUserDataEvalValue(uint typeHash, IntPtr obj); - - [DllImport("libPorygonLang", EntryPoint = "CreateFunctionEvalValue",CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr CreateFunctionEvalValue(IntPtr func, IntPtr parent); - } } \ No newline at end of file diff --git a/PorygonSharp/EvalValues/EvalValueCreator.cs b/PorygonSharp/EvalValues/EvalValueCreator.cs new file mode 100644 index 0000000..559d9fd --- /dev/null +++ b/PorygonSharp/EvalValues/EvalValueCreator.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using PorygonSharp.UserData; + +namespace PorygonSharp.EvalValues +{ + public static class EvalValueCreator + { + public static EvalValue CreateValue(object o) + { + var type = o.GetType(); + var typeCode = Type.GetTypeCode(type); + switch (typeCode) + { + case TypeCode.Boolean: + return new EvalValue(CreateBoolEvalValue((bool)o)); + case TypeCode.Byte: + case TypeCode.SByte: + case TypeCode.Int16: + case TypeCode.Int32: + case TypeCode.Int64: + case TypeCode.UInt16: + case TypeCode.UInt32: + case TypeCode.UInt64: + return new EvalValue(CreateIntegerEvalValue(Convert.ToInt64(o))); + case TypeCode.Char: + case TypeCode.String: + return new EvalValue(CreateStringEvalValue(o.ToString())); + case TypeCode.Decimal: + case TypeCode.Double: + case TypeCode.Single: + return new EvalValue(CreateFloatEvalValue(Convert.ToDouble(o))); + case TypeCode.Object: + if (typeof(IList).IsAssignableFrom(type)) + return CreateListEvalValue((IList)o, type); + var typeHash = UserDataHandler.GetTypeId(type); + var handle = GCHandle.Alloc(o, GCHandleType.WeakTrackResurrection); + return new EvalValue(CreateUserDataEvalValue(typeHash, GCHandle.ToIntPtr(handle))); + default: + throw new Exception($"Type {type} is not currently available as EvalValue"); + } + } + + public static EvalValue FunctionEvalValue(IntPtr func, IntPtr parent) + { + return new EvalValue(CreateFunctionEvalValue(func, parent)); + } + + private static EvalValue CreateListEvalValue(IList collection, Type type) + { + var helper = new ListEvalValue(collection, type); + var ptr = CreateCollectionValue(IntPtr.Zero, helper.ParentCollection, helper.Getter, helper.Setter, + helper.GetIterator); + return new EvalValue(ptr); + } + + [DllImport("libPorygonLang", EntryPoint = "CreateIntegerEvalValue",CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr CreateIntegerEvalValue(long l); + [DllImport("libPorygonLang", EntryPoint = "CreateFloatEvalValue",CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr CreateFloatEvalValue(double d); + [DllImport("libPorygonLang", EntryPoint = "CreateBoolEvalValue",CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr CreateBoolEvalValue(bool b); + [DllImport("libPorygonLang", EntryPoint = "CreateStringEvalValue",CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr CreateStringEvalValue(string s); + [DllImport("libPorygonLang", EntryPoint = "CreateUserDataEvalValue",CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr CreateUserDataEvalValue(uint typeHash, IntPtr obj); + + [DllImport("libPorygonLang", EntryPoint = "CreateFunctionEvalValue",CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr CreateFunctionEvalValue(IntPtr func, IntPtr parent); + + [DllImport("libPorygonLang", EntryPoint = "CreateCollectionValue", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr CreateCollectionValue(IntPtr type, IntPtr parent, IntPtr getter, IntPtr setter, + IntPtr iterator); + } +} \ No newline at end of file diff --git a/PorygonSharp/EvalValues/ListEvalValue.cs b/PorygonSharp/EvalValues/ListEvalValue.cs new file mode 100644 index 0000000..419847d --- /dev/null +++ b/PorygonSharp/EvalValues/ListEvalValue.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace PorygonSharp.EvalValues +{ + internal class ListEvalValue + { + private delegate IntPtr GetterDelegate(IntPtr parent, IntPtr index); + private delegate void SetterDelegate(IntPtr parent, IntPtr index, IntPtr value); + public delegate IntPtr GetIteratorDelegate(IntPtr parent); + + public readonly IntPtr ParentCollection; + public readonly IntPtr Getter; + public readonly IntPtr Setter; + public readonly IntPtr GetIterator; + + public ListEvalValue(IList list, Type type) + { + var valueType = type.IsArray ? type.GetElementType() : type.GetGenericArguments()[0]; + if (valueType == null) + throw new ArgumentNullException(); + + var parentHandle = GCHandle.Alloc(list, GCHandleType.WeakTrackResurrection); + ParentCollection = GCHandle.ToIntPtr(parentHandle); + Getter = Marshal.GetFunctionPointerForDelegate(new GetterDelegate((parent, index) => + { + var val = new EvalValue(index).EvaluateInteger(); + return EvalValueCreator.CreateValue(list[(int) val - 1]).GetPointer(); + })); + Setter = Marshal.GetFunctionPointerForDelegate(new SetterDelegate((parent, index, value) => + { + var key = new EvalValue(index).EvaluateInteger(); + var val = new EvalValue(value).GetObjectValue(); + list[(int) key - 1] = Convert.ChangeType(val, valueType); + })); + GetIterator = + Marshal.GetFunctionPointerForDelegate(new GetIteratorDelegate(parent => + ListIterator.CreateListIterator(list))); + } + } +} \ No newline at end of file diff --git a/PorygonSharp/EvalValues/ListIterator.cs b/PorygonSharp/EvalValues/ListIterator.cs new file mode 100644 index 0000000..203b9e5 --- /dev/null +++ b/PorygonSharp/EvalValues/ListIterator.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections; +using System.Runtime.InteropServices; + +namespace PorygonSharp.EvalValues +{ + public static class ListIterator + { + public static IntPtr CreateListIterator(IList list) + { + return CreateCollectionRangeIterator(0, list.Count); + } + + [DllImport("libPorygonLang", EntryPoint = "CreateCollectionRangeIterator", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr CreateCollectionRangeIterator(int start, int end); + } +} \ No newline at end of file diff --git a/PorygonSharp/EvaluateResult.cs b/PorygonSharp/EvaluateResult.cs index d63afe2..dc9e151 100644 --- a/PorygonSharp/EvaluateResult.cs +++ b/PorygonSharp/EvaluateResult.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.InteropServices; +using PorygonSharp.EvalValues; namespace PorygonSharp { @@ -9,7 +10,7 @@ namespace PorygonSharp private struct EvaluateResultInternal { public readonly IntPtr Value; - public readonly byte Result; + public readonly bool Result; } private readonly IntPtr _ptr; @@ -22,12 +23,12 @@ namespace PorygonSharp public EvalValue GetValue() { - return !IsSuccess() ? null : new EvalValue(_internal.Value); + return new EvalValue(_internal.Value); } public bool IsSuccess() { - return _internal.Result == 0; + return !_internal.Result; } public string GetError() diff --git a/PorygonSharp/PorygonSharp.csproj b/PorygonSharp/PorygonSharp.csproj index e306e6a..e67c354 100644 --- a/PorygonSharp/PorygonSharp.csproj +++ b/PorygonSharp/PorygonSharp.csproj @@ -5,4 +5,10 @@ true + + + PreserveNewest + + + diff --git a/PorygonSharp/Script.cs b/PorygonSharp/Script.cs index 54f843b..fd2cdc2 100644 --- a/PorygonSharp/Script.cs +++ b/PorygonSharp/Script.cs @@ -1,10 +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; +using PorygonSharp.EvalValues; namespace PorygonSharp { @@ -13,8 +12,10 @@ namespace PorygonSharp { private readonly IntPtr _evaluator; private readonly IntPtr _scriptVariables; + private readonly IntPtr _scriptTypes; private readonly SharedPointer _boundScript; private readonly SharedPointer _returnType; + private readonly IntPtr _scriptOptions; internal readonly SharedPointer Diagnostics; } @@ -43,12 +44,12 @@ namespace PorygonSharp private Diagnostics _diagnostics; public Diagnostics Diagnostics => _diagnostics ?? (_diagnostics = new Diagnostics(_internalScript.Diagnostics)); - private static readonly RuntimeTypeHandle _setupHandle = typeof(CoreSetup).TypeHandle; + private static readonly RuntimeTypeHandle SetupHandle = typeof(CoreSetup).TypeHandle; public Script(string s) { // Ensure core setup has been called - RuntimeHelpers.RunClassConstructor(_setupHandle); + RuntimeHelpers.RunClassConstructor(SetupHandle); _internalScriptHandle = Create(s); _internalScript = Marshal.PtrToStructure(_internalScriptHandle); @@ -90,9 +91,20 @@ namespace PorygonSharp public EvalValue CallFunction(string key, params object[] parameters) { - var scriptParameters = parameters.Select(x => EvalValue.CreateValue(x).GetPointer()).ToArray(); + var scriptParameters = parameters.Select(x => EvalValueCreator.CreateValue(x).GetPointer()).ToArray(); var ptr = CallFunction(_internalScriptHandle, key, scriptParameters, scriptParameters.Length); - return new EvalValue(ptr); + foreach (var parameter in scriptParameters) + { + Marshal.FreeHGlobal(parameter); + } + using (var result = new EvaluateResult(ptr)) + { + if (result.IsSuccess()) + { + return result.GetValue(); + } + throw new EvaluationException(result.GetError()); + } } [DllImport("libPorygonLang", EntryPoint = "CreateScript", CallingConvention = CallingConvention.Cdecl)] @@ -106,8 +118,10 @@ namespace PorygonSharp [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); + private static extern IntPtr CallFunction(IntPtr script, [MarshalAs(UnmanagedType.LPWStr)]string key, + IntPtr[] parameters, int parameterCount); } } \ No newline at end of file diff --git a/PorygonSharp/ScriptType/ScriptType.cs b/PorygonSharp/ScriptType/ScriptType.cs index 3be14b0..f5dd1d8 100644 --- a/PorygonSharp/ScriptType/ScriptType.cs +++ b/PorygonSharp/ScriptType/ScriptType.cs @@ -1,6 +1,9 @@ using System; +using System.Collections; +using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; +using PorygonSharp.UserData; namespace PorygonSharp.ScriptType { @@ -34,6 +37,18 @@ namespace PorygonSharp.ScriptType { return CreateScriptType(TypeClass.Nil); } + if (UserDataHandler.IsTypeRegistered(t)) + { + return UserDataHandler.CreateUserDataType(t); + } + if (typeof(IList).IsAssignableFrom(t)) + { + return CreateUserDataListType(t); + } + if (typeof(IDictionary<,>).IsAssignableFrom(t)) + { + return CreateUserDataDictionaryType(t); + } goto default; default: throw new ArgumentOutOfRangeException(t.FullName); @@ -61,6 +76,21 @@ namespace PorygonSharp.ScriptType } } + private static IntPtr CreateUserDataListType(Type t) + { + var keyType = CreateNumericScriptType(true, false); + var valType = t.IsArray ? t.GetElementType() : t.GenericTypeArguments[0]; + var valueType = GetScriptType(valType); + return CreateCollectionType(keyType, valueType); + } + + private static IntPtr CreateUserDataDictionaryType(Type t) + { + var keyType = GetScriptType(t.GenericTypeArguments[0]); + var valueType = GetScriptType(t.GenericTypeArguments[1]); + return CreateCollectionType(keyType, valueType); + } + [DllImport("libPorygonLang", EntryPoint = "CreateScriptType", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr CreateScriptType(TypeClass t); @@ -72,5 +102,8 @@ namespace PorygonSharp.ScriptType [DllImport("libPorygonLang", EntryPoint = "CreateUserDataFunctionScriptType", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr CreateUserDataFunctionScriptType(IntPtr returnType, IntPtr[] parameters, int parameterCount); + + [DllImport("libPorygonLang", EntryPoint = "CreateCollectionType", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr CreateCollectionType(IntPtr keyType, IntPtr valueType); } } \ No newline at end of file diff --git a/PorygonSharp/UserData/UserDataHandler.cs b/PorygonSharp/UserData/UserDataHandler.cs index 9415d19..e0c7e3c 100644 --- a/PorygonSharp/UserData/UserDataHandler.cs +++ b/PorygonSharp/UserData/UserDataHandler.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; +using PorygonSharp.EvalValues; using PorygonSharp.Utilities; namespace PorygonSharp.UserData @@ -13,8 +14,8 @@ namespace PorygonSharp.UserData private delegate IntPtr GetterDelegate(IntPtr ptr); private delegate void SetterDelegate(IntPtr ptr, IntPtr val); - private delegate IntPtr CallerDelegate(IntPtr parent, - [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]IntPtr[] parameters, int size); + private delegate IntPtr CallerDelegate(IntPtr parent, IntPtr scriptOption, + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]IntPtr[] parameters, int size); public static void RegisterType(string name, Type type) { @@ -51,7 +52,7 @@ namespace PorygonSharp.UserData { var obj = GCHandle.FromIntPtr(ptr).Target; var value = field.GetValue(obj); - return EvalValue.CreateValue(value).GetPointer(); + return EvalValueCreator.CreateValue(value).GetPointer(); }); var setterPtr = IntPtr.Zero; @@ -82,7 +83,7 @@ namespace PorygonSharp.UserData { var obj = GCHandle.FromIntPtr(ptr).Target; var value = property.GetValue(obj); - return EvalValue.CreateValue(value).GetPointer(); + return EvalValueCreator.CreateValue(value).GetPointer(); }); getterPtr = Marshal.GetFunctionPointerForDelegate(getter); } @@ -110,7 +111,7 @@ namespace PorygonSharp.UserData var getter = new GetterDelegate(ptr => { - var func = new CallerDelegate((parent, parameters, size) => + var func = new CallerDelegate((parent, scriptOptions, parameters, size) => { var evaluatedParameters = new object[size]; @@ -124,10 +125,10 @@ namespace PorygonSharp.UserData var parentObj = GCHandle.FromIntPtr(parent).Target; var result = method.Invoke(parentObj, evaluatedParameters); - return EvalValue.CreateValue(result).GetPointer(); + return EvalValueCreator.CreateValue(result).GetPointer(); }); var funcPtr = Marshal.GetFunctionPointerForDelegate(func); - return EvalValue.FunctionEvalValue(funcPtr, ptr).GetPointer(); + return EvalValueCreator.FunctionEvalValue(funcPtr, ptr).GetPointer(); }); var getterPtr = Marshal.GetFunctionPointerForDelegate(getter); var type = ScriptType.ScriptType.GetFunctionScriptType(method); @@ -144,12 +145,23 @@ namespace PorygonSharp.UserData return UserDataLookup[t]; } + public static bool IsTypeRegistered(Type t) + { + return UserDataLookup.ContainsKey(t); + } + public static int GetUserDataFieldCount(Type t) { var hash = GetTypeId(t); return GetUserDataFieldCount(hash); } + internal static IntPtr CreateUserDataType(Type t) + { + var hash = GetTypeId(t); + return CreateUserDataType(hash); + } + [DllImport("libPorygonLang", EntryPoint = "RegisterUserDataType", CallingConvention = CallingConvention.Cdecl)] private static extern void RegisterUserDataType(uint hashId); @@ -161,6 +173,9 @@ namespace PorygonSharp.UserData [DllImport("libPorygonLang", EntryPoint = "GetUserDataFieldCount", CallingConvention = CallingConvention.Cdecl)] private static extern int GetUserDataFieldCount(uint hashId); + + [DllImport("libPorygonLang", EntryPoint = "CreateUserDataType", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr CreateUserDataType(uint hashId); } } \ No newline at end of file diff --git a/PorygonSharp/libPorygonLang.so b/PorygonSharp/libPorygonLang.so new file mode 100755 index 0000000..e4471f5 Binary files /dev/null and b/PorygonSharp/libPorygonLang.so differ diff --git a/PorygonSharpTests/UserDataTests.cs b/PorygonSharpTests/UserDataTests.cs index 09029ea..19f64d1 100644 --- a/PorygonSharpTests/UserDataTests.cs +++ b/PorygonSharpTests/UserDataTests.cs @@ -16,6 +16,8 @@ namespace PorygonSharpTests public int GetOnly { get; } = 865; public readonly int ReadOnly = 684; + public int[] IntArray = {55, 60, 846, 346846}; + public int TestFunc() { return 345435; @@ -210,5 +212,104 @@ end } } + [Test] + public void CanGetFromArray() + { + UserDataHandler.RegisterType("testObject", typeof(UserDataTestObject)); + using (var script = new Script(@" +function test(testObject v) + return v.IntArray[3] +end +")) + { + var diags = script.Diagnostics.GetDiagnostics(); + foreach (var diag in diags) + { + throw new Exception(script.Diagnostics.GetFullDiagnosticMessage(diag)); + } + + script.Evaluate(); + var parameter = new UserDataTestObject(); + var result = script.CallFunction("test", parameter); + Assert.AreEqual(846, result.EvaluateInteger()); + } + } + + [Test] + public void CanSetToArray() + { + UserDataHandler.RegisterType("testObject", typeof(UserDataTestObject)); + using (var script = new Script(@" +function test(testObject v) + v.IntArray[2] = 256 +end +")) + { + var diags = script.Diagnostics.GetDiagnostics(); + foreach (var diag in diags) + { + throw new Exception(script.Diagnostics.GetFullDiagnosticMessage(diag)); + } + + script.Evaluate(); + var parameter = new UserDataTestObject(); + script.CallFunction("test", parameter); + Assert.AreEqual(256, parameter.IntArray[1]); + } + } + + [Test] + public void CanIterateOverArrayKeys() + { + UserDataHandler.RegisterType("testObject", typeof(UserDataTestObject)); + using (var script = new Script(@" +function test(testObject v) + value = 0 + for i in v.IntArray do + value = value + i + end + return value +end +")) + { + var diags = script.Diagnostics.GetDiagnostics(); + foreach (var diag in diags) + { + throw new Exception(script.Diagnostics.GetFullDiagnosticMessage(diag)); + } + + script.Evaluate(); + var parameter = new UserDataTestObject(); + var result = script.CallFunction("test", parameter); + Assert.AreEqual(10, result.EvaluateInteger()); + } + } + + [Test] + public void CanIterateOverArrayValues() + { + UserDataHandler.RegisterType("testObject", typeof(UserDataTestObject)); + using (var script = new Script(@" +function test(testObject v) + value = 0 + for i, j in v.IntArray do + value = value + j + end + return value +end +")) + { + var diags = script.Diagnostics.GetDiagnostics(); + foreach (var diag in diags) + { + throw new Exception(script.Diagnostics.GetFullDiagnosticMessage(diag)); + } + + script.Evaluate(); + var parameter = new UserDataTestObject(); + var result = script.CallFunction("test", parameter); + Assert.AreEqual(347807, result.EvaluateInteger()); + } + } } } \ No newline at end of file diff --git a/libPorygonLang.so b/libPorygonLang.so deleted file mode 100755 index 5b3bc89..0000000 Binary files a/libPorygonLang.so and /dev/null differ