DUP
VARIABLEN
!
Это фрагмент дублирует значение N лежащее на стёке, следующая команда (Variable) резервирует в необходимое количество ячеек памяти и старший адрес зарезервированной области кладёт на стёк. Восклицательный знак снимает два значения со стека (адрес и значение N) и значение пересылает по адресу. Если теперь нам необходимо получить значение переменной N мы должны выполнить следующее:
N @
N - теперь воспринимается как команда языка Форт с её выполнением на стек ложится значение адреса памяти по которому хранится значение переменной. Знак собачки снимает со стека значение адреса, затем пересылает значение, взятое по этому адресу, на вершину стека и теперь мы можем выполнить команду ROLL. Она снимет со стека значение N и осуществит требуемый сдвиг массива.
И осталось завершить циклы
LOOP
LOOP
Если есть потребность просмотреть массив, необходимо вывести все элементы стека на экран циклическим повторением команды точка.
N @ (кладем на стек количество элементов массива)
1 (Кладем на стёк начальное значение параметра цикла)
DO (Снимаем со стека параметры цикла и начинаем работу)
. (Снимаем очередной элемент стека)
LOOP (Переходим к новому шагу цикла)
Запишем полученную программу целиком
(Создание переменной)
DUP
VARIABLEN
!
(Создание необходимой структуры данных для организации циклов)
DUP
1
SWAP
1
(Обработка массива)
DO
DO
2DUP
>
IF
ELSE
SWAP
THEN
N @
ROLL
LOOP
LOOP
(Вывод массива для просмотра)
N @
1
DO
.
LOOP
Тип данных это не только указание на необходимый объём памяти, но и перечень допустимых операций. Эти самые допустимые операции выглядят так очевидно, что наверное не сразу возникает идея, что допустимые операции также можно определять.
Конечно, те операции, которые приклеиваются к базовым типам, реализуются разработчиком компилятора и они для изменения недоступны, и конечно, нельзя допустить, чтобы программист - пользователь компилятора имел возможность менять код компилятора, но операцию можно реализовать и средствами самого языка высокого уровня. Это будет почти та же самая процедура или функция языка, с той лишь разницей, что она будет жёстко привязана к конкретным данным. Если таким образом к стандартному типу данных (такому как мы рассматривали в первой лекции) добавить набор процедур и функций, то получится совершенно новая языковая структура именуемая объектом. Объект хорошо тем, что в нём полностью описывается всё, что нужно для понимания его смысла, обработки, размещения в памяти, поэтому программа, построенная из объектов, становится более понятной и более прозрачной для восприятия. Такой подход широко распространён. Это сейчас называется объектным программированием, а язык Форт - это один из первых языков, где прозвучала идея объектного программирования. Правда в Форте нет терминов используемых ныне: объект, класс, инкапсуляция и т.д., но ведь это одна из первых попыток! А теперь перейдём к Форту.
Определяющее слово Форта выполняет две функции: во-первых, определяет понятие (резервирует память, указывает, откуда брать значения и т.д.) и, во-вторых, определяет действия, которые можно выполнять над определёнными понятиями. В соответствии с этим двумя функциями определяющее слово состоит из двух составляющих частей: создающей и исполняемой.
Синтаксис определяющего слова
CREATE > СОЗДАВАЕМАЯ ЧАСТЬ
DOES > ИСПОЛНЯЕМАЯ ЧАСТЬ
Рассмотрим в качестве примера определение понятия вектор. При создании вектора будем указывать размер (число элементов), а при обращении к нему - индекс элемента, в результате чего получается адрес данного элемента. Этот адрес можно разыменовать и получить значение элемента или можно заслать по этому адресу новое значение. Если желательно контролировать правильность индекса при обращении к вектору, то определение может выглядеть так:
; Вектор CREATE DUP , 2*ALLOT
DOES >
OVER 1- OVERU< (Проверка индекса)
IFSWAP 2 * + EXITTHEN
. "Ошибка в индексе"
Рассмотрим, как работает данное определение при создании вектора 10 вектор Х.
Создающая часть компилирует размер вектора и вслед за этим отводит память на 10*2 байт. Таким образом, в словаре для вектора Х отводится размером 22 байта, в первых двух байтах хранится число 10 - размер вектора. При обращении к вектору Х на стеке должно находиться значение индекса. Слово DOES> кладёт сверху адрес области сформированной создающей частью, после чего работает исполняющая часть определения. Проверив, что индекс лежит в диапазоне между 1 и 10, она оставляет на стёке адрес, равный начальному адресу области плюс I*2 то есть адрес I - го элемента вектора, если считать, что элементы располагаются в зарезервированной области подряд. Если окажется, что индекс не положителен или больше числа элементов, то будет напечатано сообщение "Ошибка в индексе" и исполнение закончится через слово ABORT.
Вспомним, что первые компьютеры обладали очень ограниченной памятью. Это было так не только из-за дороговизны оперативной памяти и даже не столько из-за неё, сколько из-за ограниченной возможности процессора адресовать память. Разрядность процессора налагает на величину максимального адреса очень жесткое ограничение. Если же основная масса памяти организована в виде стека, то проблема адресации уходит, так как запоминать необходимо только одну ячейку - вершину стека. Ещё одна крайне интересная особенность Форта видна в первых трёх примерах. Достаточно сложные вычислительные процессы идут совершенно без использования понятия переменной. Такая организация памяти, как уже упоминалось, существенным образом влияет на организацию подпрограмм. В некотором смысле их нет, а есть поток заданий, каждое из которых может представлять собой подпрограмму с точки зрения пользователя, чтобы понять механизм такого действа, нужно более тщательно рассмотреть работу Форт системы в целом, что уже выходит за рамки данной работы.
Литература
1. Вострикова З.П. и др. "Программирование на языке "БЕЙСИК" для персональных ЭВМ". Машиностроение, 1993г.
2. Гохман А.В. и др. "Сборник задач по математической логике и алгебры множеств", издательство Саратовского Университета, 1969г.
3. Гусев В.В. Основы импульсной техники. М. Советское радио, 1975
4. Касаткин В.Н. "Информация, алгоритмы, ЭВМ", М. Просвещение, 1991г.
5. Машовцев В.А. Вступительные экзамены по информатике//Информатика. 1997, №13
6. Орлов В.А. О вступительных экзаменах по информатике//Информатика, 1997, №15
7. Яснева Г.Г. Логические основы ЭВМ//Информатика и образование, 1998, №2
8. Лыскова В.Ю., Ракитина Е.А. Логика в информатике, М. Информатика и образование 1999
9. Шауцкова Л.З. “Решение логических задач средствами алгебры логики”, газета Информатика 1999, №5.