2012-03-25 82 views
2

我剛開始潛入球拍宏,並試圖製作一個簡潔的宏 - 宏定義宏。我想擴大這樣的表達式:球拍宏 - 製作對

(macro id 
    (param) replacement1 
    (params ...) replacement2) 

弄成這個樣子:

(define-syntax id 
    (syntax-rules() 
     ((id param) replacement1) 
     ((id params ...) replacement2))) 

所以原始表達式的CDDR變成表達對(用於語法規則身體),並且id被插入每個這些對的汽車中。

當我僅使用由語法規則提供的模式匹配(我一直希望像處理普通列表一樣操縱表達式)時,我在遞歸思考時遇到了麻煩。我應該使用什麼樣的模式?或者,我可以以某種方式將其作爲普通列表進行操作,然後取消在擴展中使用的結果?

非常感謝

編輯 - 試探性的解決方案,通過Taymon的回答

在這裏我的好奇心部分通知給即將擺脫那些配對括號。我研究了語法情況,但有點困惑,所以試圖純粹使用模式匹配子語言。最後我用Taymon宏觀與另一宏「pairize」給定的模板(它的作用有點像一個蓄電池功能)合併:

(define-syntax-rule (macro-aux id ((param ...) expr) ...) 
    (define-syntax id 
    (syntax-rules() 
     ((id param ...) expr) 
     ...))) 

(define-syntax pairize 
    (syntax-rules() 
    ((pairize id (pairs ...) p b) (macro-aux id pairs ... (p b))) 
    ((pairize id (pairs ...) p b rest ...) (pairize id (pairs ... (p b)) rest ...)))) 

(define-syntax macro 
    (syntax-rules() 
    ((macro id tpl-expr ...) (pairize id() tpl-expr ...)))) 

回答

6

這是不可能建立操縱的語法表達作爲常規宏擴展球拍數據。但是,在這種情況下,這並不是真的必要。

我建議的一件事是稍微改變你的語法,以便每個模式替換對括在括號中。像這樣:

(macro id 
    [(param) replacement1] 
    [(params ...) replacement2]) 

一旦完成,您可以使用常規的模式匹配宏。這是我對此採取:

(define-syntax-rule (macro id [(param ...) replacement] ...) 
    (define-syntax id 
    (syntax-rules() 
     [(id param ...) replacement] ...))) 
+0

謝謝!在看到你的例子之前,我並沒有完全意識到elipses是如何工作的,並且已經在暫時的解決方案中使用了你的規則。 – twf 2012-03-25 19:50:23

1

Taymon是正確的,但它也可以用省略號做纔不至於包裹在括號中的模式替換對,使用~seqsyntax/parse

(require syntax/parse/define) 
(define-simple-macro (macro id (~seq (param ...) replacement) ...) 
    (define-syntax id 
    (syntax-rules() 
     [(id param ...) replacement] ...))) 

可以像你最初想要的那樣使用:

(macro id 
    (param) replacement1 
    (params ...) replacement2)