DEFER
Перейти к навигации
Перейти к поиску
DEFER — фортовское порождающее слово Каллисто. Определение переменной действия.
DEFER ( −− ) Определить следующее слово, как действие с начальным значением НОП (нет операции).
При исполнении переменной действия будет исполнено то слово, токен которого ей присвоен с помощью слова TO. DEFER позволяет определять слова, значения которых меняются во время работы приложения.
Слова, исполняемые переменной действия, могут вызывать авост.
Пример[править]
В следующем примере скомпилированное слово TELLANIMAL обращается то к ANIMAL1, то к ANIMAL2 — в зависимости от содержимого переменной действия ANIMAL:
DEFER ANIMAL : TELLANIMAL ANIMAL ; : ANIMAL1 ." кот" ; : ANIMAL2 ." пёс" ; ' ANIMAL1 TO ANIMAL TELLANIMAL ' ANIMAL2 TO ANIMAL TELLANIMAL
Реализация[править]
2566 ;#DEFER 2567 ; DEFER ( −− ) Определить следующее слово, как действие с начальным значением НОП (нет операции). 2568 ; Для хранения xt (в виде адреса в единой адресации) используется поле данных DEFER 2569 ; Соглашение по векторному поля кода такое же, как у VALUE −− ведь мы используем одно и то же слово TO 2570 LDEFER: .DB 5 2571 .TEXT "DEFER" ; ( "<пр>имя" −− ) 2572 .DW LVALUE 2573 DEFER: .DW CALL, CREAT,LITP,SNOP,COMMA ; DEFER инициализируется токеном НОП 2574 .DW LITP,TODEFER,COMMA, PSCOD ; TODEFER −− второй элемент векторного поля кода 2575 ; Исполняющая часть DEFER (обычное вхождение слова) 2576 RM7 M5 KRM5 ; ( −− ) выполнить сохранённый xt 2577 KRM5 RME ∗ KRM5 + ; RX := сохранённый xt 2578 PGOTO DOEXECRX ; W := RX, JMP MEMW[W] 2579 TODEFER: 2580 RM7 3 − M5 ; R5 готов к косвенной адресации с предв. автоинкрементом 2581 RM3 MA 1 + M3 ; RA содержит номер регистра, в котором хранится новый xt 2582 KRMA ; Получить новый CFA 2583 ENT RME / FANS <−> KINT KM5 ; Сохранить старший байт нового CFA 2584 ∗ − KM5 KGOTO9 ; Сохранить младший байт нового CFA, NEXT
Реализации из SP-Forth 4.20:
0 VALUE VECT-CODE … CODE _VECT-CODE POP EBX JMP [EBX] END-CODE ' _VECT-CODE TO VECT-CODE … ' _VECT-CODE >VIRT VALUE VECT-CODE … : VECT ( -> ) [T] HEADER [I] VECT-CODE COMPILE, NOOP-CODE >VIRT , TOVALUE-CODE COMPILE, ;
: VECT ( -> ) ( создать слово, семантику выполнения которого можно менять, записывая в него новый xt по TO) HEADER ['] _VECT-CODE COMPILE, ['] NOOP , ['] _TOVALUE-CODE COMPILE, ; … : DEFER VECT ; … : DEFER CREATE ['] NOOP , DOES> @ EXECUTE ; : DEFER@ ' >BODY STATE @ IF POSTPONE LITERAL POSTPONE @ ELSE @ THEN ; IMMEDIATE : IS ' >BODY STATE @ IF POSTPONE LITERAL POSTPONE ! ELSE ! THEN ; IMMEDIATE : +TO ' >BODY STATE @ IF POSTPONE LITERAL POSTPONE +! ELSE +! THEN ; IMMEDIATE
Примечание[править]
Слова DEFER! и DEFER@ из черновика Forth 2000x в Каллисто отсутствуют. При необходимости их легко определить самостоятельно:
: DEFER! ( xt2 xt1 -- ) >BODY ! ; : DEFER@ ( xt1 -- xt2 ) >BODY @ ;
Ссылки[править]
- Исходный текст слова DEFER в Каллисто Классик 1.0
- См. слова TO, VALUE и EXECUTE
- См. также статью Векторное поле кода
- Слова DEFER, DEFER!, DEFER@ и ACTION-OF в черновике Forth 200x (англ.)
![]() |
У этой статьи нет иллюстраций. Вы можете помочь проекту, добавив их. |
![]() |
Это заготовка статьи. Вы можете помочь проекту, дополнив её. |