昨日はスロット番号付きの cut を syntax-rules で書いた。
スロット番号付き cut を syntax-rules で書く - 主題のない日記
だが、 R5RS の範囲内では書けなかった。
今回は R5RS の範囲内で書いた。 つもりなのだが…。 Gauche を含むいくつかの R5RS 処理系ではエラーとなった。 詳細は後述する。
(define-syntax %%%cutn (syntax-rules () ((_ args () slots) (lambda slots args)) ((_ (r ...) (a0 a1 ...) (slots ...)) (letrec-syntax ((ex (syntax-rules (slots ... <...>) ((_ slots) (%%%cutn (r ... slots) (a1 ...) (slots ...))) ... ((_ <...>) (rx (r ...) (slots ...) a1 ...)) ((_ x) (%%%cutn (r ... a0) (a1 ...) (slots ...))))) (rx (syntax-rules () ((_ args (slots ...)) (lambda (slots ... . <...>)(apply r ... <...>)) )))) (ex a0))))) (define-syntax %%cutn (syntax-rules () ((_ args _1 slots _2 ()) (%%%cutn () args slots)) ((_ args (r1 ...) (r2 ...) (u ...) (s ss ...)) (let-syntax ((ex (syntax-rules (u ...) ((_ u) (%%cutn args (r1 ... s) (r1 ... s) (u ...) (ss ...))) ... ((_ x) (%%cutn args (r1 ... s) (r2 ...) (u ...) (ss ...)))))) (ex s))))) (define-syntax %cutn (syntax-rules () ((_ args r slots) (%%cutn args () () r slots)) ((_ args (r ...) (slots ...) a0 a1 ...) (let-syntax ((ex (syntax-rules (slots ...) ((_ slots) (%cutn args (r ... slots) (slots ...) a1 ...)) ... ((_ _) (%cutn args (r ...) (slots ...) a1 ...)) ))) (ex a0))))) (define-syntax cutn (syntax-rules () ((_ args ...) (%cutn (args ...) () (<0> <1> <2> <3> <4> <5> <6> <7> <8> <9>) args ...))))
これで問題になるのはマクロテンプレートに現われる ellipsis のようだ。 問題を再現する小さな例を書いてみた。
(define-syntax hoge (syntax-rules () ((_ r ...) (list '(r (r ...)) ...)))) (hoge 1 2 3)
これが許されるべきなのかどうか R5RS を読んでもよくわからない。
Document ID: 7841b2535bdfb990d918947333337b0a