Skip to content

Commit d2d2f3d

Browse files
committed
Merge branch 'refs/heads/develop' into publish/v2.0.2
# Conflicts: # Jenkinsfile
2 parents 7c180a6 + 144fc70 commit d2d2f3d

11 files changed

Lines changed: 698 additions & 325 deletions

File tree

src/OneScript.StandardLibrary/Collections/ArrayImpl.cs

Lines changed: 109 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,21 @@ This Source Code Form is subject to the terms of the
55
at http://mozilla.org/MPL/2.0/.
66
----------------------------------------------------------*/
77

8-
using System.Collections.Generic;
98
using OneScript.Contexts;
109
using OneScript.Exceptions;
1110
using OneScript.Types;
1211
using OneScript.Values;
1312
using ScriptEngine.Machine;
1413
using ScriptEngine.Machine.Contexts;
14+
using System.Collections.Generic;
1515

1616
namespace OneScript.StandardLibrary.Collections
1717
{
18+
/// <summary>
19+
/// Коллекция элементов произвольного типа.
20+
/// Возможно обращение к значениям элементов по числовому индексу (нумерация начинается с 0).
21+
/// Доступен обход в цикле <c>Для Каждого Из</c>.
22+
/// </summary>
1823
[ContextClass("Массив", "Array")]
1924
public class ArrayImpl : AutoCollectionContext<ArrayImpl, IValue>, IValueArray
2025
{
@@ -24,6 +29,11 @@ public ArrayImpl()
2429
{
2530
_values = new List<IValue>();
2631
}
32+
33+
public ArrayImpl(int capacity)
34+
{
35+
_values = new List<IValue>(capacity);
36+
}
2737

2838
public ArrayImpl(IEnumerable<IValue> values)
2939
{
@@ -56,16 +66,23 @@ public override void SetIndexedValue(IValue index, IValue val)
5666
Set((int)index.AsNumber(), val);
5767
else
5868
base.SetIndexedValue(index, val);
59-
}
60-
69+
}
70+
6171
#region ICollectionContext Members
62-
72+
73+
/// <summary>
74+
/// Получает количество элементов в массиве
75+
/// </summary>
76+
/// <returns>Количество элементов массива</returns>
6377
[ContextMethod("Количество", "Count")]
6478
public override int Count()
6579
{
6680
return _values.Count;
67-
}
68-
81+
}
82+
83+
/// <summary>
84+
/// Удаляет все элементы из массива
85+
/// </summary>
6986
[ContextMethod("Очистить", "Clear")]
7087
public void Clear()
7188
{
@@ -82,19 +99,27 @@ public override IEnumerator<IValue> GetEnumerator()
8299
{
83100
yield return item;
84101
}
85-
}
86-
102+
}
103+
87104
#endregion
88-
105+
106+
/// <summary>
107+
/// Добавляет элемент в конец массива
108+
/// </summary>
109+
/// <param name="value">Произвольный: Добавляемое значение. Если не указано, то добавляется Неопределено</param>
89110
[ContextMethod("Добавить", "Add")]
90111
public void Add(IValue value = null)
91112
{
92-
if (value == null)
93-
_values.Add(ValueFactory.Create());
94-
else
95-
_values.Add(value);
96-
}
97-
113+
_values.Add(value ?? ValueFactory.Create());
114+
}
115+
116+
/// <summary>
117+
/// Вставляет значение в массив по указанному индексу
118+
/// </summary>
119+
/// <param name="index">Число: Индекс вставляемого значения.
120+
/// Если индекс превышает размер массива, то массив дополняется элементами Неопределено до указанного индекса.
121+
/// Если индекс отрицательный, то выбрасывается исключение</param>
122+
/// <param name="value">Произвольный: Вставляемое значение. Если не указано, то вставляется Неопределено</param>
98123
[ContextMethod("Вставить", "Insert")]
99124
public void Insert(int index, IValue value = null)
100125
{
@@ -104,26 +129,27 @@ public void Insert(int index, IValue value = null)
104129
if (index > _values.Count)
105130
Extend(index - _values.Count);
106131

107-
if (value == null)
108-
_values.Insert(index, ValueFactory.Create());
109-
else
110-
_values.Insert(index, value);
132+
_values.Insert(index, value ?? ValueFactory.Create());
111133
}
112134

135+
/// <summary>
136+
/// Выполняет поиск элемента в массиве
137+
/// </summary>
138+
/// <param name="what">Произвольный: Искомое значение</param>
139+
/// <returns>Если элемент найден, возвращается его индекс, иначе Неопределено</returns>
113140
[ContextMethod("Найти", "Find")]
114141
public IValue Find(IValue what)
115142
{
116143
var idx = _values.FindIndex(x => x.StrictEquals(what));
117-
if(idx < 0)
118-
{
119-
return ValueFactory.Create();
120-
}
121-
else
122-
{
123-
return ValueFactory.Create(idx);
124-
}
125-
}
126-
144+
return idx>=0 ? ValueFactory.Create(idx) : ValueFactory.Create();
145+
}
146+
147+
/// <summary>
148+
/// Удаляет значение из массива
149+
/// </summary>
150+
/// <param name="index">Число: Индекс удаляемого элемента.
151+
/// Если индекс находится за границами массива, то выбрасывается исключение
152+
/// </param>
127153
[ContextMethod("Удалить", "Delete")]
128154
public void Remove(int index)
129155
{
@@ -133,21 +159,39 @@ public void Remove(int index)
133159
_values.RemoveAt(index);
134160
}
135161

162+
/// <summary>
163+
/// Получает наибольший индекс элемента массива
164+
/// </summary>
165+
/// <returns>Наибольший индекс в массиве. Если количество элементов массива равно 0, возвращает -1</returns>
136166
[ContextMethod("ВГраница", "UBound")]
137167
public int UpperBound()
138168
{
139169
return _values.Count - 1;
140-
}
141-
170+
}
171+
172+
/// <summary>
173+
/// Получает значение из массива по индексу
174+
/// </summary>
175+
/// <param name="index">Число: Индекс элемента.
176+
/// Если индекс находится за границами массива, то выбрасывается исключение
177+
/// </param>
178+
/// <returns>Значение элемента массива</returns>
142179
[ContextMethod("Получить", "Get")]
143180
public IValue Get(int index)
144181
{
145182
if (index < 0 || index >= _values.Count)
146183
throw RuntimeException.IndexOutOfRange();
147184

148185
return _values[index];
149-
}
150-
186+
}
187+
188+
/// <summary>
189+
/// Устанавливает значение в массиве по индексу
190+
/// </summary>
191+
/// <param name="index">Число: Индекс элемента.
192+
/// Если индекс находится за границами массива, то выбрасывается исключение
193+
/// </param>
194+
/// <param name="value">Произвольный: Устанавливаемое значение</param>
151195
[ContextMethod("Установить", "Set")]
152196
public void Set(int index, IValue value)
153197
{
@@ -165,20 +209,22 @@ private void Extend(int count)
165209
}
166210
}
167211

168-
private static void FillArray(ArrayImpl currentArray, int bound)
212+
private static ArrayImpl CreateArray(int bound)
169213
{
214+
var array = new ArrayImpl(bound);
170215
for (int i = 0; i < bound; i++)
171216
{
172-
currentArray._values.Add(ValueFactory.Create());
217+
array._values.Add(ValueFactory.Create());
173218
}
219+
return array;
174220
}
175221

176-
private static IValue CloneArray(ArrayImpl cloneable)
222+
private static ArrayImpl CloneArray(ArrayImpl cloneable)
177223
{
178-
ArrayImpl clone = new ArrayImpl();
224+
ArrayImpl clone = new ArrayImpl(cloneable._values.Count);
179225
foreach (var item in cloneable._values)
180226
{
181-
clone._values.Add(item ?? ValueFactory.Create());
227+
clone._values.Add(item is ArrayImpl arr ? CloneArray(arr) : item );
182228
}
183229
return clone;
184230
}
@@ -198,35 +244,37 @@ public static ArrayImpl Constructor()
198244
public static ArrayImpl Constructor(IValue[] dimensions)
199245
{
200246
if (dimensions.Length == 1 && dimensions[0] is FixedArrayImpl fa)
201-
{
202-
return Constructor(fa);
247+
{
248+
return Constructor(fa);
203249
}
204-
205-
ArrayImpl cloneable = null;
206-
for (int dim = dimensions.Length - 1; dim >= 0; dim--)
250+
251+
// fail fast
252+
int size = 0;
253+
for (int dim = 0; dim < dimensions.Length; dim++)
207254
{
208255
if (dimensions[dim] == null)
209-
throw RuntimeException.InvalidNthArgumentType(dim + 1);
210-
211-
int bound = (int)dimensions[dim].AsNumber();
212-
if (bound <= 0)
256+
throw RuntimeException.InvalidNthArgumentType(dim + 1);
257+
258+
size = (int)dimensions[dim].AsNumber();
259+
if (size <= 0)
213260
throw RuntimeException.InvalidNthArgumentValue(dim + 1);
214-
215-
var newInst = new ArrayImpl();
216-
FillArray(newInst, bound);
217-
if(cloneable != null)
218-
{
219-
for (int i = 0; i < bound; i++)
220-
{
221-
newInst._values[i] = CloneArray(cloneable);
222-
}
223-
}
224-
cloneable = newInst;
225-
261+
}
262+
263+
var newInst = CreateArray(size); // длина по последней размерности
264+
265+
for (int dim = dimensions.Length - 2; dim >= 0; dim--) // если размерность >= 2
266+
{
267+
ArrayImpl nested = newInst;
268+
int bound = (int)dimensions[dim].AsNumber();
269+
270+
newInst = new ArrayImpl(bound);
271+
for (int i = 0; i < bound; i++)
272+
{
273+
newInst._values.Add(CloneArray(nested));
274+
}
226275
}
227276

228-
return cloneable;
229-
277+
return newInst;
230278
}
231279

232280
[ScriptConstructor(Name = "На основании фиксированного массива")]

0 commit comments

Comments
 (0)