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) private static EvalValue CreateListEvalValue(IList collection, Type type)
{ {
var helper = new ListEvalValue(collection, type); var helper = new ListEvalValue(collection, type);
var ptr = CreateCollectionValue(IntPtr.Zero, helper.ParentCollection, helper.Getter, helper.Setter, var ptr = CreateCollectionValue(IntPtr.Zero, helper.ParentCollectionPtr, helper.GetterPtr, helper.SetterPtr,
helper.GetIterator); helper.GetIteratorPtr, helper.GetLengthPtr);
return new EvalValue(ptr); return new EvalValue(ptr);
} }
@ -86,6 +86,6 @@ namespace PorygonSharp.EvalValues
[DllImport("PorygonLang", EntryPoint = "CreateCollectionValue", CallingConvention = CallingConvention.Cdecl)] [DllImport("PorygonLang", EntryPoint = "CreateCollectionValue", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr CreateCollectionValue(IntPtr type, IntPtr parent, IntPtr getter, IntPtr setter, 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 internal class ListEvalValue
{ {
private readonly IList _list;
private readonly Type _valueType;
private delegate IntPtr GetterDelegate(IntPtr parent, IntPtr index); private delegate IntPtr GetterDelegate(IntPtr parent, IntPtr index);
private delegate void SetterDelegate(IntPtr parent, IntPtr index, IntPtr value); 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) public ListEvalValue(IList list, Type type)
{ {
var valueType = type.IsArray ? type.GetElementType() : type.GetGenericArguments()[0]; _list = list;
if (valueType == null) _valueType = type.IsArray ? type.GetElementType() : type.GetGenericArguments()[0];
if (_valueType == null)
throw new ArgumentNullException(); throw new ArgumentNullException();
ParentCollection = ObjectEvalValueHandler.GetObjectPtr(list); ParentCollectionPtr = IntPtr.Zero;
Getter = Marshal.GetFunctionPointerForDelegate(new GetterDelegate((parent, index) => _getter = Getter;
{ _setter = Setter;
var val = new EvalValue(index).EvaluateInteger(); _getIterator = GetIterator;
return EvalValueCreator.CreateValue(list[(int) val - 1]).GetPointer(); _getLength = GetLength;
}));
Setter = Marshal.GetFunctionPointerForDelegate(new SetterDelegate((parent, index, value) => GetterPtr = Marshal.GetFunctionPointerForDelegate(_getter);
{ GetterPtr = Marshal.GetFunctionPointerForDelegate(_getter);
var key = new EvalValue(index).EvaluateInteger(); SetterPtr = Marshal.GetFunctionPointerForDelegate(_setter);
var val = new EvalValue(value).GetObjectValue(); GetIteratorPtr = Marshal.GetFunctionPointerForDelegate(_getIterator);
list[(int) key - 1] = Convert.ChangeType(val, valueType); GetLengthPtr = Marshal.GetFunctionPointerForDelegate(_getLength);
})); }
GetIterator =
Marshal.GetFunctionPointerForDelegate(new GetIteratorDelegate(parent => private IntPtr Getter(IntPtr parent, IntPtr index)
ListIterator.CreateListIterator(list))); {
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.