DOES⟩

Материал из ПМК вики
Перейти к навигации Перейти к поиску

DOES> (исполнить, исполняет) — фортовское слово Каллисто.

DOES>          ( −− a )                             Начало обработчика в порождающем слове.
Пример работы слова DOES>

Начало обработчика (исполняющей части) в порождающем слове (англ. defining word).

Обычно слово DOES> используется внутри определения через двоеточие после слова <BUILDS, с которого начинается определяющая часть порождающего слова. Слово DOES> завершает определяющую часть и начинает определение обработчика — той части слова, которая общая у всех слов, созданных порождающим словом.

Ввод слова DOES>[править]

В режиме ЛАТ последовательно нажмите клавиши  K   5   ИП   1     P   F   ИП 

Эти нажатия оставляют клавиатуру в режиме NUM.

DOES> в стандарте ANS Forth[править]

 6.1.1250   DOES>                              "does"                       CORE
        Интерпретация: Семантика интерпретации для этого слова не определена.

        Компиляция: ( C: colon-sys1 -- colon-sys2 )
            Добавляет семантику времени-выполнения ниже к текущему определению. 
            В любом случае текущее определение представленное находимым в 
            словаре при компиляции DOES> - определенное реализацией. Потребляет 
            colon-sys1 и производит colon-sys2. Добавляет семантику 
            инициирования, данную ниже к текущему определению.

        Время-выполнения: ( -- ) ( R: nest-sys1 -- )
            Заменяет семантику выполнения самого последнего определения, 
            упоминаемого как name, семантикой выполнения имени данной ниже. 
            Возвращает управление на вызывающее определение, определенное nest-
            sys1. Неопределенная ситуация существует если name не было 
            определено CREATE, или определенным пользователем словом которое 
            вызывает CREATE.

        Инициирование: ( i*x -- i*x a-addr )  ( R:  -- nest-sys2 )
            Сохраняет зависящую-от-реализации информацию nest-sys2 о вызывающем 
            определении. Размещает адрес поля данных name на стеке. Состояние 
            стека i*x представляет параметры name.

        name Выполнение: ( i*x -- j*x )
            Выполняет часть определения, которая начинается с семантики 
            инициирования добавленной изменившим name DOES>. Состояния стека 
            i*x и j*x представляют параметры, и результаты name, 
            соответственно.

        См.: 6.1.1000 CREATE.

 A.6.1.1250   DOES>
 Типичное использование:
        : X ... DOES> ... ;

 Относительно DOES>, Стандартная Программа не может делать какие-либо 
 предположения относительно способности  находить имя определения содержащего 
 DOES> или любое предыдущее определение чье имя может быть скрыто этим. DOES> 
 эффективно заканчивает одно определение и начинает другое насколько 
 заинтересованы переменные local и структуры потока управления. Поведение 
 компиляции проясняет, что пользователь не имеет право помещать DOES> внутри 
 любых структур потока управления.

Совместимость[править]

Слово DOES> в Каллисто работает только в паре со словом <BUILDS. При переносе DOES> с Форта найдите слово CREATE, ему соответствующее, и замените его на <BUILDS. В большинстве случаев этого достаточно.

История[править]

Впервые слово DOES> появилось под именем ;: в 1971-73 годах, когда Чак Мур перенёс Форт на DEC PDP-11 в National Radio Astronomy Observatory (англ., Шарлотсвилл) и с тех пор разные варианты шитого кода применяется в подавляющем числе различных реализаций Форта.

Как ;CODE , оно определяло класс слов, указывая как интерпретировать описание, когда на слово ссылались. Чак Мур писал, что его было сложно изобрести, но оно оказалось особенно полезным для определения кодов операций.

В 1976 году на microFORTH появилась первая версия целевого компилятора. Примерно в это время была реализована улучшенная версия CREATE … DOES> , которая экономила 2 байта на каждом слове DOES> Эта разработка заняла 3 года.

DOES> в предыдущем стандарте Forth-83 (англ.)[править]

      DOES>        -- addr                       C,I,83          "does"
                   --   (compiling)
           Defines the execution-time action of a word created by a
           high-level defining word.  Used in the form:
                   : <namex> ... <create> ... DOES> ... ;
           and then
                   <namex> <name>
           where <create> is CREATE or any user defined word which
           executes CREATE .

           Marks the termination of the defining part of the defining
           word <namex> and then begins the definition of the
           execution-time action for words that will later be defined
           by <namex>.  When <name> is later executed, the address of
           <name>'s parameter field is placed on the stack and then the
           sequence of words between DOES> and ; are executed.

DOES> в стандарте Forth-79 (англ.)[править]

DOES>                                        I,C,168         "does"
    Define  the run-time action of a word created by a  high-level
    defining word.  Used in the form:
         :  <name> ... CREATE ... DOES> ... ;
         and then   <namex>  <name>
    Marks  the  termination of the defining part of  the  defining
    word <name> and begins the defining of the run-time action for
    words  that will later be defined by <name>.   On execution of
    <namex>  the  sequence  of  words  between  DOES>  and  ;  are
    executed, with the address of <namex>'s parameter field on the
    stack.

DOES> в fig-FORTH Release 1 glossary, май 1979 (англ.)[править]

DOES>                                           L0
       A word which defines the run-time action within a high-level
       defining word. DOES> alters the code field and first parameter of
       the new word to execute the sequence of compiled word addresses
       following DOES>. Used in combination with <BUILDS. When the DOES>
       part executes it begins with the address of the first parameter of
       the new word on the stack. This allows interpretation using this
       area or its contents. Typical uses include the Forth assembler,
       multidimensional arrays, and compiler generation.

Реализация[править]

Основная часть слова DOES> является высокоуровневой. Для ускорения исполнения порождаемых слов исполняющая часть слова DOES> написана на языке МК.

Также в поле данных слова DOES> присутствует вторая исполняющая часть — для порождающего слова VOCABULARY, высокоуровневая исполняющая часть которого находится в памяти программ.

2596 ;#DOES
2597 ; DOES>            ( −− a )                             Начало обработчика в порождающем слове.
2598 ; Все слова, определённые через DOES> находятся в памяти данных
2599 ; DOES> переводится с Форта на русский как "исполняется".
2600 ; Слово присутствует во всех фортах, но начиная с Форта−83 его реализация сильно отличается из−за отсутствия в этих языках слова <BUILDS
2601 LDOES:          .DB     5
2602                 .TEXT   "DOES>"                 ; ( −− pfa)
2603                 .DW     LDEFER
2604 DOESD:          .DW CALL, FROMR, LITP
2605                 .DB 39,16                       ; 10000
2606                 .DW SUB, LATES,N2PFA,STORE, PSCOD
2607                 ;∗∗ CALL по адресу из @PFA с засылкой в стек PFA+2
2608 SDOED:                                          ; Обработчик в памяти данных, обычный случай
2609                 KGSBC                           ; RPUSH RI; RX := W
2610                 2 + M7 M5                       ; W указывало на SDOED, а теперь указывает на xt (CFA) обработчика
2611                 10002 + KM3                     ; PUSH W+2      ; PFA+2 с трансляцией адресов
2612                 KRM7 RME ∗ KRM5 +               ; CFA всегда считывается из памяти данных
2613                 1 −                             ; RX := PFA−1, передаём в указатель шитого кода R6=RI
2614                 PGOTO SETRIDAT                  ; Перейти на NEXT для области данных
2615 
2616 DOESP:          .DW     CALL                    ; Сейчас используется только для слова VOCABULARY
2617                 .DW FROMR,LATES,N2PFA,STORE,PSCOD
2618 SDOEP:                                          ; Обработчик в памяти программ, единичный случай
2619                 KGSBC                           ; RPUSH RI; RX := W
2620                 2 + M7 M5                       ; W указывало на SDOE, а теперь на xt (CFA) обработчика
2621                 10002 + KM3                     ; PUSH W+2      ; PFA+2 с трансляцией адресов
2622                 KRM7 RME ∗ KRM5 +               ; .NUM DOVOC
2623                 PGOTO SETRIPRG                  ; Перейти на NEXT для области программ

Реализация из SP-Forth 4.20:

0  VALUE  DOES-CODE
…
' R>  VALUE  DOES-CODE
…
: (DOES1) \ та часть, которая работает одновременно с CREATE (обычно)
  R> DOES>A @ CFL + -
  DOES>A @ 1+ !
;

CODE (DOES2)
   LEA  EBP, -4 [EBP]
   MOV  [EBP], EAX
   MOV  EAX, 4 [ESP]
   MOV  EBX, [ESP]
   LEA  ESP, 8 [ESP]
   JMP  EBX
END-CODE

' (DOES2) ' DOES-CODE TC-VECT!

: DOES>  \ 94
\ Интерпретация: семантика неопределена.
\ Компиляция: ( C: clon-sys1 -- colon-sys2 )
\ Добавить семантику времени выполнения, данную ниже, к текущему
\ определению. Будет или нет текущее определение сделано видимо
\ для поиска в словаре при компиляции DOES>, зависит от реализации.
\ Поглощает colon-sys1 и производит colon-sys2. Добавляет семантику
\ инициализации, данную ниже, к текущему определению.
\ Время выполнения: ( -- ) ( R: nest-sys1 -- )
\ Заменить семантику выполнения последнего определения name, на семантику
\ выполнения name, данную ниже. Возвратить управление в вызывающее опреде-
\ ление, заданное nest-sys1. Неопределенная ситуация возникает, если name
\ не было определено через CREATE или определенное пользователем слово,
\ вызывающее CREATE.
\ Инициализация: ( i*x -- i*x a-addr ) ( R: -- nest-sys2 )
\ Сохранить зависящую от реализации информацию nest-sys2 о вызывающем
\ определении. Положить адрес поля данных name на стек. Элементы стека
\ i*x представляют аргументы name.
\ name Выполнение: ( i*x -- j*x )
\ Выполнить часть определения, которая начинается с семантики инициализации,
\ добавленной DOES>, которое модифицировало name. Элементы стека i*x и j*x
\ представляют аргументы и результаты слова name, соответственно.
  ['] (DOES1) COMPILE,
  ['] (DOES2) COMPILE,
; IMMEDIATE

Советская реализация[править]

Описание и определение слова DOES> в ядре ФОРТ-ЕС:

DOES>  HK -> НАЧАЛО "ИСПОЛНЕНИЯ" В ОПРЕДЕЛЯЮЩЕМ СЛОВЕ           34
DOES#  M  ПОДПРОГРАММА - НАЧАЛО РАСШИРЕНИЯ "DOES>"              3

                      Экран номер 3
(  09.09.86 ДОПОЛНИТЕЛЬНЫЕ ВХОДЫ  В АДРЕСНЫЙ ИНТЕРПРЕТАТОР)

M: DOES# RI  RPUSH,  RI 4 (,  15  LA,  RI RFORTH  SR,
A: CREATE#   RW1 14 LR,            (  ПОМЕСТИТЬ  РFA СТАТЬИ)
M: PUSHRW1   RSTACK  RTWO  SR,    ( ПОМЕСТИТЬ ЗНАЧЕНИЕ ИЗ RW1)
M: PUTRW1    RW1 PUT,   RNEXT BR, (   ЗАМЕНИТЬ   ВЕРХНЕЕ)

                     Экран номер 36
( 09.09.86  CREATE   DOES> )

: DOES>  ( ->)  COMPILE (;CODE) 2LIT
  [ DOES#  B, ] , , ; IMMEDIATE

Определение слова DOES> в FORTH ИТЭФ:

            HEAD     205Q,'DOES',276Q,DOES,$COL           ; DOES>
            DW  FROMR,LATES,PFA,STORE,PSCOD
   $DOE     LABEL   FAR
            SUB  BP,  2
            ADD  BX, 2
            MOV  [BP],   SI
            MOV  SI, [BX]
            ADD  BX, 2
            PUSH BX
            NEXT

Ссылки[править]


  Stub-icon-48px.png Это заготовка статьи. Вы можете помочь проекту, дополнив её.