ОПРЕДЕЛЯЮЩИЕ И КОМПИЛИРУЮЩИЕ СЛОВА
Форт-система может работать как в режиме интерпретации,
так и в режиме компиляции. Функции интерпретатора обычно
выполняет слово INTERPRET, а компилятора - слово ]. Выбор
имени ] для компилятора может показаться несколько странным.
Однако в Форте имеется еще одно слово, [, которое переводит его
в режим интерпретации. Таким образом, пара квадратных скобок
позволяет внутри определения через двоеточие перейти к
интерпретации программы.
Состояние Форт-системы (интерпретация или компиляция)
зависит от значения системной переменной STATE. Если она
равна нулю, то Форт интерпретирует поступившую на его вход
программу. Следовательно, слово [ определяется так:
: [ STATE OFF; IMMEDIATE
144
Определение тривиально, однако завершающее его слово
IMMEDIATE является новым.
Если IMMEDIATE находится за каким-либо словом, то пос-
леднее является компилирующим словом. В приведенном выше
описании первого байта из поля имени бит 6 последнего опреде-
ленного слова устанавливается словом IMMEDIATE. При считыва-
нии очередного слова компилятор прежде всего проверяет значение
этого бита. Если в нем находится единица, то компилятор сразу
приступает к исполнению прочитанного слова, в противном случае
юмпилирует его cfa. Так как слово выполняется в период компи-
ляции, оно должно использоваться для поддержки самого процесса
компиляции. Слово [ - компилирующее, поскольку переводит
Форт-систему в режим интерпретации. Такой переход может быть
сделан только в период выполнения. Если же это слово начнет
компилироваться как часть данного определения, то оно сможет
" сработать" лишь при выполнении определяемого слова (в его
период выполнения). Но нужный момент будет уже упущен, пос-
кольку назначение слова [ - переключать режимы в период компи-
ляции. Таким образом, слово [ является компилирующим. Чтобы
продемонстрировать использование слов [ и ] в определении через
двоеточие, необходимо объяснить назначение еще одного компили-
рующего слова - LITERAL. Когда компилятору встречается в текс-
те определения какое-либо число, он обращается к слову LITE-
RAL. Оно компилирует слово периода выполнения с именем (LIT),
за которым следует само число. В период выполнения подпрограм-
ма (LIT) выбирает число из находящейся за ней области памяти, и
переставляет указатель IP на область, расположенную за той ячей-
кой, в которой до этого находилось число.
Пусть нам необходимо скомпилировать внутри определения
через двоеточие cfa слова FOO. Введем в определение выражение:
[ ' FOO ] LITERAL
Слово [ переключит Форт-систему в режим интерпретации, а
FOO возвратит cfa слова FOO. Затем ] вернет систему обратно в
режим компиляции и компилирующее слово LITERAL выполнит
компиляцию cfa как числа. Поскольку такая последовательность
операций встречается довольно часто, в Форте-83 предусмотрено
специальное слово, результат действия которого эквивалентен
упомянутой последовательности:
['] FOO
Заметим, что скобки в выражении ['] как раз и обеспечивают эту
эквивалентность.
А что случится, если слово ' встретится внутри определения
через двоеточие? Поскольку слово ' не относится к числу компили-
рующих (в отличие от ['] ), оно скомпилируется в некоторое слово
145
и будет выполняться вместе с ним. При этом ' будет искать стоя-
щее за ним слово во входном потоке, а его cfa - в словаре. Рассмо-
трим, например, слово
: FOO ';
Оно выполняет те же действия, что и слово ', поэтому должно
предшествовать имени некоторого другого слова. При выполнении
выражения FOO СЛОВО 1 вместе с ним выполняется и ', которое
считывает СЛОВО1 из входного потока (находящееся за FOO) и
возвращает его cfa.
К классу компилирующих слов относятся также и управляю-
щие конструкции. Как вы видели, слова IF, WHILE и UNTIL про-
изводят ветвление, если значение флага, снятого с вершины стека,
ложно, в противном случае (т.е. когда значение флага отлично от
нуля) они продолжают выполнять находящиеся за ними слова.
При выполнении в период компиляции эти слова компилируют
примитив перехода? BRANCH и адрес перехода, находящийся за
ним. Во время выполнения? BRANCH снимает число (или флаг) с
вершины стека. При его значении, равном нулю, производится пе-
реход. Если это не так, то указатель IP переставляется на адрес
области шитого кода, находящийся за адресом перехода. Описан-
ная схема приведена на рис. 6.7. При выполнении управляющих
слов ELSE и REPEAT вместо слова? BRANCH компилируется при-
митив BRANCH. Он реализует безусловный переход по адресу, на-
ходящемуся за ним в шитом коде.
Рис. 6.7. Схема компиляции шитого кода для слов I F, WHILE ( A ),
Слова LITERAL (В), слова; (С). Переменная I P переводится словом