Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Таунсенд Проектирование и программная реализац...doc
Скачиваний:
15
Добавлен:
12.11.2019
Размер:
4.53 Mб
Скачать

Слова literal (в), слова ; (с). Переменная ip переводится словом периода выполнения в положение сброшенного указателя

Компилирующие слова расширяют возможности компиляции. С помощью определяющих слов создаются новые слова. Все слова, введенные конкретным определяющим словом, используют одну и ту же подпрограмму периода выполнения. Например, все слова, определенные через двоеточие, в процессе исполнения вызывают подпрограмму NEST. Переменные, определенные словом VARIAB- LE, будут обращаться к подпрограмме (VAR), а константы - к (CON). Действия этих переменных в период выполнения объясне- ны выше, но мы пока еще не касались вопросов их компиляции.

При компиляции широко применяется слово CREATE. Оно со- здает в словаре поле имени, а также cfa, указывающий на подпро- грамму (VAR). Если у создаваемого слова процедура периода ис- полнения иная, нежели для переменной то cfa должен быть позд- нее изменен. Прежде всего слово CREATE строит поле связи для того, чтобы включить заголовок создаваемого им слова в некото- рый список словаря. CREATE почти полностью завершает построе- ние переменной, за исключением выделения памяти под ее значе- ние, т.е. оно создает не тело, а только заголовок. Под переменную необходимо выделить еще одну ячейку памяти Форт-системы для хранения ее числового значения.

Выделение памяти осуществляется словом ALLOT, резервиру- ющим область памяти заданного размера:

ALLOT (n ==> )

Выделение в словаре п байт.

ALLOT - простое слово, его определение выглядит так: : ALLOT DP +! ;

Здесь DP - системная переменная Форта, которая содержит указатель на свободную область памяти, находящуюся непосред- ственно за последним байтом словаря. Конечно, этот адрес можно также получить с помощью команды DP@, но она применяется на- столько часто, что ее целесообразно включить в число стандартных средств Форта в виде слова:

HERE ( ==> addr )

Возвращает адрес свободной области памяти, расположенной непосредственно за словарем.

Наконец, еще одно элементарное слово, применяемое при построении словаря, определяется следующим образом:

: , HERE ! 2 ALLOT ;

Данное определение справедливо для версий Форта, реализо- ванных на 16-разрядных процессорах. Таким образом, чтобы за- першить формирование определяющего слова для переменной, нам

146

147

необходимо только выделить два байта под ее значение. Для этой цели следует воспользоваться командой 2 ALLOT. Затем перемен- ной необходимо присвоить начальное значение, равное нулю, что легче всего сделать с помощью слова "запятая", расположив его в упомянутом выражении после нуля:

: VARIABLE CREATE 0 , ;

Более широкие по сравнению с другими языками возможности Форта заключаются не в наличии средств для определения слов, не входящих в стандартный набор, а в том, что вы можете вводить новые определяющие слова и их исполняющие процедуры. Впоследствии эти определяющие слова применяются для задания новых слов, таких, как : (двоеточие) и VARIABLE.

Помимо периода компиляции и периода выполнения в Форте еще выделяется этап третьего типа - период компиляции определя- ющего слова. Оно называется периодом определения. Процедура DOES> позволяет вводить подпрограммы периода выполнения для слов, заданных с помощью новых определяющих слов. В качестве иллюстрации рассмотрим определение слова ARRAY, создающего массивы. Во время компиляции выполняются следующие дейст- вия. Слово

ARRAY (n ==> )

считывает число п, которое указывает размерность массива, задаваемую количеством выделенных ячеек памяти. Затем во время исполнения происходит обращение к слову

ARRAY ( n ==> addr)

При этом со стека снимается индекс созданного словом ARRAY массива и возвращает указатель на соответствующее значение. Определение слова ARRAY имеет вид:

: ARRAY CREATE 2 * ALLOT DOES> SWAP 2 * + ; Пусть слово ARRAY встретилось в выражении: 10 ARRAY A1

Здесь слово ARRAY сначала создаст заголовок А1, затем извлечет из стека число 10, удвоит его и выделит 20 байт памяти под тело А1. На этом закончится период компиляции для А1.

Слово DOES> отмечает, что далее следует период выполнения для массивов. Вначале в cfa массива А1 возвращается значение, указывающее на начало последовательности действий. Затем ком- пилируется машинный код перехода на слово (DOES) - исполняю- щую процедуру для DOES. Она создает шитый код, находящийся

148

Р ис. 6.8. Слово Форта DOES>, определенное через двоеточие, ком- пилирует в слове ARRAY последовательность: (;CODE), JSR и (DOES>). Во время определения словом ARRAY слова А1 команда 'CODE) помещает rta в cfa слова А1. Команда (DOES>) инициирует выполнение внутренним интерпретатором процедуры периода выпол- нения слова ARRAY, которое находится за (DOES>)

149

за JSR (DOES), который и выполняется. Перечисленные действия слова DOES показаны на рис. 6.8. Их суть лучше всего пояснить в терминах трех типов периодов, выделяемых в процессе обработки'; слова.

В период определения слово ARRAY создается (компилирует-; ся). Во время компиляции производятся стандартные действия до тех пор, пока не встретится слово DOES>. Оно является компили- рующим и будет выполнено немедленно. Слово DOES>, определен- ное через двоеточие, последовательно компилирует cfa выражения (; DOES) в ARRAY, затем машинную команду перехода JSR и, на- конец, cfa слова (DOES), имеющего тип CODE. Следующие за DOES> слова - исполняющие подпрограммы ARRA\ - компилиру- ются как элементы высокого уровня (шитый код).

Во время компиляции теперь, когда слово ARRAY уже опре- делено, происходит собственно создание массива А1. Таким об-j разом, для слова ARRAY начинается период выполнения, а для массива А1 - период компиляции. Подпрограмма периода выпол- нения слова ARRAY создает заголовок А1 и выделяет память для хранения массива. Затем выполняется слово (;CODE). Оно опреде- лено через двоеточие и поэтому первым действием снимает верх- ний элемент со стека возвратов. В этот момент в вершине стека возвратов находится указатель на шитый код слова ARRAY. Если указатель был снят во время выполнения подпрограммы UNNEST; слова (; CODE), то внутренний интерпретатор вернется для про-; должения работы на то слово, которое обратилось к слову ARRAY.; Это один из возможных способов выйти из слова ARRAY без выпо-- лнения подпрограммы UNNEST. Значение, извлеченное из стека возвратов, служит указателем на область памяти, находящуюся непосредственно за словом (; CODE) в слове ARRA i. т.е. адресом подпрограммы периода выполнения для ARRAY. Остальные слова из (; CODE), следующие за словом R>, запоминают rta (адрес пе- риода выполнения) в cfa А1, так что при обращении к А1 эта под- программа будет выполняться, начиная с rta. В период выполнения слова А1 подпрограмма NEXT перейдет с cfa A1 на rta, после чего инициализирует слово (DOES>). Оно аналогично слову NEST, i поскольку также запоминает содержимое IP на стеке возвратов, пересылает значение, на которое указывает W (являющееся не чем; иным, как rta) в IP, увеличивает его на три для обхода JSR' (DOES>), помещает pfa A1 на стек параметров и переходит к сло- ву NEXT.

Рассмотренная процедура - едва ли не самая сложная из всех, которые могут встретиться в Форте. Если столь подробное описа- ние кажется вам не совсем ясным, можно ограничиться следующи- ми сведениями, которых будет достаточно для практической рабо- ты. В период выполнения вновь определенных слов процедура DOES> заносит pfa слова, которое подлежит выполнению, на стек.

Таким образом, стековая нотация слова DOES> в период выполне- ния имеет следующий вид:

DOES> ( ==> pfa )

Слово ARRAY использует pfa A1 как базовый адрес. Оно по- мещает индекс массива на стек, предварительно умножив его на 2, чтобы выделить необходимую для хранения массива память, а за- тем прибавляет его к значению pfa. Результатом является указа- тель на значение массива с данным индексом.

В заключение приведем еще одно определяющее слово - DEFER. Оно нам уже встречалось ранее в качестве определителя векторов исполнения. Его определение выглядит так:

: DEFER CREATE [ ' ] NOOP , DOES> @ EXECUTE ;

DEFER сначала создает заголовок, а затем компилирует словом , cfa слова NOOP, которое не произродит никаких действий:

: NOOP ;

После этого управление передается в исполняющую часть слова DEFER. Процедура DOES> возвращает pfa определенного с помощью DEFER слова, в котором было скомпилировано NOOP. Оно считывает cfa слова NOOP из заданной области памяти и выполняет NOOP подпрограммой EXECUTE. EXECUTE - слово Форта, которое снимает со стека cfa некоторого слова и выполняет его. Поскольку не имеет смысла исполнять одно лишь слово NOOP, pfa определяемых с помощью DEFER слов следует изме- нить таким образом, чтобы они указывали на нужное слово. Как уже отмечалось, слово EMIT обычно указывает на подпрограмму EMIT), управляющую дисплеем. Для реализации этого нужно вы полнить следующую последовательность слов:

' (EMIT) ' EMIT >BODY !

или использовать более подходящее нестандартное слово IS: ' (EMIT) IS EMIT

Действия слова IS зависят от текущего режима Форт-системы, при компиляции и интерпретации они различны. Слово COMPILE берет cfa следующей непосредственно за ними ячейки шитого кода и компилирует cfa в словарь. Находящееся в ячейке слово не отно- сится к числу компилирующих, поскольку работает в период вы- полнения другого слова, находясь внутри него.

150

151

( cfa ==> )

: IS STATE @

IF COMPILE (IS)

ELSE ' >BODY !

THEN

; IMMEDIATE

Слово IS язляется компилирующим, так как обладает ком- пилирующими возможностями. Его определение:

: (IS) R@ @ >BODY ! 2+ >R ;

СЛОВА ДЛЯ УПРАВЛЕНИЯ ВНЕШНЕЙ ПАМЯТЬЮ

Форт - больше чем язык, это программная среда, обладающая собственными средствами для взаимодействия с внешней памятью. На логическом уровне внешняя память представляется в виде сово- купности блоков по 1024 байта (1К) в каждом, пронумерованных начиная с нуля. Внешняя память в Форте построена на основе принципа виртуализации. В памяти Форт-системы 1К блоков ре- зервируется под буферный пул. При включении нового блока под него выделяется свободный буфер. Если все буферы оказались за- нятыми, то самый "старый" блок (тот, который обновлялся позже остальных) будет переписан обратно во внешнюю память, чтобы освободить место для нового блока. Каждый буфер включает в себя флаг (признак), по значению которого можно судить, обновлялся блок или нет. Если во время нахождения блока в буфере он не из- менялся, то его не нужно переписывать обратно во внешнюю па- мять.

Все буферы могут быть очищены с уничтожением содержа- щихся в них данных с помощью слова EMPTY-BUFFERS. Для сох- ранения во внешней памяти всех блоков, подвергавшихся измене- ниям, служиг слово SAVE-BUFFERS. Перед очисткой внешней па- мяти целесообразно выполнить слово FLUSH, определяемое следу- ющим образом:

: FLUSH SAVE-BUFFERS EMPTY-BUFFERS ;

Важную роль играют слова LOAD и THRU, управляющие вхо- дным потоком данных, передаваемых из внешней памяти. Слово LOAD загружает один экран, а слово THRU - последовательность экранов:

Для работы с исходными текстами программ, находящимися во внешней памяти, требуется текстовый редактор. В Форте не предусмотрен какой-либо стандарт на средства редактирования, поэтому за их описанием следует обращаться к документации по конкретой системе. Блоки в редакторе называются экранами. В конце книги помещен глоссарий слов Форта. Там же приведена и библиография по языку Форт.

УПРАЖНЕНИЯ

1. Определите следующие слова Форта, используя стандартные слова: a) ON и OFF б) 2DUP в) -ROT

г) +! д) ?DUP ж) COUNT

2. Каково назначение слов:

а) (IS)

б) 7CREATE

(оно приведено на экране 45 исходных текстов программ в приложении А)?

LOAD (n -=> )

Переписывает блок п.

THRU (be ==> )

Переписывает блоки с b по е ,

152

сравнительно недавно. Лисп-машины в настоящее время продаются несколькими компаниями и снабжены программами типа MACSY- МА. В гл. 9 рассматривается другое направление, вынесенное в название данной книги. Разработанная в рамках этого направле- ния система, основанная на знаниях, реализована посредством слов правления списками.