2016-07-25 10 views
5

私はしばしばラケットのパターンマッチングコンストラクトmatchを使用していますが、matchを使ってデバッグプログラムを手助けし、ラケット/スキームマクロがどのように機能するかを知る方法を考えました。どのパターンが一致したかなどの情報言い換えればマクロ定義の昇順番号

は、私はこれを与えられた、というマクロを作成しているよ:

(match/debug 'two 
    ['one 1] 
    ['two 2]) 

出力する。このような何か:

Case 2 <-- Printed 
2  <-- Returned value 

主な障害は、これまでに取得しようとしてきました解決されたケースが正しく表示されることを示す数字。

私の目標は次のように展開すると何か書き込もうとしました:

(match 'two 
    ['one (displayln "Case 1") 1] 
    ['two (displayln "Case 2") 2]) 

をしかし、私はそれらの「ケース#」文字列を生成する方法を把握することができていません。

は、ここに私が試みマクロ定義です:

(define-syntax-rule (match/debug id [pattern value] ...) 
    (let ([index 0]) 
    (match id 
     [(begin 
     (set! index (add1 index)) 
     pattern) 
     (printf "Case ~a\n" index) 
     value] ...))) 

それは私がこのような何かをさせませんmatchの構文かのように見えるが、これは私は考えることができる唯一の方法でした。私はCommon Lispのマクロスタイルには本当に慣れています。

答えて

5

ここに解決策があります。

ヘルパ関数clauses->numbersは、0から1つの節数未満のリストを返します。これは、各節に独自の番号を付けるために使用されます。このソリューションは0から数えます(例では1ではありません)。

#lang racket 
(require (for-syntax syntax/parse)) 

(begin-for-syntax 
    (require racket/list) ; import range 
    (define (clauses->numbers stx) 
    (range (length (syntax->list stx))))) 

(define-syntax (match/debug stx) 
    (syntax-parse stx 
    [(_match/debug id [pattern value] ...) 
    (with-syntax ([(n ...) (clauses->numbers #'([pattern value] ...))]) 
     (syntax/loc stx 
     (match id 
      [pattern (begin (displayln (~a "Case: " n)) value)] 
      ...)))])) 

(match/debug 'one 
    ['one 1] 
    ['two 2]) 

(match/debug 'two 
    ['one 1] 
    ['two 2]) 

出力:私は実際に引用されたパターンを使用して終了

Case: 0 
1 
Case: 1 
2 
+0

はFunnily十分...、それは私に十分な情報を与えました。しかし、迅速かつ徹底的な対応に感謝します! – mellowmaroon

関連する問題