Forth
http://fforum.winglion.ru/

Вопрос по реализации CREATE ... DOES> (настройка адресов)
http://fforum.winglion.ru/viewtopic.php?f=24&t=2713
Страница 1 из 1

Автор:  : AL/M ; [ Сб мар 05, 2011 05:37 ]
Заголовок сообщения:  Вопрос по реализации CREATE ... DOES> (настройка адресов)

Непонятно как можно реализовать слово DOES>
Вот схематично изобразил как я понимаю работу CREATE -- DOES>:

: SOMETH CREATE   ...   DOES>   ...   ;
? ?
? ?sets up the jump-addr
?> HEAD,??? ? during compile-time
? ? ?
?> PFA, ????????????????
? ? ? ?
?> JUMP,??? <??? ?
?? ?
?????????????????????????????
(at run-time >>) ? ? ?
? ? ?
V V V
???????????????????????????????????????????????
SOMETH XXX --> ? XXX ... ? push PFA code ? jump -> DOES ?
???????????????????????????????????????????????
^ ^
CFA PFA

Вопрос заключен в фразе выделенной красным цветом -- а именно: откуда DOES> узнает по какому адресу он должен записать "свой" адрес? Ведь между CREATE и DOES> в определении SOMETH может быть скомпилировано произвольное кол-во др. слов

Автор:  WingLion [ Сб мар 05, 2011 08:56 ]
Заголовок сообщения:  Re: Вопрос по реализации CREATE ... DOES> (настройка адресов

Так ведь HERE для того и существует, чтобы знать этот адрес!

А писать его надо в последнее компилируемое слово. То, что по CREATE создается при исполнении создающего слова.

Автор:  dynamic-wind [ Сб мар 05, 2011 12:08 ]
Заголовок сообщения:  Re: Вопрос по реализации CREATE ... DOES> (настройка адресов

В Ф-83 CREATE засовывал NFA нового определения в переменную LAST.
А IMMEDIATE, RECURSE и DOES> брали его оттуда.

Автор:  mOleg [ Сб мар 05, 2011 18:40 ]
Заголовок сообщения:  Re: Вопрос по реализации CREATE ... DOES> (настройка адресов

8)
Код:
\ разрешить ссылку на DOES> часть
: (JOIN) ( r: addr --> ) AR> LAST A@ LINK>C TOKEN! ; unfeasible

\ вернуть адрес поля данных, перейти на код обработчика
: (DOES) ( --> addr ) DR> EXECUTE ; unfeasible

\ во время компиляции связывает текст за DOES> с текущим определением   ?
\ используется в паре с CREATE : name CREATE data, DOES> ( --> 'data ) ;
: DOES> ( --> )
        ?COMP
        COMPILE IT-DOES   \ метит новое созданное слово признаком &das
        COMPILE (JOIN)
        COMPILE (DOES)
        ; IMMEDIATE

Автор:  Ethereal [ Сб мар 05, 2011 21:54 ]
Заголовок сообщения:  Re: Вопрос по реализации CREATE ... DOES> (настройка адресов

Лучше привести побольше классических примеров.

В классическом 16-разрядном FIG-Forth с косвенным шитым кодом, если
его определения перевести с ассемблера на Форт будет :
: PFA COUNT 1F AND + ALIGNED 4 + ; \ NFA -> PFA
: CFA 2 - ; \ PFA -> CFA

: (;CODE) R> LATEST PFA CFA ! ;
: DOES> R> LATEST PFA ! (;CODE) тут_машинный_код_(DOES>) IMMEDIATE

Т.е. при выполнении DOES> у последнего определения (адрес имени
которого в словаре возвращается по LATEST) поле параметров
делается указывающим на то, что стоит в опрелелении c CREATE-DOES>
сразу после DOES>, а поле кода делается указывающим на специальный
машинный код (DOES>)

Машинный код (DOES>) делает вот что :
Код:
(--RP) <- IP    // укладывает счетчик команд шитого кода на стек возвратов
IP <- (PFA)     // новый счетчик команд шитого кода берет из поля параметров
                // , где CFA = (IP-2) , PFA = CFA+2
(--SP) <- PFA+2 // укладывает на стек данных значение HERE, где HERE = PFA+2

Короче говоря, все адреса найти помогут R> HERE и LATEST ,оно-же LAST @ ,оно-же CURRENT @ @

Автор:  : AL/M ; [ Пн мар 07, 2011 23:18 ]
Заголовок сообщения:  Re: Вопрос по реализации CREATE ... DOES> (настройка адресов

Всем спасибо! Однако в приведенных ответах мне кое-чего не доставало: принципа действия отделённого от малосущественных деталей реализации. Увы, указания об использовании HERE, LAST и тд слишком общи, а приведнные примеры кода наоборот черезчур детализированы и производят впечатления заточенности под конкретную реализацию -- все эти манипуляции с адресами и стеками только уводят в сторону от истинного понимания сути.
Но, кажется, я все-таки разобрался как это должно работать. Опишу своё видение -- может кому-то еще будет полезно, а может я снова ошибаюсь

Итак, еще раз обрисую проблему

Вот как я до этого понимал компиляцию и исполнение создающих слов:

: SOMETH  CREATE C1 ... CN  DOES> D1 ... DM ;
?????????????????????????????????????????????
?
?compile
? ???? compiled by DOES>
(head) V V
????????????????????????????????????????????????????????????????
?"SOMETH" ... ?create? c1 ? ... ? cN ?exit? d1 ? ... ? dM ?exit?
????????????????????????????????????????????????????????????????
? ^
?execute "SOMETH XXX" ?
? ?
(head) V ?????????????
????????????????????????????????
?"XXX" ...?push PFA?jump * ?
???????????????????????????????
^
PFA


Я предполагал, что DOES> должно настроить jump-адрес прямо во время своего исполнения (т.е. во время компиляции SOMETH). Однако на рисунке видно, что при таком раскладе это невозможно: просто непонятно куда DOES> должно записать "свой" адрес -- слово XXX еще не существует, а create модифцировать нельзя.
Вот тут меня осенило: раз уж DOES> занимается компиляцией слова exit (необходимо чтобы создающая часть SOMETH не "залезла" в исполняющую), то почему бы ему не скомпилировать вдобавок и код который настроит этот jump адрес?
Получится такая схема:

: SOMETH  CREATE C1 ... CN  DOES> D1 ... DM ;
?????????????????????????????????????????????
?
?compile
? ???? compiled by DOES>
(head) V V
????????????????????????????????????????????????????????????????????????????
?"SOMETH" ... ?create? c1 ? ... ? cN ?setup jump?exit? d1 ? ... ? dM ?exit?
????????????????????????????????????????????????????????????????????????????
? ? ^
?execute "SOMETH XXX" ?put the ?
? ?address ?
? ???????????????? ?
V V ????????????????????????
????????????????????????????????
?"XXX" ...?push PFA?jump * ?
???????????????????????????????
^
PFA


-- setup jump сработает во время выполнения SOMETH и к этому моменту уже будет создано описание XXX и известен его адрес (через LAST или LATEST) так что дальше вычисления уже очевидны и расписывать их не имеет смысла

Автор:  mOleg [ Вт мар 08, 2011 07:20 ]
Заголовок сообщения:  Re: Вопрос по реализации CREATE ... DOES> (настройка адресов

: AL/M ; писал(а):
Опишу своё видение -- может кому-то еще будет полезно, а может я снова ошибаюсь

вы понимаете несколько сложнее, чем оно есть.
1) таки скомпилированная в порождаемом с помощью CREATE - DOES> определении перезаписывается адрес CREATE.
2) место, где находятся данные, которые располагались за CREATE в порожденном слове берутся со стека возвратов в явном виде, т.е. вычислять ничего не нужно.
3) exit после DOES> не нужен (я имею ввиду в коде он не компилируется).
собственно, вот если вам надо получить адрес данных, располженных в коде вслед за исполняемым словом, делается так:
: (@ADDR) ( --> addr ) R> ;
: some ... (@ADDR) а тут пошли данные ;
при выполнении some, когда выполнение дойдет до (@ADDR) на стек возвратов будет выложен адрес, следующий за вызовом (@ADDR) и управление будет передано на (@ADDR). Т.е. первое значение, снятое со стека возвратов и будет этим самым нужным нам адресом. А возврат из слова (@ADDR) будет совершон уже не внутрь some, а внутрь слова, вызвавшего some !!!
Тут сложность не в устройстве, а в том, как уследить за порядком исполнения.
собственно, почитать стоит вот это

Автор:  WingLion [ Вт мар 08, 2011 07:24 ]
Заголовок сообщения:  Re: Вопрос по реализации CREATE ... DOES> (настройка адресов

: AL/M ; писал(а):
-- setup jump сработает во время выполнения SOMETH и к этому моменту уже будет создано описание XXX и известен его адрес (через LAST или LATEST) так что дальше вычисления уже очевидны и расписывать их не имеет смысла


Именно так и есть!

просто, в контексте CREATE ... DOES> есть фактически четыре "состояния".

1. момент компиляции самого создающего (с помощью CREATE DOES>) слова.
2. момент исполнения создающего слова.
3. компиляция создаваемого слова (фактически совпадает с п.2.)
4. момент исполнения созданного слова.
Вот во всех этих моментах и надо не запутаться.

Автор:  WingLion [ Вт мар 08, 2011 07:35 ]
Заголовок сообщения:  Re: Вопрос по реализации CREATE ... DOES> (настройка адресов

mOleg писал(а):
3) exit после DOES> не нужен (я имею ввиду в коде он не компилируется).


В коде компилируется само исполнение DOES> который фактически и исполняет те самые
setup jump?exit


Потому что самому DOES> после компиляции адреса, куда переходить при исполнении создаваемого слова, делать больше нечего.

Автор:  Ethereal [ Чт мар 10, 2011 02:50 ]
Заголовок сообщения:  Re: Вопрос по реализации CREATE ... DOES> (настройка адресов

mOleg писал(а):
: AL/M ; писал(а):
Опишу своё видение -- может кому-то еще будет полезно, а может я снова ошибаюсь

вы понимаете несколько сложнее, чем оно есть.
...
3) exit после DOES> не нужен (я имею ввиду в коде он не компилируется).

В плане понимания абстрактной идеи, он понял не сложнее, а в самый раз.
Ведь можно сделать и так :
: (DOES>) R@ CELL+ тыры_пыры_проделать_setup_jump ;
: DOES> COMPILE (DOES>) COMPILE EXIT и_еще_может_кое_что_сделать ; IMMEDIATE ;

Т.е. можно EXIT после (DOES>) и компилировать.
Другое дело, что сразу в глаза бросается, что EXIT можно легко убрать :
: (DOES>) R> тыры_пыры_проделать_setup_jump ;
: DOES> COMPILE (DOES>) и_еще_может_кое_что_сделать ; IMMEDIATE ;

Это я предельно абстрактный пример для косвенного и прямого шитых кодов привел.

To AL/M :
Да, DOES> - слово немедленного исполнения, которое должно скомпилировать код,
который В ПОСЛЕДУЮЩЕМ проделает setup_jump и выполнит EXIT

Страница 1 из 1 Часовой пояс: UTC + 3 часа [ Летнее время ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/