Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Пт мар 29, 2024 00:18

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 4 ] 
Автор Сообщение
 Заголовок сообщения: Все, что вам надо знать о словах STATE, IMMEDIATE и POSTPONE
СообщениеДобавлено: Чт апр 23, 2009 02:21 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 5062
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 23 раз.
Поблагодарили: 63 раз.
Автор: Жак Брин
Дата публикации: 2000.04
оригинал статьи взят: http://www.figuk.plus.com/articles/issue106.pdf p.21-26
Перевел: mOleg

Все, что вам надо знать о словах STATE, IMMEDIATE и POSTPONE


Использование и контроль состояния системы (STATE)
STATE это флаг, который сообщает программе в каком режиме: компиляции или интерпретации – находится система.
STATE @ IF компиляция ELSE интерпретация THEN
Во время компиляции STATE может быть временно переключено с помощью слова [ для работы в режиме интерпретации, и восстановлен с помощью ] для возврата в режим компиляции. Эти действия могут быть произведены, к примеру, для расчета литерального значения и подобных тому вещей:
VARIABLE FOO
...
: BAR ... [ foo @ ] LITERAL ;
: BAR1 ... foo @ ;
"Foo @" интерпретируется во время компиляции внутри определения BAR , и результат исполнения компилируется словом LITERAL. В определении BAR1 , "foo @" компилируется само в код и будет вычислено во время исполнения этого слова. BAR
всегда возвращает одно и то же начальное значение, в то время как BAR1 возвращает всегда то значение, которое хранится на момент исполнения слова в переменной FOO.

Выражение: ' name возвращает исполнимый адрес (xt) слова name, который определяет его поведение. Выражение: ' name EXECUTE выполнит поведение слова name (то есть выполняет то же действие, которое исполняет Форт при простом вызове слова по имени). EXECUTE не должно знать или заботиться о текущем состоянии переменной STATE, таким образом получая один исполнимый адрес оно будет исполнять то же действие и в режиме компиляции и в режиме интерпретации.

Теперь о том, как текстовый интерпретатор обрабатывает слова немедленного исполнения (IMMEDIATE) и нормальные слова во время интерпретации. Если во время компиляции встречается нормальное слово (то есть не помеченное признаком IMMEDIATE), интерпретатор добавляет его (слова) поведение в текущее определение, то есть компилирует в текущее определение исполнимый адрес этого слова.
Слово из стандарта для компиляции исполнимого адреса (xt) называется COMPILE, .

Слова немедленного исполнения.
Когда слова немедленного исполнения встречаются во время компиляции, то они исполняются, а не добавляются к текущему определению. Такие слова создавать легко – нужно только использовать слово IMMEDIATE сразу после завершения создания определения. (IMMEDIATE изменяет флаг последнего созданного определения). Вы можете пометить признаком IMMEDIATE обычные определения (то есть определенные с помощью конструкции : name .. ; ), переменные, константы, любое определение, которое имеет собственное имя. FIND должен различать обычные слова от слов немедленного исполнения. Слово FIND возвращает xt и флаг=-1 для нормальных слов, и xt и флаг=1 для слов немедленного исполнения. Это единственное различие между обычными словами и словами немедленного исполнения. Ни EXECUTE , ни COMPILE, не знают и не заботятся о том, какой xt они получили: от нормального слова или от слова немедленного исполнения.
Вот простой текстовый интерпретатор (настолько простой, что сдается на первом неизвестном слове):
<pre>
BEGIN BL WORD FIND DUP WHILE
STATE @ IF \ компиляция?
-1 = IF COMPILE, \ обычные слова компилируем
ELSE EXECUTE \ imm слова исполняем
THEN
ELSE EXECUTE \ интерпретация
THEN
REPEAT 2DROP
</pre>
Это все, что вам необходимо для создания простого компилятора большинства Фортов.
Фактически, вам достаточно одного слова немедленного исполнения: [ для переключения из режима компиляции в режим интерпретации. Обычные слова могут переключать транслятор в обратном направлении. Но гораздо удобнее иметь большее количество слов немедленного исполнения:
! слова управления потоком исполнения: BEGIN , DO , IF , THEN , и подобные.
! литеральные слова: ['] , [CHAR] , LITERAL , S" и подобные.
! слова для завершения режима компиляции: [ , ;
! комментарии: ( , \ , [IF] и.др.

Только компилирующие слова
Однако, такие слова действуют так, что не имеет смысла использовать их во время интерпретации. В действительности только слова-комментарии исполняются без учета состояния STATE . Остальные – это только компилирующие слова, которые никогда не вызываются во время интерпретации. Возможно реализовать компилирующие слова и как нормальные, и как immediate определения (и многие системы так сделаны) но необходимо быть осторожным и никогда не вызывать их при STATE отличном от того, для которого они предназначены. Это плохая практика – и на некоторых системах невозможно переопределять компилирующие слова. К счастью, эти ограничения существенны только если вы хотите писать свои собственный компилирующий текстовый интерпретатор, а это находится за пределами данной статьи.
Использование POSTPONE
Существует стандартный метод скомпилировать компилирующие слова:
POSTPONE name
POSTPONЕ и само является компилирующим словом. Если name компилирующее слово, его компилирующее действие добавляется в текущее определение. Если слово name – слово немедленного исполнения, код эквивалентный:
' name COMPILE,
будет исполнен во время компиляции.
Если name обычное слово, код будет эквивалентен:
' name COMPILE,
Будет исполнен во время выполнения. В любом случае, код скомпилированный словом POSTPONE никогда не вызывается во время интерпретации. Единственное возможное исключение, когда name является словом немедленного исполнения:
: MY( POSTPONE ( ; IMMEDIATE
Будет работать на любой известной системе, известной мне, потому что оно эквивалентно: : MY( ['] ( EXECUTE ; IMMEDIATE
что является более удачной практикой.
Делает ли использование POSTPONE только компилирующим словом? Не обязательно.
Простой пример из стандарта:
: NOP : POSTPONE ; IMMEDIATE ;
NOP ALIGN NOP ALIGNED

Правило 1: Никогда не пытайтесь использовать xt только компилирующего слова NOP. Это определяющее слово создает ничего не делающее определение и делает это мгновенно, таким образом оно ничего не делает независимо от состояния STATE (они никогда не компилируются внутрь других слов). Тут STATE переключается во время исполнения NOP : включает его, компилирует ; выключает его. Таким образом, хотя NOP выполняет компилирующее действие слова ‘;’ он делает это лишь когда STATE установлено в режим компиляции. Аналогичный принцип используется в так называемых STATE-учитывающих (state-smart) словах.

STATE-учитывающие слова
STATE-учитывающие слова очень удобны. Они хороши, когда вы не хотите заставлять пользователя запоминать два отдельных слова: одно для режима интерпретации, другое – для компиляции. Так F83 имел слово ASCII которое может быть определено так:
: ASCII STATE @ IF POSTPONE [CHAR] ELSE CHAR THEN ; IMMEDIATE
Компилирующее действие слова ASCII защищено тестированием переменной STATE.
Во время компиляции оно эквивалентно [CHAR] , а во время интерпретации ASCII вызывает CHAR . Так же безопасно делать POSTPONE ASCII и с другими анализирующими STATE словами, так долго, как вы наблюдаете ограничения на использование получившегося кода во время интерпретации. Так что, если у вас есть отсроченное (POSTPONE) действие, оно всегда будет исполняться во время компиляции, то есть STATE при вызове всегда будет установлен. С другой стороны вот пример того, как делать не надо:
Скажем, вы хотите иметь слово CONTROL , которое возвращает управляющий код вместо ASCII кода символа. Интерпретирующая версия:
<pre>
: CONTROL POSTPONE ASCII \ OK. ASCII слово немедленного исполнения
>CONTROL ; \ конвертировать значение возвращенное словом ASCII
</pre>
Проверьте его, оно работает. CONTROL вызывает CHAR во время интерпретации, и так же компилирует внутри другого определения, которое так же работает в режиме интерпретации. В любом случае, из-за того, что ASCII state-проверяющее слово, выражение POSTPONE ASCII должно привести к проблемам в последствии. Например, мы можем создать только компилирующую версия [CONTROL] по аналогии с:
: [CHAR] CHAR POSTPONE LITERAL ; IMMEDIATE
Правило 2: Определенные с помощью POSTPONE слова обычно только компилирующие.
код:
: [CONTROL] CONTROL POSTPONE LITERAL ; IMMEDIATE
Работает не так, как вы ожидаете.
CONTROL только вызывает CHAR если STATE выключено. Когда оно исполняется внутри [CONTROL] то вызовет компилирующее действие слова [CHAR] , что несомненно нам не нужно. Это не поможет написать:
: CONTROL ['] ASCII EXECUTE ;
['] , ' или FIND не могут самостоятельно распознать STATE-анализирующие слова, поэтом и извлечь STATE-тупое интерпретирующее действие не могут.
Не существует простой методики вызова интерпретирующего действия STATE-анализирующего слова во время компиляции. Безопаснее всего использовать State-анализирующие слова, как только компилирующие и не использовать их исполнимые адреса.
Описанный ниже COMPINT - нелегкое решение. См созданные Энтоном Ерлом комбинированные слова в http://www.complang.tuwien.ac.at/forth/combined.zip Он грязный, но это хорошая иллюстрация возможностей слова POSTPONE. COMPINT это улучшенный POSTPONE который позволить избегать этих проблем:
: [[ POSTPONE [ ; \ Сбросить STATE во время исполнения, а не время компиляции
\ компилировать эквивалент кода для интерпретирующего действия
\ анализирующий STATE слов
<pre>
: COMPINT
' \ получить xt
POSTPONE STATE POSTPONE @ POSTPONE IF
POSTPONE [[ \ Код для выключения STATE если оно включено
DUP COMPILE, \ компилировать xt
POSTPONE ] \ и восстановить STATE
POSTPONE ELSE \ Если режим интерпретации, не трогаем STATE
COMPILE, POSTPONE THEN ; IMMEDIATE
</pre>
1 Так же смотрите комментарии Энтона Ерла http://www.complang.tuwien.ac.at/forth/dpanshtml/сomment-semantics.html
и предложения Митча Брэдли по «синтаксическим элементам» ftp://ftp.minerva.com/pub/x3j14/proposa ... -7-8-9.txt для получения представления о других возможных решениях.

Правило 3: STATE-учитывающие слова, определенные с помощью POSTPONE всегда компилирующие.
Используются как : CONTROL COMPINT ASCII >CONTROL ; это генерирует код:
: CONTROL STATE @ IF [[ ASCII ] ELSE ASCII THEN >CONTROL ;
Лучше старайтесь избегать анализа STATE , и отделяйте интерпретирующее действие в отдельное определение, а потом используйте его взамен STATE-учитывающего слова.
Это приводит нас к последним простейшим правилам:
Правило 4: COMPINT это безопасная версия слова POSTPONE.
Правило 5: Избегайте state-зависимых слов.


Последний раз редактировалось mOleg Пн апр 27, 2009 03:20, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Чт апр 23, 2009 02:25 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 5062
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 23 раз.
Поблагодарили: 63 раз.
к сожалению ссылки в статье битые, и я не смог найти статьи, на которые сделана ссылка

_________________
Мне бы только мой крошечный вклад внести,
За короткую жизнь сплести
Хотя бы ниточку шёлка.
fleur


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пт апр 24, 2009 02:17 
Не в сети

Зарегистрирован: Сб май 06, 2006 12:01
Сообщения: 959
Откуда: Украина, Харьков
Благодарил (а): 2 раз.
Поблагодарили: 7 раз.
mOleg писал(а):
контрольный код вместо ASCII код символа
М. управляющий? Ну и согласовать. ;)[/quote]

_________________
With best wishes, in4.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пт апр 24, 2009 02:22 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 5062
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 23 раз.
Поблагодарили: 63 раз.
in4 писал(а):
управляющий? Ну и согласовать.

спасибо, исправил

_________________
Мне бы только мой крошечный вклад внести,
За короткую жизнь сплести
Хотя бы ниточку шёлка.
fleur


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 4 ] 

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10


Вы не можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB