Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 109 additions & 61 deletions src/OneScript.StandardLibrary/Collections/ArrayImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@ This Source Code Form is subject to the terms of the
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/

using System.Collections.Generic;
using OneScript.Contexts;
using OneScript.Exceptions;
using OneScript.Types;
using OneScript.Values;
using ScriptEngine.Machine;
using ScriptEngine.Machine.Contexts;
using System.Collections.Generic;

namespace OneScript.StandardLibrary.Collections
{
/// <summary>
/// Коллекция элементов произвольного типа.
/// Возможно обращение к значениям элементов по числовому индексу (нумерация начинается с 0).
/// Доступен обход в цикле <c>Для Каждого Из</c>.
/// </summary>
[ContextClass("Массив", "Array")]
public class ArrayImpl : AutoCollectionContext<ArrayImpl, IValue>, IValueArray
{
Expand All @@ -24,6 +29,11 @@ public ArrayImpl()
{
_values = new List<IValue>();
}

public ArrayImpl(int capacity)
{
_values = new List<IValue>(capacity);
}

public ArrayImpl(IEnumerable<IValue> values)
{
Expand Down Expand Up @@ -56,16 +66,23 @@ public override void SetIndexedValue(IValue index, IValue val)
Set((int)index.AsNumber(), val);
else
base.SetIndexedValue(index, val);
}

}
#region ICollectionContext Members


/// <summary>
/// Получает количество элементов в массиве
/// </summary>
/// <returns>Количество элементов массива</returns>
[ContextMethod("Количество", "Count")]
public override int Count()
{
return _values.Count;
}

}

/// <summary>
/// Удаляет все элементы из массива
/// </summary>
[ContextMethod("Очистить", "Clear")]
public void Clear()
{
Expand All @@ -82,19 +99,27 @@ public override IEnumerator<IValue> GetEnumerator()
{
yield return item;
}
}

}
#endregion


/// <summary>
/// Добавляет элемент в конец массива
/// </summary>
/// <param name="value">Произвольный: Добавляемое значение. Если не указано, то добавляется Неопределено</param>
[ContextMethod("Добавить", "Add")]
public void Add(IValue value = null)
{
if (value == null)
_values.Add(ValueFactory.Create());
else
_values.Add(value);
}

_values.Add(value ?? ValueFactory.Create());
}

/// <summary>
/// Вставляет значение в массив по указанному индексу
/// </summary>
/// <param name="index">Число: Индекс вставляемого значения.
/// Если индекс превышает размер массива, то массив дополняется элементами Неопределено до указанного индекса.
/// Если индекс отрицательный, то выбрасывается исключение</param>
/// <param name="value">Произвольный: Вставляемое значение. Если не указано, то вставляется Неопределено</param>
[ContextMethod("Вставить", "Insert")]
public void Insert(int index, IValue value = null)
{
Expand All @@ -104,26 +129,27 @@ public void Insert(int index, IValue value = null)
if (index > _values.Count)
Extend(index - _values.Count);

if (value == null)
_values.Insert(index, ValueFactory.Create());
else
_values.Insert(index, value);
_values.Insert(index, value ?? ValueFactory.Create());
}

/// <summary>
/// Выполняет поиск элемента в массиве
/// </summary>
/// <param name="what">Произвольный: Искомое значение</param>
/// <returns>Если элемент найден, возвращается его индекс, иначе Неопределено</returns>
[ContextMethod("Найти", "Find")]
public IValue Find(IValue what)
{
var idx = _values.FindIndex(x => x.StrictEquals(what));
if(idx < 0)
{
return ValueFactory.Create();
}
else
{
return ValueFactory.Create(idx);
}
}

return idx>=0 ? ValueFactory.Create(idx) : ValueFactory.Create();
}

/// <summary>
/// Удаляет значение из массива
/// </summary>
/// <param name="index">Число: Индекс удаляемого элемента.
/// Если индекс находится за границами массива, то выбрасывается исключение
/// </param>
[ContextMethod("Удалить", "Delete")]
public void Remove(int index)
{
Expand All @@ -133,21 +159,39 @@ public void Remove(int index)
_values.RemoveAt(index);
}

/// <summary>
/// Получает наибольший индекс элемента массива
/// </summary>
/// <returns>Наибольший индекс в массиве. Если количество элементов массива равно 0, возвращает -1</returns>
[ContextMethod("ВГраница", "UBound")]
public int UpperBound()
{
return _values.Count - 1;
}

}

/// <summary>
/// Получает значение из массива по индексу
/// </summary>
/// <param name="index">Число: Индекс элемента.
/// Если индекс находится за границами массива, то выбрасывается исключение
/// </param>
/// <returns>Значение элемента массива</returns>
[ContextMethod("Получить", "Get")]
public IValue Get(int index)
{
if (index < 0 || index >= _values.Count)
throw RuntimeException.IndexOutOfRange();

return _values[index];
}

}

/// <summary>
/// Устанавливает значение в массиве по индексу
/// </summary>
/// <param name="index">Число: Индекс элемента.
/// Если индекс находится за границами массива, то выбрасывается исключение
/// </param>
/// <param name="value">Произвольный: Устанавливаемое значение</param>
[ContextMethod("Установить", "Set")]
public void Set(int index, IValue value)
{
Expand All @@ -165,20 +209,22 @@ private void Extend(int count)
}
}

private static void FillArray(ArrayImpl currentArray, int bound)
private static ArrayImpl CreateArray(int bound)
{
var array = new ArrayImpl(bound);
for (int i = 0; i < bound; i++)
{
currentArray._values.Add(ValueFactory.Create());
array._values.Add(ValueFactory.Create());
}
return array;
}

private static IValue CloneArray(ArrayImpl cloneable)
private static ArrayImpl CloneArray(ArrayImpl cloneable)
{
ArrayImpl clone = new ArrayImpl();
ArrayImpl clone = new ArrayImpl(cloneable._values.Count);
foreach (var item in cloneable._values)
{
clone._values.Add(item ?? ValueFactory.Create());
clone._values.Add(item is ArrayImpl arr ? CloneArray(arr) : item );
}
return clone;
}
Expand All @@ -198,35 +244,37 @@ public static ArrayImpl Constructor()
public static ArrayImpl Constructor(IValue[] dimensions)
{
if (dimensions.Length == 1 && dimensions[0] is FixedArrayImpl fa)
{
return Constructor(fa);
{
return Constructor(fa);
}

ArrayImpl cloneable = null;
for (int dim = dimensions.Length - 1; dim >= 0; dim--)

// fail fast
int size = 0;
for (int dim = 0; dim < dimensions.Length; dim++)
{
if (dimensions[dim] == null)
throw RuntimeException.InvalidNthArgumentType(dim + 1);

int bound = (int)dimensions[dim].AsNumber();
if (bound <= 0)
throw RuntimeException.InvalidNthArgumentType(dim + 1);
size = (int)dimensions[dim].AsNumber();
if (size <= 0)
throw RuntimeException.InvalidNthArgumentValue(dim + 1);

var newInst = new ArrayImpl();
FillArray(newInst, bound);
if(cloneable != null)
{
for (int i = 0; i < bound; i++)
{
newInst._values[i] = CloneArray(cloneable);
}
}
cloneable = newInst;

}

var newInst = CreateArray(size); // длина по последней размерности

for (int dim = dimensions.Length - 2; dim >= 0; dim--) // если размерность >= 2
{
ArrayImpl nested = newInst;
int bound = (int)dimensions[dim].AsNumber();

newInst = new ArrayImpl(bound);
for (int i = 0; i < bound; i++)
{
newInst._values.Add(CloneArray(nested));
}
}

return cloneable;

return newInst;
}

[ScriptConstructor(Name = "На основании фиксированного массива")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public void LoadColumn(IValue values, IValue columnIndex)
[ContextMethod("ВыгрузитьКолонку", "UnloadColumn")]
public ArrayImpl UnloadColumn(IValue column)
{
var result = new ArrayImpl();
var result = new ArrayImpl(_rows.Count);

foreach (var row in _rows)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public void LoadColumn(ArrayImpl values, IValue columnIndex)
[ContextMethod("ВыгрузитьКолонку", "UnloadColumn")]
public ArrayImpl UnloadColumn(IValue column)
{
ArrayImpl result = new ArrayImpl();
ArrayImpl result = new ArrayImpl(_rows.Count);

foreach (ValueTreeRow row in _rows)
{
Expand Down
2 changes: 1 addition & 1 deletion src/OneScript.StandardLibrary/SystemEnvironmentContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ public FixedArrayImpl GetLogicalDrives
{
get
{
var arr = new ArrayImpl();
var data = Environment.GetLogicalDrives();
var arr = new ArrayImpl(data.Length);
foreach (var itm in data)
{
arr.Add(ValueFactory.Create(itm));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public void WaitCompletionOfTasks()
public ArrayImpl GetBackgroundJobs(StructureImpl filter = default)
{
if(filter == default)
return new ArrayImpl(_tasks.ToArray());
return new ArrayImpl(_tasks);

var arr = new ArrayImpl();
foreach (var task in _tasks)
Expand Down
Loading