挿入する必要のある場所に新しい構文を挿入するために、構文パラメーターを使用しようとしています。この結果は、他の構文で使用されます。ただし、期待どおりに機能していません。最小限の作業例を次に示します。
(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の構文パラメーターを使用してコンパイル時に構文を挿入しますか?
ここでの問題は、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
、そして私はあなたの質問を理解していません。ただし、その場合、追加のコンテキストがないと、何が得られているのかを理解するのは難しいと思います。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加