Update ListEvalValue to handle length unary operator

This commit is contained in:
Deukhoofd 2019-09-12 18:24:59 +02:00
parent c3f1a00750
commit 6402746101
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
3 changed files with 58 additions and 25 deletions

View File

@ -63,8 +63,8 @@ namespace PorygonSharp.EvalValues
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);
var ptr = CreateCollectionValue(IntPtr.Zero, helper.ParentCollectionPtr, helper.GetterPtr, helper.SetterPtr,
helper.GetIteratorPtr, helper.GetLengthPtr);
return new EvalValue(ptr);
}
@ -86,6 +86,6 @@ namespace PorygonSharp.EvalValues
[DllImport("PorygonLang", EntryPoint = "CreateCollectionValue", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr CreateCollectionValue(IntPtr type, IntPtr parent, IntPtr getter, IntPtr setter,
IntPtr iterator);
IntPtr iterator, IntPtr size);
}
}

View File

@ -6,36 +6,69 @@ namespace PorygonSharp.EvalValues
{
internal class ListEvalValue
{
private readonly IList _list;
private readonly Type _valueType;
private delegate IntPtr GetterDelegate(IntPtr parent, IntPtr index);
private delegate void SetterDelegate(IntPtr parent, IntPtr index, IntPtr value);
public delegate IntPtr GetIteratorDelegate(IntPtr parent);
private delegate IntPtr GetIteratorDelegate(IntPtr parent);
private delegate int GetLengthDelegate(IntPtr parent);
// ReSharper disable PrivateFieldCanBeConvertedToLocalVariable
private readonly GetterDelegate _getter;
private readonly SetterDelegate _setter;
private readonly GetIteratorDelegate _getIterator;
private readonly GetLengthDelegate _getLength;
// ReSharper restore PrivateFieldCanBeConvertedToLocalVariable
public readonly IntPtr ParentCollectionPtr;
public readonly IntPtr GetterPtr;
public readonly IntPtr SetterPtr;
public readonly IntPtr GetIteratorPtr;
public readonly IntPtr GetLengthPtr;
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)
_list = list;
_valueType = type.IsArray ? type.GetElementType() : type.GetGenericArguments()[0];
if (_valueType == null)
throw new ArgumentNullException();
ParentCollection = ObjectEvalValueHandler.GetObjectPtr(list);
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)));
ParentCollectionPtr = IntPtr.Zero;
_getter = Getter;
_setter = Setter;
_getIterator = GetIterator;
_getLength = GetLength;
GetterPtr = Marshal.GetFunctionPointerForDelegate(_getter);
GetterPtr = Marshal.GetFunctionPointerForDelegate(_getter);
SetterPtr = Marshal.GetFunctionPointerForDelegate(_setter);
GetIteratorPtr = Marshal.GetFunctionPointerForDelegate(_getIterator);
GetLengthPtr = Marshal.GetFunctionPointerForDelegate(_getLength);
}
private IntPtr Getter(IntPtr parent, IntPtr index)
{
var val = new EvalValue(index).EvaluateInteger();
return EvalValueCreator.CreateValue(_list[(int) val - 1]).GetPointer();
}
private void Setter(IntPtr parent, IntPtr index, IntPtr value)
{
var key = new EvalValue(index).EvaluateInteger();
var val = new EvalValue(value).GetObjectValue();
_list[(int) key - 1] = Convert.ChangeType(val, _valueType);
}
private IntPtr GetIterator(IntPtr parent)
{
return ListIterator.CreateListIterator(_list);
}
private int GetLength(IntPtr parent)
{
return _list.Count;
}
}
}

Binary file not shown.