2012-03-25 12 views
2

Ich habe gerade angefangen, in Racket-Makros einzutauchen, und versuche, ein kurzsichtiges, Makro definierendes Makro zu erstellen. Ich möchte einen Ausdruck wie folgt erweitern: wie dieseRacket-Makros - Paare bilden

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

In etwas:

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

So ist die CDDR des ursprünglichen Ausdrucks wird in Paare von Ausdrücken gedreht (für den Einsatz in der Syntax-Regeln Körper), und die ID wird in das Auto jedes dieser Paare eingefügt.

Ich habe Probleme, rekursiv zu denken, wenn ich nur den Mustervergleich benutze, der von den Syntaxregeln bereitgestellt wird (ich möchte den Ausdruck so manipulieren, als wäre es eine normale Liste). Welche Art von Muster sollte ich verwenden? Oder kann ich es irgendwie als normale Liste manipulieren und dann das Ergebnis für die Verwendung in der Erweiterung aufheben?

Vielen Dank

Bearbeiten - vorläufige Lösung, informiert durch Taymon Antwort

Teil meiner Neugier war hier über diese Paarung Klammern loszuwerden. Ich habe mich mit dem Syntaxfall beschäftigt, bin aber ein wenig verwirrt, also habe ich versucht, es rein mit der Muster-passenden Untersprache zu machen. Ich landete Taymon Makro in Kombination mit einem anderen Makro zu ‚pairize‘ die gegebenen Vorlagen (es wirkt ein bisschen wie ein Akkumulator-Funktion) mit bis:

(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 ...)))) 

Antwort

6

Es ist möglich, ein Makro-Expander zu bauen, der die Syntax Ausdruck als reguläre manipuliert Schlägerdaten. Dies ist jedoch in diesem Fall nicht wirklich notwendig.

Eine Sache, die ich empfehlen würde, ist Ihre Syntax leicht zu ändern, so dass jedes Muster-Ersatz-Paar in Klammern eingeschlossen ist. Wie folgt:

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

Sobald das erledigt ist, können Sie einfach ein reguläres Muster-Matchmakro verwenden. Hier ist mein nehmen auf sie:

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

Vielen Dank! Ich war mir nicht ganz bewusst, wie Elips in Mustern funktionierten, bis ich dein Beispiel sah, und habe deine Regel in einer vorläufigen Lösung verwendet. – twf

1

Taymon ist richtig, aber es ist auch möglich, mit Ellipsen zu tun ohne Umwickeln der Muster-Ersetzen-Paare in Klammern, mit ~seq von syntax/parse:

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

Welche können verwendet werden, wie Sie ursprünglich wollten:

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