2010-01-12 5 views
1

Je souhaite créer une macro d'aide pour écrire des extensions de correspondance. J'ai quelque chose comme ceci:Comment lier les variables "repos" à la liste de valeurs dans la macro dans le schéma

(define-match-expander my-expander 
    (λ (stx) 
    (let* ([dat (cdr (syntax-e stx))] 
      [var1 (car dat))] 
      [var2 (cadr dat)]) 
     ;transformer goes here))) 

Donc je voulais une macro qui le fera laisser la liaison. Je l'ai commencé avec quelque chose comme ceci:

(define-syntax-rule (define-my-expander (id vars ...) body) 
    (define-match-expander id 
    (λ (stx) 
     (match-let ([(vars ...) (cdr (syntax-e stx))]) 
     body)))) 

mais match-let n'est pas définie dans le temps de transformation.

La première question serait: y a-t-il une autre façon de faire cela (ce qui veut dire que ce sont des expandeurs)? Peut-être y a-t-il déjà quelque chose de similaire dans le plt-scheme que je ne connais pas, ou je le fais d'une manière ou d'une autre.

Indépendamment de la réponse à la première question, si jamais je veux lier la liste des variables à la liste des valeurs à l'intérieur d'une macro, comment dois-je faire?

EDIT: En combinaison avec la macro réponse Eli ressemble maintenant à ceci:

(define-syntax-rule (define-my-expander (id vars ...) body) 
    (define-match-expander id 
    (λ (stx) 
     (syntax-case stx() 
     [(_ vars ...) 
     body])))) 

Répondre

4

Je ne sais pas ce qu'il est que vous essayez d'atteindre, mais je pense que cela va dans le droit direction:

(define-match-expander my-expander 
    (lambda (stx) 
    (syntax-case stx() 
     [(_ (var1 var2) stuff ...) 
     ;; use #'var1 #'var2 and #'(stuff ...) here 
     ]))) 

la chose est que syntax-e est utilisé pour « déballer » un objet de syntaxe et de vous donner ce qu'elle contient - mais le contenu peut vous surprendre. Par exemple, (foo . (bar)) aura un contenu légèrement différent de (foo bar). Donc en général, en utilisant syntax-case pour faire la correspondance de modèle pour vous est beaucoup plus facile. En plus d'être plus facile, il donnera aussi des messages d'erreur sensibles lorsqu'il y a des erreurs, au lieu de ce que vous obtiendriez avec votre code.

+0

Merci, ceci m'a été utile et utile pour m'aider à résoudre mon problème. Par souci d'exhaustivité, si je ne faisais pas d'expandeurs, mais disons, une macro qui se développe en quelque chose qui a lambda qui prend une liste et que je veux lier des éléments de liste à des paramètres de macro? – Slartibartfast

+0

Dans la plupart des cas, vous écrivez des macros à l'aide de travaux de correspondance de modèles. Mais de temps en temps (peut-être plus fréquemment lorsque vous écrivez des macros plus avancées avec des problèmes comme de bons messages d'erreur), vous devez les transformer en une liste. Pour cela, vous pouvez utiliser quelque chose comme '(syntax-> list # '(stuff ...))' - il prend l'objet de syntaxe entre parenthèses, et le transforme en une liste d'objets de syntaxe. –

Questions connexes