Whereused

0 views
Skip to first unread message

Duke

unread,
Mar 20, 2008, 8:04:59 AM3/20/08
to Forth On TOP @ AMCP
Всё-таки не получилось у меня закончить определение этого слова
whereused. (посмотрел, кстати, внутренности see -- так там эта
волшебное слово .definition-class с большим кейсом... надеюсь, этого
не придётся реализовывать)

Пока что надо разобраться с UNNSET.

Итак, я написал слова для проверки строк на равенство, которые
работают ожидаемым образом:

: ssize=? dup 3 roll = ;

: 2c@ c@ swap c@ ;

: 21+ 1+ swap 1+ ;

: go? key BL = drop ;

: log cr .s cr ;

: check_strings
if
0 do
2dup 2c@
<> if 2drop 0 ( exit ) leave then
21+
loop
dup 0= if exit then
2drop -1 exit
else drop ( size ) 2drop ( addr1 addr2 ) 0
then
;

: s=? ssize=?
check_strings
;

: csize=?
count rot count 2swap
ssize=?
;

: c=?
csize=?
check_strings
;

c=? сравнивает две строки со счётчиком, s=? сравнивает 2 строки в
формате адрес - длина.

Так вот если описать слово MySee таким образом:

: MySee
' begin dup
>body @ >name ctype space
cell+
key BL <>
until
drop
;

То, произведя вызов MySee check_strings можно увидеть следующее:

DSee check_strings ?BRANCH [UNKNOWN] 0 (DO) [UNKNOWN] 2DUP 2C@ <> ?
BRANCH [UNKNOWN] 2DROP 0 LEAVE _THEN 21+ (LOOP) [UNKNOWN] DUP 0= ?
BRANCH [UNKNOWN] UNNEST _THEN 2DROP -1 UNNEST BRANCH S=? DROP 2DROP 0
_THEN UNNEST

Дальше идёт определение слова s=? ...

[UNKNOWN] SSIZE=? CHECK_STRINGS UNNEST ...

Так вот вопросы,
1. почему UNNEST встречается несколько раз?
2. Кто его компилит в определение слова?
3. Какой признак конца слова, всё-таки выбрать?

Michael Gasanenko

unread,
Mar 20, 2008, 8:40:07 AM3/20/08
to Forth On TOP @ AMCP


> Так вот вопросы,

0. выход изнутри цикла DO-LOOP

DO .... IF UNLOOP EXIT THEN ... LOOP

> 1. почему UNNEST встречается несколько раз?

Это run-time semantics для EXIT, которое встретилось несколько раз.

> 2. Кто его компилит в определение слова?

EXIT

> 3. Какой признак конца слова, всё-таки выбрать?

существование в словаре определения, начинающегося по этому адресу.

: q 1 . ; ok
: w 2 . ; ok
hex ' q . ' w . 43CBCC 43CBDC ok
' q 20 dump
43CBCC | 00 10 40 00 68 B0 40 00 BC C4 40 00 84 10 40 00 |..@.h癅.寄
@.?@.|
43CBDC | 00 10 40 00 70 B0 40 00 BC C4 40 00 84 10 40 00 |..@.p癅.寄
@.?@.| ok

Из этого можно заключить, что имена находятся в отдельном сегменте.

Действительно,

' q >name n>link 30 DUMP
54EC90 | 30 B6 54 00 CC CB 43 00 03 01 51 00 FF FF FF FF |0禩.趟
C...Q.????|
54ECA0 | 50 E1 40 00 28 CF 54 00 DC CB 43 00 03 01 57 00 |P酅.(蟃.芩
C...W.|
54ECB0 | FF FF FF FF 50 E1 40 00 00 00 00 00 00 00 00 00 |????P
酅.........| ok
' q >name n>link . ' w >name n>link . 54EC90 54ECA4 ok

адреса полей кода и данных и полей имени и связи отличаются очень
сильно.

Duke

unread,
Mar 20, 2008, 8:44:21 AM3/20/08
to Forth On TOP @ AMCP
Michael Gasanenko
20 мар, 15:28

Автор: Michael Gasanenko <m...@yandex.ru>

Вообще-то слово UNNEST не нужно. У нормальных людей в конце
определения компилируется EXIT.

Однако в Win32Forth'е EXIT -- компилирующее слово, оно компилирует
UNNEST.

see exit
: EXIT "0x50BB88" PARMS
IF COMPILE UNNESTP
ELSE COMPILE UNNEST
THEN ; IMMEDIATE ok

Это, в частности, означает, что Win32Forth больше не использует
UNNEST
как маркер конца определения (что вообще-то правильно).

О том, зачем нужен UNNESTP, я распространяться не хочу. Есть
некоторое
расширение языка, реализация которого размещает на стеке возвратов
дополнительные значения, и их перед выходом нужно убрать.

Другое дело, что на вершину стека возвратов надо было помещать адрес
кода, убирающего эти значения. И тогда на вершине стека возвратов
всегда был бы адрес, по которому можно передать управление, когда
нужен возврат. Но это моё IMHO, т.к. я пользуюсь расширением языка,
для которого нужно это свойство.
Reply all
Reply to author
Forward
0 new messages