Раздел: Язык программирования Форт
Язык программирования Форт
Раздел является первой крупной отечественной публикацией по языку Форт. Этот язык, получивший широкое распространение за рубежом (особенно как средство программирования для персональных ЭВМ), стал привлекать внимание и советских программистов благодаря особенностям своей методологии. Язык Форт сочетает в себе достоинства интерпретирующих и компилирующих систем и ориентирован на диалоговый режим работы. В книге приведено большое количество примеров.
Книга рассчитана на широкий круг инженеров-программистов и может быть полезна пользователям...
Система программирования
Система программирования на Форте (форт-система) обычно обеспечивает полный набор средств поддержки для разработки и исполнения программ: операционную систему, интерпретатор для диалогового исполнения, компилятор, ассемблер, текстовый редактор и обслуживающие программы. Все эти компоненты являются расширениями Форта и написаны на том же Форте. Таким образом Форт является одновременно и системой для пользователя, и собственной метасистемой, т. е. системой, описывающей саму себя.
В соответствии с общим принципом Форта в форт-системе используется...
Основные понятия
Приступая к изучению нового для нас языка программирования, мы прежде всего задаемся вопросами: какие конструкции есть в этом языке (какова морфология), как они записываются (каков синтаксис) и что означают (какова семантика). Например, в широко распространенном языке Паскаль имеется около двадцати конструкций (идентификатор, число без знака, присваивание, условный оператор и др.), синтаксис которых обычно задают с помощью граф-схем или порождающих правил, а семантику объясняют на основе той или иной машинно независимой модели вычислений....
Работа в диалоговом режиме
Программирование на языке Форт является существенно диалоговым. Работая за терминалом, программист вводит слова-команды, а загруженная в память ЭВМ форт-система, т. е. реализация языка Форт на данной ЭВМ, немедленно выполняет обозначаемые этими словами действия. О своей готовности к обработке очередной строки текста форт-система обычно сообщает программисту специальным приглашением (например, знаком < , который печатается на терминале). Получив такое приглашение, программист набирает на терминале очередную порцию форт-текста, заканчивая...
Стек данных и вычисления
Как уже говорилось, в основе вычислительной модели для языка Форт лежит стековая машина. Ее команды (слова в языке Форт) обычно используют в качестве своих операндов верхние элементы стека, убирая их со стека и возвращая результаты (если они есть) на место операндов. Как правило, слова используют одно-два верхних значения на стеке. Для их описания будем применять следующую диаграмму:
имя вершина стека 5о —> вершина стека после слова исполнения слова исполнения слова
При этом считаем, что самое верхнее значение в стеке (последнее добавленное)...
Внешнее представление чисел
Для внешнего представления чисел используется система счисления, задаваемая программистом. Стандарт языка предусматривает следующие слова для переключения в наиболее общеупотребительные системы:
DECIMAL —> десятичная
HEX —> шестнадцатиричная
OCTAL —> восьмеричная
Первоначально устанавливается десятичная система. Если в процессе работы будет исполнено, например, слово HEX (от HEXADECIMAL — шестнадцатиричная), то при дальнейшем вводе и выводе чисел будет использоваться шестнадцатиричная система с цифрами от 0 до 9 и от А до F до тех пор, пока...
Использование стека для хранения промежуточных значений
Использование стека для хранения промежуточных значений естественным образом приводит к так называемой «обратной польской форме» — одному из способов бесскобочной записи арифметических выражений, подразумевающему постановку знака операции после операндов. Например, выражение (A/B + Q * (D*E — F*(G — Н)) записывается следующим образом: А В/ С + DE*FGH — * — *. Очевидно, что этот текст выполним для Форта, если А, В и т. д.— слова, которые кладут на стек по одному числу. Таким образом, форт-систему можно использовать как калькулятор. Чтобы вычислить,...
Введение новых слов
Замечательное свойство языка Форт — это возможность вводить в него новые слова, расширяя тем самым набор его команд в нужном программисту направлении. Для введения новых слов чаще всего используется определение через двоеточие — определение нового слова через уже известные. Такое определение начинается словом : (двоеточие) и заканчивается словом ; (точка с запятой). Сразу после двоеточия идет определяемое слово, а за ним — последовательность слов, через которые оно определяется.
Например, текст : S2 DUP * SWAP DUP * + ; определяет слово S2 , вычисляющее...
Текстовый интерпретатор
Проследим за работой текстового интерпретатора по обработке уже рассмотренного определения слова : S2 DUP * SWAP DUP * + ; . Предположим, что перед началом обработки введенной строки интерпретатор находится в состоянии исполнения. Первым словом является : (двоеточие), которое исполняется. Его семантика состоит в том, что из входной строки выбирается очередное слово и запоминается в качестве определяемого, а интерпретатор переключается в состояние компиляции. Следующие слова, которые интерпретатор будет извлекать из входной строки ( DUP , # , SWAP и...
Константы и переменные, работа с памятью
Программисту часто бывает удобно работать не с «анонимными» значениями, а с именованными. По аналогии со средствами других языков эти средства языка Форт называются константами и переменными. Впоследствии мы увидим, что они являются не «изначальными», а (наряду с определениями через двоеточие) частными случаями более общего понятия «определяющие слова».
Слово CONSTANT (константа) А ->- работает следующим образом. Со стека снимается верхнее значение, а из входного текста выбирается очередное слово и запоминается в словаре как новая команда....
Константы и переменные
Константы и переменные позволяют программисту использовать память в словаре вполне определенным образом. А как быть, если требуется что-то иное? Общий принцип языка Форт состоит в том, чтобы не закрывать от программиста даже самые элементарные единицы, из которых строятся его более сложные слова, а предоставлять их наравне с другими словами. Элементарными словами для работы с памятью в словаре, помимо приведенных выше @ и ! , являются следующие:
HERE — > А ALLOT А — > , А — >
Предполагается, что словарь занимает некоторую начальную часть адресного...
Логические операции
В языке Форт имеется только один тип значений — 16-разрядные двоичные числа, которые, как мы видели, рассматриваются в зависимости от ситуации как целые числа со знаком или как адреса и т. д. Точно так же подходят и к проблеме представления логических значений ИСТИНА и ЛОЖЬ: число 0, в двоичном представлении которого все разряды нули, представляет значение ЛОЖЬ, а любое другое 16-разрядное значение понимается как ИСТИНА.
Вместе с тем стандартные слова, которые должны возвращать в качестве результата логическое значение, из всех возможных представлений...
Структуры управления
Во всех приводившихся выше определениях слов тело определения записывалось как последовательность уже известных слов-команд; семантика определяемого таким образом слова состоит в последовательном выполнении слов-команд тела. Помимо последовательного исполнения традиционными приемами в программировании стали ветвление (выбор между разными последовательностями действий) и цикл (многократное повторение одной последовательности действий).
В языке Форт тоже имеются условные операторы и циклы, реализованные с помощью специальных слов-команд,...
Циклом с проверкой в конце
Цикл BEGIN—UNTIL называется циклом с проверкой в конце. После исполнения слов, составляющих его тело, на стеке остается логическое значение — условие завершения цикла. Слово UNTIL (пока не) снимает это значение со стека и анализирует его. Если это ИСТИНА (не нуль)» то исполнение цикла завершается, т. е. далее будут исполняться слова, следующие за UNTIL , а если это ЛОЖЬ (нуль), то управление возвращается к началу цикла от слова BEGIN . Например, определение слова, вычисляющего факториал, может выглядеть так:
Как и ранее, в комментариях, сопровождающих каждую...
Литеры и строки, форматный вывод чисел
В современном программировании важное место занимает обработка текстовых данных. С каждой литерой, которую можно ввести с внешнего устройства или вывести на него, связывается некоторое число — код этой литеры, так что в памяти ЭВМ литеры представлены своими кодами. Стандарт языка Форт предусматривает использование таблицы кодов ASCII, в которой задействованы все числа в диапазоне от 0 до 127. Каждый код занимает один 8-разрядный байт, в котором для представления литеры используются младшие 7 разрядов.
Такая привязка к одной конкретной кодировке...
Кодирование пробела
Ввиду его особой важности для кодирования пробела выделена специальная константа BL (от BLANK — пробел), которую для кода ASGII можно задать так: 32 CONSTANT BL. При исполнении слова BL на стеке остается код пробела. Чтобы вывести пробел на терминал, имеются следующие стандартные слова:
« SPACE ( — > ) BL EMIT | i SPACES < N--->) ?DUP IF 0 DO SPACE LOOP THEN f
Слово SPACE (пробел) выводит на терминал один пробел, а слово SPACES (пробелы) — несколько, снимая их количество со стека (это значение, как и длина строки в слове TYPE, должно быть неотрицательным).
Внутри определений через двоеточие...
Форматные преобразования
Важной областью применения строковых значений являются форматные преобразования, позволяющие переводить число из машинного двоичного представления в строку литер. Эти преобразования выполняются над числами двойной длины, результирующая строка размещается во временном буфере PAD (прокладка), который заполняется с конца. Такое название буфера связано с тем, что он располагается в незащищенной части адресного пространства между словарем и стеком. Слово PAD кладет на стек адрес конца этого буфера и обычно определяется так:
Г PAD ( —> А ) HERE...
Определяющие слова
Конструкции языка Форт, которые мы рассматривали до сих пор, имеют аналоги в других известных языках программирования. Например, определению через двоеточие очевидным образом соответствует описание процедуры в языках Фортран и Паскаль. Теперь мы рассмотрим свойство языка Форт, которое существенно отличает его от других и в значительной степени определяет его как нечто новое.
Программируя какую-либо задачу, мы моделируем понятия, в которых эта задача формулируется и решается, через понятия данного языка программирования. Традиционные...
Понятие вектора
Рассмотрим другой пример. Введем понятие вектора. При создании вектора будем указывать размер (число элементов), а при обращении к нему — индекс (номер) элемента, в результате чего получается адрес данного элемента. Этот адрес можно разыменовать и получить значение элемента или можно заслать по этому адресу новое значение. Если желательно контролировать правильность индекса при обращении к вектору, то определение может выглядеть так:
ОШИБКА В ИНДЕКСЕ" ABORT j
Разберем, как работает данное определение при создании вектора 10 вектор X.
Создающая...
Шитый код и его разновидности
Логически можно выделить два подхода к реализации языков программирования — трансляцию и интерпретацию. Транслятор преобразует входной текст программы в машинный код данной ЭВМ; впоследствии этот код, объединяясь с другими машинными модулями, образует рабочую программу, которую можно загрузить в оперативную память и исполнить. Интерпретатор непосредственно исполняет программу на языке высокого уровня, рассматривая входной текст как последовательность кодов операций, управляющих его работой. Между этими полюсами располагается целый...
Разновидности шитого кода
Во всех разновидностях шитого кода его интерпретатор должен обеспечивать выполнение трех действий, которые традиционно обозначаются так:
NEXT (следующий) — переход к интерпретации следующей ссылки в данной последовательности ссылок;
CALL (вызов) — переход в подпрограмму верхнего уровня, представленную в шитом коде;
RETURN (возврат) — возврат из подпрограммы верхнего уровня на продолжение интерпретации.
В силу его очевидной рекурсивности интерпретатор использует специальный стек в качестве собственной структуры данных. Этот стек называется...
Косвенный шитый код
Косвенный шитый код уступает прямому по скорости исполнения, но имеет то преимущество, что его высокоуровневые подпрограммы не зависят от машины, поскольку не содержат машинных кодов. Как и в случае прямого кода, последовательность операций промежуточного языка состоит из последовательности адресов подпрограмм, разница заключается в организации этих подпрограмм и действиях интерпретатора. Теперь чтобы передать управление на машинный код, в действии NEXT требуется выполнить еще одно разыменование.
Подпрограмма верхнего уровня начинается...
Структура словарной статьи
Каждое слово-команда, известное форт-системе, хранится в оперативной памяти (в словаре) в виде специальной структуры данных — словарной статьи, состоящей из поля имени, поля связи, поля кода и поля параметров. Стандарт не фиксирует порядок взаимного расположения этих полей, оставляя его на усмотрение разработчиков реализации. Как правило, поля располагаются подряд в том порядке, как они перечислены выше.
Поля имени и связи вместе образуют заголовок словарной статьи, который нужен для поиска статьи по имени слова. Результатом поиска являются...
Байт-счетчик
Изображены две словарные статьи: верхнего уровня для слова F, определенного через двоеточие, и нижнего уровня для слова EXIT, являющаяся к тому же частью адресного интерпретатора.
Поле имени каждой статьи начинается байтом-счетчиком, в котором записано число литер в имени слова. Далее располагаются коды самих этих литер.
Вслед за полем имени идет поле связи, содержащее адрес поля имени предыдущей словарной статьи. В тех реализациях, где двухбайтные значения должны располагаться с четного адреса, поле имени тоже располагают с четного адреса,...
Стек возвратов и реализация структур управления
Один из важных принципов языка Форт состоит в том, чтобы предоставить программисту максимальный доступ ко всем средствам его реализации. В соответствии с этим принципом собственные данные адресного интерпретатора — стек возвратов — были сделаны доступными, для чего введены специальные слова: > RA ->, R> ->А и R@->A. Буква R (от RETURN— возврат) в имени этих слов напоминает о том, что они работают со стеком возвратов. Все эти слова можно использовать только внутри компилируемых определений. Во время исполнения любого такого определения, представленного...
Определение слова PBRANCH
То обстоятельство, что в определении слова PBRANCH используется условный оператор, для реализации условного оператора несущественно, потому что на практике слова BRANCH и PBRANCH реализуются в форт-системах как подпрограммы нижнего уровня. Приведенные определения лишь иллюстрируют выразительные возможности языка, показывая, что даже такие, самые элементарные действия можно задать машиннонезависимым способом в виде высокоуровневых определений.
Слово LITERAL анализирует текущее состояние текстового интерпретатора: если это компиляция, то компилирует...
Адрес зарезервированного места
В этих определениях для контроля вместе с адресом зарезервированного места передается число I, которое проверяется с помощью слова PPAIRS в словах, использующих переданный адрес. Такой простой способ контроля на практике оказывается вполне достаточным. При этом программист может встроить любой другой контроль по своему желанию.
Приведенное определение условного оператора связано с реализацией стандартных слов BRANCH и PBRANCH , выполняющих переходы в шитом коде. Из соображений эффективности эти слова обычно задают как подпрограммы нижнего...
LOOP
Аналогично работает и слово ( + LOOP) , которое дополнительно снимает со стека данных значение шага цикла. Разумеется, реализация этих слов должна соответствовать принятому способу задания переходов в шитом коде. Для прямых адресов перехода соответствующие определения можно задать так:
I (DO) ( А2: ГРАНИЧНОЕ, AI s НАЧАЛЬНОЕ > )
Определение ( + LOOP) выглядит аналогично.
Во всех приведенных примерах доступ к адресу возврата в шитом коде осуществляется через стек возвратов из данного определения. Этот адрес модифицируется словами 2+или @ , тем самым обеспечивая...
Управление поиском слов
Множество слов, «известных» форт-системе, хранится в словаре в виде одного или более цепных списков словарных статей, соединенных через поле связи. Порядок поиска статей в этих списках обратен порядку их включения в словарь по времени определения: статья последнего определенного слова находится в начале списка. Такой порядок делает естественным исключение слов из словаря с помощью слова FORGET : нужный список просто усекается до соответствующего места.
Являясь самостоятельной структурой данных, список слов имеет и соответствующее определяющее...
FORTH
В конечном счете любой список заканчивается словами списка FORTH , который уже не имеет базового. На рис. 2.7 показаны поля параметров списков А , В и FORTH . Список В является базовым для А и, в свою очередь, базируется на списке FORTH. Слова Аь ..., А/ входят в список А ; Bi, ... , В* — в В и Fi, ... , F„ — в FORTH.
Показанный на рисунке порядок поиска слов соответствует исполнению текста В DEFINITIONS А, в результате чего сначала будут просмотрены списки А , В , FORTH , а затем В , FORTH .
Чтобы обеспечить большую гибкость в управлений порядком поиска слов и иметь возможность переопределять...
