syntax-rulesの仕様を読んで確認した
r7rsのsyntax-rulesのパターンの部分の仕様を読んで確認する。(vectorは省く)
とる形は、以下の4つ(Pはパターンで、[ellipsis]は、0個以上の繰り返し)
1. (P1 ... Pn )
2. (P1 ... Pn . Pn+1)
3. (P1 ... Pk Pe [ellipsis] Pm+1 ... Pn)
4. (P1 ... Pk Pe [ellipsis] Pm+1 ... pn . Px )
つまり、
1.真性リストで[ellipsis]を含まない。
2.非真性リストで[ellipsis]を含まない。
3.真性リストで[ellipsis]を含む。
4.非真性リストで[ellipsis]を含む。
ということか。
1
(define-syntax check-1 (syntax-rules () ((_ (a b c d e)) (quote (a b c d e))))) (display (check-1 (1 2 3 4 5)))(newline) ;(1 2 3 4 5)
真性リストで同じ要素数のものだけしかマッチしない。
特になし
2
(define-syntax check-2 (syntax-rules () ((_ (a b . c))(quote (a b c))))) (display (check-2 (1 2 )))(newline);(1 2 ()) (display (check-2 (1 2 3 )))(newline);(1 2 (3)) (display (check-2 (1 2 3 4 5)))(newline);(1 2 (3 4 5)) (display (check-2 (1 2 . 3)))(newline);(1 2 3)
非真性、真性どちらでもよく、左から順にマッチさせていき、のこりを最後のcdr部にマッチさせる。
これも、特になし。
3
(define-syntax check-3 (syntax-rules () ((_ (a b ... c d ))(quote (a b ... c d ))))) (display (check-3 (1 2 3 4 5)))(newline);(1 2 3 4 5) (display (check-3 (1 2 3)))(newline);(1 2 3)
真性リストで、[ellipsis]の左側と右側をマッチさせて、残りを[ellipsis]の所にマッチさせる。
これも、特になし。
4-1
全部、パターン変数の場合。
(define-syntax check-4a (syntax-rules () ((_ (a b ... c . d))(quote (b ... d ))))) (display (check-4a (1 2 3 4 5)))(newline);(2 3 4 ()) (display (check-4a (1 2 3 4 . 5)))(newline);(2 3 5) (display (check-4a (1 2 3)))(newline);(2 ())
処理系によっては、動かなかったり、明らかに間違った結果がでたりした。
saggitarius0.6.11やgauche0.9.5の結果だと、
非真性リストを入れると、末尾cdr同士、それ以外同士でマッチングし、
真性リストを入れると、patternの末尾cdrにnullがマッチして、全部その左側にマッチする。
4-2
定数を入れた場合。
(define-syntax check-4b (syntax-rules () ((_ (1 2 ... 3 . d))(quote d )))) (print (check-4b (1 2 2 2 3 . 4 )));4
真性リストを入力した場合、最後のcdr要素(null)だけが、Pxにマッチするので、
Pnまでうまくマッチできそうなケースでもだめだね。