Как вставить литералы в определение двоеточия?

Я написал интерпретатор Forth для процессора J1, который сейчас портирую на Z80. В новой версии слово через двоеточие представляет собой список адресов, по которым будет обращаться интерпретатор.

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

Пример:

: 1+ 1 + ;

Когда компилятор встречает литерал 1, у него нет адреса для вызова, который помещает значение в стек.

Решением было бы динамически генерировать такую ​​процедуру, как

ld   hl, 1
push hl
ret

где-нибудь еще и используйте этот адрес в определении через двоеточие.

Другое решение — использовать недопустимый адрес (например, 0x0000), за которым следует литерал, что интерпретатор будет рассматривать как особый случай: при обнаружении адреса 0x0000 он просто помещает значение следующих двух байтов в стек. В этом случае определение 1+ в памяти будет таким:

0x0000 ;
0x0001 ; literal
0x4500 ; + routine address

Есть ли лучшее решение?

Редактировать

В машинном коде J1 1+ компилируется в это

addr code     comments

0125 8001     1   ; Bit 15=1 push literal into stack
0126 628f     %+  ; This combine op codes PLUS and RET

Поскольку эта проблема не зависит от целевого процессора: как вы решили ее на своем бывшем Форте? -- Боюсь, что ваш вопрос приведет к самоуверенным ответам и на этом можно закрыться.

the busybee 10.07.2024 15:39

J1 — это машина на Форте, поэтому слова переводятся непосредственно в машинный код. Мой интерпретатор компилирует машинный код, где значения автоматически помещаются в стек. См. thh.org/svfig/kk/11-2010-Bowman.pdf

Candid Moe 10.07.2024 16:38
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Классический подход — манипулировать обратным адресом:

: (lit) ( -- x ) ( R: addr1 -- addr2 )
  \ NB: "(lit)" should not be used as an ordinary word
  r> dup cell+ >r @
;

: lit, ( x -- )
  ['] (lit) compile, ,
  \ it is assumed that code space
  \ is united with data space 
;
: literal ( x -- x | )
  state @ if lit, then
; immediate

Слово (lit) выше также известно как простое lit. Традиционно в Форте имя слова в скобках используется, чтобы подчеркнуть, что это слово предназначено только для внутренних целей.

Давайте рассмотрим определение foo:

: foo 42 + ;

Пусть одна ячейка занимает две единицы адреса, а тело foo начинается с адреса 1024. Тогда потоковый код тела состоит из следующих элементов:

  • 1024: xt из (lit)
  • 1026: число 42
  • 1028: xt из +
  • 1030: xt из exit

Когда (lit) вызывается из foo, верхнее значение в стеке возврата равно 1026. Это адрес, по которому хранится число 42. (lit) извлекает верхнее значение из стека возврата (1026), увеличивает его копию на размер ячейки и помещает результат (1028) в стек возврата. Он также извлекает значение по адресу 1026, оставляя в стеке 42. Затем выполнение продолжается на этапе 1028.

Значение, которое следует за инструкцией в двоичном коде и от которого зависит поведение инструкции, иногда называется «непосредственным аргументом» (непосредственным аргументом инструкции). Инструкцию с ее непосредственным аргументом можно рассматривать как одну инструкцию большего размера.

Не только (lit) имеет непосредственный аргумент. Инструкции условного перехода и перехода обычно также имеют непосредственный аргумент.

Альтернативный подход — генерировать анонимный примитив для каждой уникальной пары инструкции и ее непосредственного аргумента. Я не уверен, что этот подход использовался на практике.

См. также: Открытый интерпретатор: переносимость стека возврата Манипуляции , М.Л.Гасаненко, 1998г.

Я не понимаю, как это работает. Я уже компилирую слово, когда найден новый литерал (например, 42). Можете ли вы расширить?

Candid Moe 10.07.2024 16:50

@CandidMoe, см.: Открытый интерпретатор: переносимость манипуляций со стеком возврата. Дайте мне знать, если что-то неясно.

ruvim 10.07.2024 17:56

Похоже, мне придется переписать 1+ как : 1+ lit [ 1 , ] + ; , что некрасиво. А еще у меня есть xt из lit; просто я не понимаю, где хранить конкретное значение с помощью DTC. Есть только на lit, но значений много.

Candid Moe 10.07.2024 18:51

Почему бы и нет : 1+ [ 1 lit, ] + ;? Но это не обязательно. Обычно это делается текстовым интерпретатором Форта (или целевым компилятором). Я добавил конкретный пример того, как это работает.

ruvim 10.07.2024 22:32

Да, я думал в том же направлении. Это умаляет чистоту реализации «списка адресов», но работает.

Candid Moe 10.07.2024 22:48

По поводу чистоты списка адресов — даже без литералов он не такой чистый: условные переходы и переходы обычно тоже имеют непосредственный аргумент (пост обновил).

ruvim 11.07.2024 11:28

Другие вопросы по теме