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
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
| `count()` | Возвращает количество элементов в стеке |
| `empty()` | Возвращает `Истина`, если стек не содержит элементов |
| `clear()` | Удаляет все элементы из стека |
| `contains(значение)` | Возвращает `Истина`, если указанное значение присутствует среди элементов стека |

Стек может хранить значения любого типа, включая объекты — `pop()`/`peek()` возвращают тот же самый объект, который был передан в `push()`, без копирования.
Стек может хранить значения любого типа, включая объекты — `pop()`/`peek()` возвращают тот же самый объект, который был передан в `push()`, без копирования. `contains()` сравнивает значения строгим равенством: для примитивов (числа, строки и т.п.) — по значению, для объектов — по ссылке.

## Установка

Expand Down Expand Up @@ -47,6 +48,11 @@
Стек.push(1);
Стек.clear();
Сообщить(Стек.empty()); // Истина

Стек.push(1);
Стек.push(2);
Сообщить(Стек.contains(2)); // Истина
Сообщить(Стек.contains(35)); // Ложь
```

Попытка получить элемент из пустого стека (`pop()` или `peek()`) бросает исключение с текстом `stack underflow`:
Expand Down
196 changes: 117 additions & 79 deletions src/stack.os
Original file line number Diff line number Diff line change
@@ -1,79 +1,117 @@

Var mStackContainer;

// Возвращает количество элементов, находящихся в стеке.
//
// Возвращаемое значение:
// Число - количество элементов в стеке.
//
Function count() Export
return mStackContainer.count();
EndFunction

// Добавляет элемент на вершину стека.
//
// Параметры:
// value - Произвольный - значение, добавляемое на вершину стека.
//
Function push(value) Export
mStackContainer.add(value);
EndFunction

// Извлекает элемент с вершины стека и удаляет его из стека.
// Если стек пуст, вызывает исключение с текстом "stack underflow".
//
// Возвращаемое значение:
// Произвольный - значение, находившееся на вершине стека.
//
Function pop() Export
Var topValue;

// we want to check for underflow and throw exception here
// peek() does this so we utilize it to reuse code
topValue = this().peek();
mStackContainer.delete(mStackContainer.UBound());

return topValue;
EndFunction

// Возвращает элемент с вершины стека, не удаляя его из стека.
// Если стек пуст, вызывает исключение с текстом "stack underflow".
//
// Возвращаемое значение:
// Произвольный - значение, находящееся на вершине стека.
//
Function peek() Export
If this().empty() Then
Raise "stack underflow: attempt to get element out of empty stack object";
Endif;

return mStackContainer.get(mStackContainer.UBound());
EndFunction

// Проверяет, пуст ли стек.
//
// Возвращаемое значение:
// Булево - Истина, если стек не содержит элементов; иначе Ложь.
//
Function empty() Export
Return 0 = this().count();
EndFunction

// Удаляет все элементы из стека.
//
Procedure clear() Export
mStackContainer.Clear();
EndProcedure

Function this()
// early versions of intepreter didn't have ThisObject variable,
// only it's russian synonym - ЭтотОбъект
return ЭтотОбъект;
EndFunction

Procedure init()
mStackContainer = New Array;
EndProcedure


init();

Var _StackContainer;

// Возвращает количество элементов, находящихся в стеке.
//
// Возвращаемое значение:
// Число - количество элементов в стеке.
//
Function count() Export

return _StackContainer.count();

EndFunction


// Добавляет элемент на вершину стека.
//
// Параметры:
// value - Произвольный - значение, добавляемое на вершину стека.
//
Function push( value ) Export

_StackContainer.add( value );

EndFunction


// Извлекает элемент с вершины стека и удаляет его из стека.
// Если стек пуст, вызывает исключение с текстом "stack underflow".
//
// Возвращаемое значение:
// Произвольный - значение, находившееся на вершине стека.
//
Function pop() Export

Var topValue;

// we want to check for underflow and throw exception here
// peek() does this so we utilize it to reuse code
topValue = this().peek();
_StackContainer.delete( _StackContainer.UBound() );

return topValue;

EndFunction


// Возвращает элемент с вершины стека, не удаляя его из стека.
// Если стек пуст, вызывает исключение с текстом "stack underflow".
//
// Возвращаемое значение:
// Произвольный - значение, находящееся на вершине стека.
//
Function peek() Export

If this().empty() Then
Raise "stack underflow: attempt to get element out of empty stack object";
Endif;

return _StackContainer.get( _StackContainer.UBound() );

EndFunction


// Проверяет, пуст ли стек.
//
// Возвращаемое значение:
// Булево - Истина, если стек не содержит элементов; иначе Ложь.
//
Function empty() Export

Return 0 = this().count();

EndFunction


// Проверяет наличие указанного значения среди элементов стека.
//
// Параметры:
// value - Произвольный - значение, наличие которого проверяется.
//
// Возвращаемое значение:
// Булево - Истина, если значение содержится в стеке; иначе Ложь.
//
Function contains( value ) Export

Return _StackContainer.Find( value ) <> Undefined;

EndFunction


// Удаляет все элементы из стека.
//
Procedure clear() Export

_StackContainer.Clear();

EndProcedure


Function this()

// early versions of intepreter didn't have ThisObject variable,
// only it's russian synonym - ЭтотОбъект
return ЭтотОбъект;

EndFunction


Procedure init()

_StackContainer = New Array;

EndProcedure


init();
76 changes: 76 additions & 0 deletions tests/stack.os
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
Тесты.Добавить("ВызовClearОпустошаетСтек");
Тесты.Добавить("ВызовClearУЖеПустогоСтекаНеГенерируетИсключение");

Тесты.Добавить("ДолженИметьМетодContains");
Тесты.Добавить("МетодContainsВозвращаетИстинаЕслиЗначениеЕстьВСтеке");
Тесты.Добавить("МетодContainsВозвращаетЛожьЕслиЗначенияНетВСтеке");
Тесты.Добавить("МетодContainsВозвращаетЛожьДляПустогоСтека");
Тесты.Добавить("МетодContainsНеИзменяетКоличествоЭлементов");

Возврат Тесты;
КонецФункции

Expand Down Expand Up @@ -424,6 +430,76 @@
ОсвободитьОбъект(Стек);
КонецПроцедуры

Функция ДолженИметьМетодContains() Экспорт
Перем Стек, Рефлектор;

Стек = Новый Стек;
Рефлектор = Новый Рефлектор;
Ожидаем
.Что(Рефлектор.МетодСуществует(Стек, "contains"), "Объект стека должен иметь метод contains()")
.ЭтоИстина()
;

ОсвободитьОбъект(Стек);
ОсвободитьОбъект(Рефлектор);
КонецФункции

Функция МетодContainsВозвращаетИстинаЕслиЗначениеЕстьВСтеке() Экспорт
Перем Стек;

Стек = Новый Стек;
Стек.push(1);
Стек.push(2);
Стек.push(3);
Ожидаем
.Что(Стек.contains(2), "Значение, добавленное в стек, должно быть найдено методом contains()")
.Равно(Истина)
;

ОсвободитьОбъект(Стек);
КонецФункции

Функция МетодContainsВозвращаетЛожьЕслиЗначенияНетВСтеке() Экспорт
Перем Стек;

Стек = Новый Стек;
Стек.push(1);
Стек.push(2);
Ожидаем
.Что(Стек.contains(35), "Значение, не добавлявшееся в стек, не должно быть найдено методом contains()")
.Равно(Ложь)
;

ОсвободитьОбъект(Стек);
КонецФункции

Функция МетодContainsВозвращаетЛожьДляПустогоСтека() Экспорт
Перем Стек;

Стек = Новый Стек;
Ожидаем
.Что(Стек.contains(1), "У пустого стека не может быть найдено ни одно значение")
.Равно(Ложь)
;

ОсвободитьОбъект(Стек);
КонецФункции

Функция МетодContainsНеИзменяетКоличествоЭлементов() Экспорт
Перем Стек;

Стек = Новый Стек;
Стек.push(1);
Стек.contains(1);
Стек.contains(35);
Ожидаем
.Что(Стек.count(), "Вызов contains() не должен изменять количество элементов в стеке")
.Равно(1)
;

ОсвободитьОбъект(Стек);
КонецФункции

Процедура Инициализация()
ПодключитьСценарий(ОбъединитьПути(ТекущийСценарий().Каталог, "..", "src", "stack.os"), "Стек");
КонецПроцедуры
Expand Down