Могут ли параметры синтаксиса использоваться для замены синтаксиса? - PullRequest
0 голосов
/ 25 апреля 2018

Я пытаюсь использовать параметры синтаксиса, чтобы внедрить новый синтаксис там, где мне нужно его ввести.Результат этого затем используется в другом синтаксисе.Тем не менее, это не работает, как я ожидаю.Вот минимальный рабочий пример:

(require racket/stxparam)
(require (for-syntax racket/stxparam))

;; declare parameter to be replaced with code
(define-syntax-parameter placeholder
  (lambda (stx)
    (raise-syntax-error
     (syntax-e stx)
     "can only be used inside declare-many-commands")))

;; this is just to print what 'arg' looks like
(define-syntax (print-syntax stx)
  (syntax-case stx ()
    [(_ arg)
     #'(displayln 'arg)]))

;; this is the top-level entity invoked to produce many commands
(define-syntax-rule (declare-many-commands cmds)
  (begin
    (let ([X 10])
      (syntax-parameterize
       ([placeholder (make-rename-transformer #'X)])
       cmds))
    (let ([X 20])
      (syntax-parameterize
       ([placeholder (make-rename-transformer #'X)])
       cmds))))

(declare-many-commands
 (print-syntax placeholder))

Что я хотел бы получить в результате при запуске это:

10
20

, но я получаю:

placeholder
placeholder

РЕДАКТИРОВАТЬ:

Добавлено новый вопрос для уточнения проблемы: Внедрение синтаксиса во время компиляции с использованием параметров синтаксиса Racket?

1 Ответ

0 голосов
/ 25 апреля 2018

Проблема в том, что ваш макрос print-syntax заключает в кавычки свои входные данные, а входные данные для макротрансформаторов имеют нерасширенный синтаксис.Это означает, что расширение (print-syntax placeholder) всегда будет (displayln 'placeholder), и при quote никогда не происходит макроразложение, поэтому привязка placeholder в области действия не имеет значения.

Если вы хотите использовать синтаксисПараметр, вам нужно создать ссылку на привязку placeholder.В этом случае вам просто нужно исключить использование quote.Вы можете изменить print-syntax на (displayln arg), но на этом этапе действительно нет причины для print-syntax быть макросом, поскольку он эквивалентен функции displayln.Просто используйте это вместо:

(declare-many-commands
 (displayln placeholder))

Это напечатает 10 и 20, как вы ожидаете.

Возможно, вы действительно хотите quote, а я нетпонимаю твой вопрос.В этом случае, однако, я думаю, что мне трудно понять, к чему вы клоните, без какого-либо дополнительного контекста.

...