Автор |
Сообщение |
|
|
Заголовок сообщения: |
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
[quote="mOleg"][quote=": AL/M ;"]Опишу своё видение -- может кому-то еще будет полезно, а может я снова ошибаюсь[/quote] вы понимаете несколько сложнее, чем оно есть. ... 3) exit после DOES> не нужен (я имею ввиду в коде он не компилируется). [/quote] В плане понимания абстрактной идеи, он понял не сложнее, а в самый раз. Ведь можно сделать и так : [b]: (DOES>) R@ CELL+ тыры_пыры_проделать_setup_jump ; : DOES> COMPILE (DOES>) COMPILE EXIT и_еще_может_кое_что_сделать ; IMMEDIATE ;[/b] Т.е. можно EXIT после (DOES>) и компилировать. Другое дело, что сразу в глаза бросается, что EXIT можно легко убрать : [b]: (DOES>) R> тыры_пыры_проделать_setup_jump ; : DOES> COMPILE (DOES>) и_еще_может_кое_что_сделать ; IMMEDIATE ;[/b] Это я предельно абстрактный пример для косвенного и прямого шитых кодов привел.
To AL/M : Да, DOES> - слово немедленного исполнения, которое должно скомпилировать код, который В ПОСЛЕДУЮЩЕМ проделает setup_jump и выполнит EXIT
|
|
|
|
Добавлено: Чт мар 10, 2011 02:50 |
|
|
|
|
|
Заголовок сообщения: |
Re: Вопрос по реализации CREATE ... DOES> (настройка адресов |
|
|
mOleg писал(а): 3) exit после DOES> не нужен (я имею ввиду в коде он не компилируется). В коде компилируется само исполнение DOES> который фактически и исполняет те самые setup jump?exit Потому что самому DOES> после компиляции адреса, куда переходить при исполнении создаваемого слова, делать больше нечего.
[quote="mOleg"]3) exit после DOES> не нужен (я имею ввиду в коде он не компилируется).[/quote]
В коде компилируется само исполнение DOES> который фактически и исполняет те самые [pre]setup jump?exit[/pre]
Потому что самому DOES> после компиляции адреса, куда переходить при исполнении создаваемого слова, делать больше нечего.
|
|
|
|
Добавлено: Вт мар 08, 2011 07:35 |
|
|
|
|
|
Заголовок сообщения: |
Re: Вопрос по реализации CREATE ... DOES> (настройка адресов |
|
|
: AL/M ; писал(а): -- setup jump сработает во время выполнения SOMETH и к этому моменту уже будет создано описание XXX и известен его адрес (через LAST или LATEST) так что дальше вычисления уже очевидны и расписывать их не имеет смысла Именно так и есть! просто, в контексте CREATE ... DOES> есть фактически четыре "состояния". 1. момент компиляции самого создающего (с помощью CREATE DOES>) слова. 2. момент исполнения создающего слова. 3. компиляция создаваемого слова (фактически совпадает с п.2.) 4. момент исполнения созданного слова. Вот во всех этих моментах и надо не запутаться.
[quote=": AL/M ;"] -- setup jump сработает во время выполнения SOMETH и к этому моменту уже будет создано описание XXX и известен его адрес (через LAST или LATEST) так что дальше вычисления уже очевидны и расписывать их не имеет смысла[/quote]
Именно так и есть!
просто, в контексте CREATE ... DOES> есть фактически четыре "состояния".
1. момент компиляции самого создающего (с помощью CREATE DOES>) слова. 2. момент исполнения создающего слова. 3. компиляция создаваемого слова (фактически совпадает с п.2.) 4. момент исполнения созданного слова. Вот во всех этих моментах и надо не запутаться.
|
|
|
|
Добавлено: Вт мар 08, 2011 07:24 |
|
|
|
|
|
Заголовок сообщения: |
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 !!! Тут сложность не в устройстве, а в том, как уследить за порядком исполнения. собственно, почитать стоит вот это
[quote=": AL/M ;"]Опишу своё видение -- может кому-то еще будет полезно, а может я снова ошибаюсь[/quote] вы понимаете несколько сложнее, чем оно есть. 1) таки скомпилированная в порождаемом с помощью CREATE - DOES> определении перезаписывается адрес CREATE. 2) место, где находятся данные, которые располагались за CREATE в порожденном слове берутся со стека возвратов в явном виде, т.е. вычислять ничего не нужно. 3) exit после DOES> не нужен (я имею ввиду в коде он не компилируется). собственно, вот если вам надо получить адрес данных, располженных в коде вслед за исполняемым словом, делается так: : (@ADDR) ( --> addr ) R> ; : some ... (@ADDR) а тут пошли данные ; при выполнении some, когда выполнение дойдет до (@ADDR) на стек возвратов будет выложен адрес, следующий за вызовом (@ADDR) и управление будет передано на (@ADDR). Т.е. первое значение, снятое со стека возвратов и будет этим самым нужным нам адресом. А возврат из слова (@ADDR) будет совершон уже не внутрь some, а внутрь слова, вызвавшего some !!! Тут сложность не в устройстве, а в том, как уследить за порядком исполнения. собственно, [url=http://www.fforum.winglion.ru/viewtopic.php?f=34&t=2308]почитать стоит вот это[/url]
|
|
|
|
Добавлено: Вт мар 08, 2011 07:20 |
|
|
|
|
|
Заголовок сообщения: |
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) так что дальше вычисления уже очевидны и расписывать их не имеет смысла
Всем спасибо! Однако в приведенных ответах мне кое-чего не доставало: принципа действия отделённого от малосущественных деталей реализации. Увы, указания об использовании HERE, LAST и тд слишком общи, а приведнные примеры кода наоборот черезчур детализированы и производят впечатления заточенности под конкретную реализацию -- все эти манипуляции с адресами и стеками только уводят в сторону от истинного понимания сути. Но, кажется, я все-таки разобрался как это должно работать. Опишу своё видение -- может кому-то еще будет полезно, а может я снова ошибаюсь
Итак, еще раз обрисую проблему
Вот как я до этого понимал компиляцию и исполнение создающих слов:
[pre]: 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[/pre]
Я предполагал, что DOES> должно настроить jump-адрес прямо во время своего исполнения (т.е. во время компиляции SOMETH). Однако на рисунке видно, что при таком раскладе это невозможно: просто непонятно куда DOES> должно записать "свой" адрес -- слово XXX еще не существует, а create модифцировать нельзя. Вот тут меня осенило: раз уж DOES> занимается компиляцией слова exit (необходимо чтобы создающая часть SOMETH не "залезла" в исполняющую), то почему бы ему не скомпилировать вдобавок и код который настроит этот jump адрес? Получится такая схема:
[pre]: SOMETH CREATE C1 ... CN DOES> D1 ... DM ; ????????????????????????????????????????????? ? ?compile ? ???? compiled by DOES> (head) V V ???????????????????????????????????????????????????????????????????????????? ?"SOMETH" ... ?create? c1 ? ... ? cN ?[color=#FF0000]setup jump[/color]?exit? d1 ? ... ? dM ?exit? ???????????????????????????????????????????????????????????????????????????? ? ? ^ ?execute "SOMETH XXX" ?put the ? ? ?address ? ? ???????????????? ? V V ???????????????????????? ???????????????????????????????? ?"XXX" ...?push PFA?jump * ? ??????????????????????????????? ^ PFA[/pre]
-- setup jump сработает во время выполнения SOMETH и к этому моменту уже будет создано описание XXX и известен его адрес (через LAST или LATEST) так что дальше вычисления уже очевидны и расписывать их не имеет смысла
|
|
|
|
Добавлено: Пн мар 07, 2011 23:18 |
|
|
|
|
|
Заголовок сообщения: |
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 @ @
Лучше привести побольше классических примеров.
В классическом 16-разрядном FIG-Forth с косвенным шитым кодом, если его определения перевести с ассемблера на Форт будет : [b]: PFA COUNT 1F AND + ALIGNED 4 + ; \ NFA -> PFA : CFA 2 - ; \ PFA -> CFA
: (;CODE) R> LATEST PFA CFA ! ; : DOES> R> LATEST PFA ! (;CODE) тут_машинный_код_(DOES>) IMMEDIATE[/b] Т.е. при выполнении DOES> у последнего определения (адрес имени которого в словаре возвращается по LATEST) поле параметров делается указывающим на то, что стоит в опрелелении c CREATE-DOES> сразу после DOES>, а поле кода делается указывающим на специальный машинный код (DOES>)
Машинный код (DOES>) делает вот что : [code](--RP) <- IP // укладывает счетчик команд шитого кода на стек возвратов IP <- (PFA) // новый счетчик команд шитого кода берет из поля параметров // , где CFA = (IP-2) , PFA = CFA+2 (--SP) <- PFA+2 // укладывает на стек данных значение HERE, где HERE = PFA+2[/code] Короче говоря, все адреса найти помогут R> HERE и LATEST ,оно-же LAST @ ,оно-же CURRENT @ @
|
|
|
|
Добавлено: Сб мар 05, 2011 21:54 |
|
|
|
|
|
Заголовок сообщения: |
Re: Вопрос по реализации CREATE ... DOES> (настройка адресов |
|
|
Код: \ разрешить ссылку на 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
8) [code]\ разрешить ссылку на 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[/code]
|
|
|
|
Добавлено: Сб мар 05, 2011 18:40 |
|
|
|
|
|
Заголовок сообщения: |
Re: Вопрос по реализации CREATE ... DOES> (настройка адресов |
|
|
В Ф-83 CREATE засовывал NFA нового определения в переменную LAST. А IMMEDIATE, RECURSE и DOES> брали его оттуда.
В Ф-83 CREATE засовывал NFA нового определения в переменную LAST. А IMMEDIATE, RECURSE и DOES> брали его оттуда.
|
|
|
|
Добавлено: Сб мар 05, 2011 12:08 |
|
|
|
|
|
Заголовок сообщения: |
Re: Вопрос по реализации CREATE ... DOES> (настройка адресов |
|
|
Так ведь HERE для того и существует, чтобы знать этот адрес!
А писать его надо в последнее компилируемое слово. То, что по CREATE создается при исполнении создающего слова.
Так ведь HERE для того и существует, чтобы знать этот адрес!
А писать его надо в последнее компилируемое слово. То, что по CREATE создается при исполнении создающего слова.
|
|
|
|
Добавлено: Сб мар 05, 2011 08:56 |
|
|
|
|
|
Заголовок сообщения: |
Вопрос по реализации 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 может быть скомпилировано произвольное кол-во др. слов
Непонятно как можно реализовать слово DOES> Вот схематично изобразил как я понимаю работу CREATE -- DOES>:
[pre]: SOMETH CREATE ... DOES> ... ; ? ? ? ?[color=#FF0000]sets up the jump-addr[/color] ?> HEAD,??? ? [color=#FF0000]during compile-time[/color] ? ? ? ?> PFA, ???????????????? ? ? ? ? ?> JUMP,??? <??? ? ?? ? ????????????????????????????? [color=#4000FF](at run-time >>)[/color] ? ? ? ? ? ? V V V ??????????????????????????????????????????????? SOMETH XXX --> ? XXX ... ? push PFA code ? jump -> DOES ? ??????????????????????????????????????????????? ^ ^ CFA PFA[/pre] Вопрос заключен в фразе выделенной красным цветом -- а именно: откуда DOES> узнает по какому адресу он должен записать "свой" адрес? Ведь между CREATE и DOES> в определении SOMETH может быть скомпилировано произвольное кол-во др. слов
|
|
|
|
Добавлено: Сб мар 05, 2011 05:37 |
|
|
|
|