2012-03-25 2 views
2

Я только что начал погружаться в макросы Racket и стараюсь сделать крошечный макрос макроопределения. Я хотел бы расширить выражение вроде этого:Racket macros - making pairs

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

В чем-то вроде этого:

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

Так cddr оригинального выражения превращается в пар выражений (для использования в синтаксических правил тело), ​​а идентификатор вставлен в автомобиль каждой из этих пар.

У меня возникли проблемы с рекурсивным анализом при использовании только соответствия шаблонов, предоставляемого синтаксическими правилами (я все время хочу манипулировать выражением, как если бы это был обычный список). Какую модель я должен использовать? Или я могу каким-то образом манипулировать им как обычный список, а затем безоговорочно использовать результат для использования в расширении?

Большое спасибо

Edit - предварительное решение, информируются ответ 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

1

Taymon прав, но это также можно сделать с эллипсов без оберточной пары шаблонов замены в скобках, используя ~seq из syntax/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)