ЧТО ТАКОЕ КОМПИЛИРУЮЩЕЕ СЛОВО?
Если обычные слова Форта появляются внутри определения через двоеточие, то они компилируются в словарь. Эти слова во время компиляции ведут себя пассивно. Компилирующие слова также появляются внутри определения через двоеточие, но в противоположность первым активно влияют на процесс компиляции. Такие слова, как IF, THEN, BEGIN, REPEAT и ." являются компилирующими.
Создатели Форта проявили последовательность и в данном случае. Коль уж существует тенденция не включать в язык все возможные определяющие слова, то компилирующих операторов в самом языке немного. Возможность управлять компиляцией путем образования собственных компилирующих слов предоставляет вам такую свободу, какую не может обеспечить ни один из известных языков программирования. Это средство позволяет локализовать информацию внутри соответствующих определений (не рассредоточивая ее по всей программе), что упрощает написание программы, облегчает ее чтение, восприятие и сопровождение. Вероятно, ваша программа будет выглядеть более привлекательной, если в язык включить оператор выбора вариантов, который сравнивает текстовые фрагменты. А, может быть, вы хотели бы добавить к вашим операторам управления средства жесткого аварийного контроля? Не исключено, что вам захочется иметь оператор цикла DO, использующий 32-разрядный индекс. Все это в ваших силах.
По мере дальнейшего изложения материала мы будем приводить примеры применения компилирующих слов. Некоторые из них уже есть в вашей системе. Даже если у вас нет намерения создавать свои компилирующие слова, поняв механизм их создания, вы разберетесь и в том, как образуются собственные компилирующие слова Форта. Форт-система написана на Форте, так что все, что может делать она, можете делать и вы!
Прежде чем перейти к примерам, рассмотрим механизм создания компилирующих слов. Как уже отмечалось, компилирующие слова, когда до них доходит очередь компилятора внутри определения через двоеточие, не компилируются, а выполняются. Это ключ к механизму создания компилирующих слов.
Чтобы понять, как он действует, изучим компилятор двоеточия.
Компилятор двоеточия функционирует аналогично текстовому интерпретатору. Он выбирает из входного потока слова и пытается отыскать их в словаре. Однако, вместо того чтобы (как ИНТЕРПРЕТАТОР) исполнять эти слова немедленно, он, как правило, компилирует их адреса в словарь. Но компилятор распознает компилирующие слова и только их исполняет сразу, подобно текстовому интерпретатору.
Каким образом компилятор двоеточия отличает компилирующие слова? По биту немедленного исполнения данного определения (гл. 9 «Структура словарной статьи»): если бит сброшен, то компилируется адрес слова, если установлен, что слово немедленно исполняется. Такие слова называются словами немедленного исполнения (immediate).
Слово IMMEDIATE делает слово немедленно исполняемым. Его формат: : имя определение ; IMMEDIATE
т. е. это слово выполняется сразу после компиляции определения. Допустим, у нас есть определение: : ТЕСТ ; IMMEDIATE
Это слово немедленного исполнения которое ничего не выполняет. Если мы обратимся к нему из определения другого слова, например: : 2CRS CR ТЕСТ CR ;
то будет скомпилирован следующий фрагмент словаря:
Как видите, определение скомпилировано без слова ТЕСТ. На самом деле оно выполнено во время компиляции слова 2CRS. Поскольку слово ТЕСТ ничего не выполняет, оно бесполезно. Приведем другой пример. Предположим, что у нас есть слово с именем ТЮЛЬПАН и определение: : ТЕСТ COMPILE ТЮЛЬПАН ; IMMEDIATE
Теперь переопределим слово 2CRS точно так же, как и ранее: : 2CRS CR ТЕСТ CR ;
и получим следующий результат:
На сей раз слово ТЕСТ во время компиляции определения 2CRS скомпилировало адрес слова ТЮЛЬПАН. На самом деле мы нашим определением как бы сказали: : 2CRS CR ТЮЛЬПАН CR ;
и что компилировать, а что нет, определяет ТЕСТ, потому что это слово немедленного исполнения. Обратите внимание на слово COMPILE (КОМПИЛЯЦИЯ). Мы ввели его как бы между прочим, поскольку его функции проще понять в контексте.
: ТЕСТ COMPILE ТЮЛЬПАН ; IMMEDIATE
COMPILE вычисляет адрес следующего слова определения и запоминает его в виде числа:
: 2CRS CR ТЕСТ CR ;
Когда исполняется слово немедленного выполнения, в котором появилось COMPILE, оно компилирует запомненный адрес в создаваемое определение. Этот процесс можно трактовать как отсроченную компиляцию. Приведем теперь очень полезный пример. Допустим, вы написали отладочное средство с именем ОТЛАДКА, которое хотите использовать в любом месте своей программы. Так как желательно иметь возможность при необходимости включать и отключать это средство, воспользуемся словом ТЕСТ, определенным следующим образом: : ТЕСТ ПРОВЕРКА? IF ОТЛАДКА THEN ;
Слово ТЕСТ при выполнении проверяет флаг и определяет, обращаться к слову ОТЛАДКА или нет. Казалось бы, все хорошо, однако много времени уходит на остановку для проверки флага на каждом шаге цикла. Если вы не работаете в отладочном режиме, вам вряд ли нужно всякий раз проверять режим. Проблема решается путем переопределения слова ТЕСТ: : ТЕСТ ПРОВЕРКА? IF COMPILE ОТЛАДКА THEN ; IMMEDIATE
В такой ситуации для включения отладочного средства придется перекомпилировать программу, но это займет немного времени. В отладочном режиме слово ТЕСТ скомпилирует ОТЛАДКА в соответствующие места программы. В противном случае оно вообще ничего компилировать не будет. Проверка IF будет осуществляться в период компиляции. Рассмотрим более сложное, но уже знакомое вам компилирующее слово .", которое не выводит строку на экран, как вы, возможно, склонны думать. На самом деле это слово компилирует строку в словарь с тем, чтобы выдать ее позднее. А какое слово нашу строку затем выводит? Примитив, названный в одних системах (."), в других - dot". Проследим шаг за шагом выполнение данного слова точно так же, как мы это делали применительно к определяющим словам. Приведенное ниже определение слова .", имеется в большинстве Форт-систем, но нам интересен принцип, а не детали.
: dot" R> COUNT 2DUP + >R TYPE ; : ." COMPILE dot" ASCII " STRING ; IMMEDIATE
Определение dot" и ."
: ВСТРЕЧА ." Эй, ты " ;
Исполнение .", которое является словом немедленного выполнения (и поэтому исполняется во время компиляции слова ВСТРЕЧА). Оно в свою очередь осуществляет компиляцию:
- адреса слова dot" в определение слова ВСТРЕЧА:
строки, ограниченной двойной кавычкой как строки со счетчиком:
ВСТРЕЧА
Выполнение слова ВСТРЕЧА, которое вызывает слово dot", а оно уже выводит строку на экран1.
Следующие два слова применяются при создании новых компилирующих слов:
IMMEDIATE
( - )
Последнее определенное слово становится немедленно исполняемым, то есть во время компиляции оно будет не компилироваться, а выполняться.
C0MPILE xxx
( - )
Применяется при определении компилируйте-то слова. Когда это компилируйте* слово будет в свою очередь использоваться в исходном определении, адрес поля кода ххх будет скомпилирован в словарную статью, так что когда вновь созданное определение выполняется, выполняется и ххх.
Содержание раздела