예제 #1
0
        /// <summary>
        /// array[index1][index2][...][indexN] = value, and
        /// indices = {index1, index2, ..., indexN}
        ///
        /// Note this function doesn't support the replication of array indexing.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="indices"></param>
        /// <param name="value"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue SetValueForIndices(StackValue array, StackValue[] indices, StackValue value, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array) || StackUtils.IsString(array));

            for (int i = 0; i < indices.Length - 1; ++i)
            {
                StackValue  index = indices[i];
                HeapElement he    = GetHeapElement(array, core);

                StackValue subArray;

                if (StackUtils.IsNumeric(index))
                {
                    index = index.AsInt();
                    int absIndex = he.ExpandByAcessingAt((int)index.opdata);
                    subArray = he.Stack[absIndex];
                }
                else
                {
                    subArray = GetValueFromIndex(array, index, core);
                }

                // auto-promotion
                if (!StackUtils.IsArray(subArray))
                {
                    subArray = HeapUtils.StoreArray(new StackValue[] { subArray }, null, core);
                    GCUtils.GCRetain(subArray, core);
                    SetValueForIndex(array, index, subArray, core);
                }

                array = subArray;
            }

            return(SetValueForIndex(array, indices[indices.Length - 1], value, core));
        }
예제 #2
0
        /// <summary>
        /// = array[index1][index2][...][indexN], and
        /// indices = {index1, index2, ..., indexN}
        ///
        /// Note this function doesn't support the replication of array indexing.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="indices"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue GetValueFromIndices(StackValue array, StackValue[] indices, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array) || StackUtils.IsString(array));
            for (int i = 0; i < indices.Length - 1; ++i)
            {
                if (!StackUtils.IsArray(array) && !StackUtils.IsString(array))
                {
                    core.RuntimeStatus.LogWarning(WarningID.kOverIndexing, WarningMessage.kArrayOverIndexed);
                    return(StackUtils.BuildNull());
                }

                StackValue index = indices[i];
                if (StackUtils.IsNumeric(index))
                {
                    index = index.AsInt();
                    array = GetValueFromIndex(array, (int)index.opdata, core);
                }
                else
                {
                    if (array.optype != AddressType.ArrayPointer)
                    {
                        core.RuntimeStatus.LogWarning(WarningID.kOverIndexing, WarningMessage.kArrayOverIndexed);
                        return(StackUtils.BuildNull());
                    }
                    array = GetValueFromIndex(array, index, core);
                }
            }

            return(GetValueFromIndex(array, indices[indices.Length - 1], core));
        }
예제 #3
0
        /// <summary>
        /// array[index] = value. Here index can be any type.
        ///
        /// Note this function doesn't support the replication of array indexing.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="index"></param>
        /// <param name="value"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue SetValueForIndex(StackValue array, StackValue index, StackValue value, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array) || StackUtils.IsString(array));

            if (StackUtils.IsNumeric(index))
            {
                index = index.AsInt();
                return(SetValueForIndex(array, (int)index.opdata, value, core));
            }
            else
            {
                HeapElement he = GetHeapElement(array, core);
                if (he.Dict == null)
                {
                    he.Dict = new Dictionary <StackValue, StackValue>(new StackValueComparer(core));
                }

                StackValue oldValue;
                if (!he.Dict.TryGetValue(index, out oldValue))
                {
                    oldValue = StackUtils.BuildNull();
                }

                GCUtils.GCRetain(index, core);
                GCUtils.GCRetain(value, core);
                he.Dict[index] = value;

                return(oldValue);
            }
        }
예제 #4
0
        /// <summary>
        /// = array[index].
        ///
        /// Note this function doesn't support the replication of array indexing.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="index"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue GetValueFromIndex(StackValue array, StackValue index, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array) || StackUtils.IsString(array));
            if (!StackUtils.IsArray(array) && !StackUtils.IsString(array))
            {
                return(StackUtils.BuildNull());
            }

            if (StackUtils.IsNumeric(index))
            {
                index = index.AsInt();
                return(GetValueFromIndex(array, (int)index.opdata, core));
            }
            else if (index.optype == AddressType.ArrayKey)
            {
                int         fullIndex = (int)index.opdata;
                HeapElement he        = GetHeapElement(array, core);

                if (he.VisibleSize > fullIndex)
                {
                    return(GetValueFromIndex(array, fullIndex, core));
                }
                else
                {
                    fullIndex = fullIndex - he.VisibleSize;
                    if (he.Dict != null && he.Dict.Count > fullIndex)
                    {
                        int count = 0;
                        foreach (var key in he.Dict.Keys)
                        {
                            if (count == fullIndex)
                            {
                                return(he.Dict[key]);
                            }
                            count = count + 1;
                        }
                    }
                }

                return(StackUtils.BuildNull());
            }
            else
            {
                HeapElement he    = GetHeapElement(array, core);
                StackValue  value = StackUtils.BuildNull();

                if (he.Dict != null && he.Dict.TryGetValue(index, out value))
                {
                    return(value);
                }
                else
                {
                    return(StackUtils.BuildNull());
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Return the element size of an array
        /// </summary>
        /// <param name="array"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static int GetElementSize(StackValue array, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array) || StackUtils.IsString(array));
            if (!StackUtils.IsArray(array) && !StackUtils.IsString(array))
            {
                return(Constants.kInvalidIndex);
            }

            return(GetHeapElement(array, core).VisibleSize);
        }
예제 #6
0
        /// <summary>
        /// = array[index]
        /// </summary>
        /// <param name="array"></param>
        /// <param name="index"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue GetValueFromIndex(StackValue array, int index, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array) || StackUtils.IsString(array));
            if (!StackUtils.IsArray(array) && !StackUtils.IsString(array))
            {
                return(StackUtils.BuildNull());
            }

            HeapElement he = GetHeapElement(array, core);

            return(StackUtils.GetValue(he, index, core));
        }
예제 #7
0
        /// <summary>
        /// array[index] = value. The array will be expanded if necessary.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="index"></param>
        /// <param name="value"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue SetValueForIndex(StackValue array, int index, StackValue value, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array) || StackUtils.IsString(array));
            if (StackUtils.IsString(array) && value.optype != AddressType.Char)
            {
                core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeMismatch, RuntimeData.WarningMessage.kAssignNonCharacterToString);
                return(StackUtils.BuildNull());
            }

            lock (core.Heap.cslock)
            {
                HeapElement arrayHeap = GetHeapElement(array, core);
                index = arrayHeap.ExpandByAcessingAt(index);
                StackValue oldValue = arrayHeap.SetValue(index, value);
                return(oldValue);
            }
        }
예제 #8
0
        /// <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 (!StackUtils.IsArray(array) && !StackUtils.IsString(array))
            {
                core.RuntimeStatus.LogWarning(WarningID.kOverIndexing, WarningMessage.kArrayOverIndexed);
                return(StackUtils.BuildNull());
            }

            StackValue[][] zippedIndices = ArrayUtils.GetZippedIndices(indices, core);
            if (zippedIndices == null || zippedIndices.Length == 0)
            {
                return(StackUtils.BuildNull());
            }

            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.GCRelease(values[i], core);
                }

                return(HeapUtils.StoreArray(values, null, core));
            }
            else
            {
                return(values[0]);
            }
        }
예제 #9
0
        public static int CompareString(StackValue s1, StackValue s2, Core core)
        {
            if (!StackUtils.IsString(s1) || !StackUtils.IsString(s2))
            {
                return(ProtoCore.DSASM.Constants.kInvalidIndex);
            }

            HeapElement he1 = ArrayUtils.GetHeapElement(s1, core);
            HeapElement he2 = ArrayUtils.GetHeapElement(s2, core);

            int len1 = he1.VisibleSize;
            int len2 = he2.VisibleSize;

            int len = len1 > len2 ? len2 : len1;
            int i   = 0;

            for (; i < len; ++i)
            {
                if (he1.Stack[i].opdata != he2.Stack[i].opdata)
                {
                    return((he1.Stack[i].opdata > he2.Stack[i].opdata) ? 1 : -1);
                }
            }

            if (len1 > len2)
            {
                return(1);
            }
            else if (len1 == len2)
            {
                return(0);
            }
            else
            {
                return(-1);
            }
        }