public static bool RemoveKey(StackValue array, StackValue key, Core core) { Validity.Assert(StackUtils.IsArray(array)); if (!StackUtils.IsArray(array)) { return(false); } HeapElement he = GetHeapElement(array, core); if (StackUtils.IsNumeric(key)) { long index = key.AsInt().opdata; if (index < 0) { index = index + he.VisibleSize; } if (index >= 0 && index < he.VisibleSize) { StackValue oldValue = he.Stack[index]; he.Stack[index] = StackUtils.BuildNull(); if (index == he.VisibleSize - 1) { he.VisibleSize -= 1; } return(true); } } else { if (he.Dict != null && he.Dict.ContainsKey(key)) { StackValue value = he.Dict[key]; GCUtils.GCRelease(key, core); GCUtils.GCRelease(value, core); he.Dict.Remove(key); return(true); } } return(false); }
/// <summary> /// Copy an array and coerce its elements/values to target type /// </summary> /// <param name="array"></param> /// <param name="type"></param> /// <param name="core"></param> /// <returns></returns> public static StackValue CopyArray(StackValue array, Type type, Core core) { Validity.Assert(array.IsArray); if (!array.IsArray) { return(StackValue.Null); } HeapElement he = GetHeapElement(array, core); Validity.Assert(he != null); int elementSize = GetElementSize(array, core); StackValue[] elements = new StackValue[elementSize]; for (int i = 0; i < elementSize; i++) { StackValue coercedValue = TypeSystem.Coerce(he.Stack[i], type, core); GCUtils.GCRetain(coercedValue, core); elements[i] = coercedValue; } Dictionary <StackValue, StackValue> dict = null; if (he.Dict != null) { dict = new Dictionary <StackValue, StackValue>(new StackValueComparer(core)); foreach (var pair in he.Dict) { StackValue key = pair.Key; StackValue value = pair.Value; StackValue coercedValue = TypeSystem.Coerce(value, type, core); GCUtils.GCRetain(key, core); GCUtils.GCRetain(coercedValue, core); dict[key] = coercedValue; } } return(core.Heap.AllocateArray(elements, dict)); }
/// <summary> /// Try to get value for key from nested dictionaries. This function is /// used in the case that indexing into dictionaries that returned from /// a replicated function whose return type is dictionary. /// </summary> /// <param name="array"></param> /// <param name="key"></param> /// <param name="value"></param> /// <param name="core"></param> /// <returns></returns> public static bool TryGetValueFromNestedDictionaries(StackValue array, StackValue key, out StackValue value, Core core) { if (!array.IsArray) { value = StackValue.Null; return(false); } HeapElement he = GetHeapElement(array, core); if (he.Dict != null && he.Dict.TryGetValue(key, out value)) { return(true); } var values = new List <StackValue>(); bool hasValue = false; foreach (var element in he.VisibleItems) { StackValue valueInElement; if (TryGetValueFromNestedDictionaries(element, key, out valueInElement, core)) { hasValue = true; GCUtils.GCRetain(valueInElement, core); values.Add(valueInElement); } } if (hasValue) { value = core.Heap.AllocateArray(values, null); return(true); } else { value = StackValue.Null; return(false); } }
/// <summary> /// = array[index1][index2][...][indexN], and /// indices = {index1, index2, ..., indexN} /// </summary> /// <param name="array"></param> /// <param name="indices"></param> /// <param name="core"></param> /// <returns></returns> public static StackValue GetValueFromIndices(StackValue array, List <StackValue> indices, Core core) { if (indices.Count == 0) { return(array); } else if (!array.IsArray && !array.IsString) { core.RuntimeStatus.LogWarning(WarningID.kOverIndexing, WarningMessage.kArrayOverIndexed); return(StackValue.Null); } StackValue[][] zippedIndices = ArrayUtils.GetZippedIndices(indices, core); if (zippedIndices == null || zippedIndices.Length == 0) { return(StackValue.Null); } StackValue[] values = new StackValue[zippedIndices.Length]; for (int i = 0; i < zippedIndices.Length; ++i) { values[i] = GetValueFromIndices(array, zippedIndices[i], core); } if (zippedIndices.Length > 1) { for (int i = 0; i < values.Length; ++i) { GCUtils.GCRetain(values[i], core); } return(core.Heap.AllocateArray(values, null)); } else { return(values[0]); } }
public static StackValue CoerceArray(StackValue array, Type typ, Core core) { //@TODO(Luke) handle array rank coersions Validity.Assert(IsArray(array), "Argument needs to be an array {99FB71A6-72AD-4C93-8F1E-0B1F419C1A6D}"); //This is the element on the heap that manages the data structure HeapElement heapElement = core.Heap.Heaplist[(int)array.opdata]; StackValue[] newSVs = new StackValue[heapElement.VisibleSize]; for (int i = 0; i < heapElement.VisibleSize; ++i) { StackValue sv = heapElement.Stack[i]; StackValue coercedValue; if (IsArray(sv)) { Type typ2 = new Type(); typ2.UID = typ.UID; typ2.rank = typ.rank - 1; typ2.IsIndexable = (typ2.rank == -1 || typ2.rank > 0); coercedValue = CoerceArray(sv, typ2, core); } else { coercedValue = TypeSystem.Coerce(sv, typ, core); } GCUtils.GCRetain(coercedValue, core); newSVs[i] = coercedValue; } return(HeapUtils.StoreArray(newSVs, core)); }