2010-01-12 2 views
1

일치 확장을 작성하기위한 도우미 매크로를 만들고 싶습니다. 나는 다음과 같은 것을 가지고있다 :스키마에서 매크로의 값 목록에 "rest"변수를 바인딩하는 방법

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

그래서 나는 바인딩을 할 매크로를 원했다. 저는 다음과 같이 시작했습니다 :

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

그러나 match-let은 변환 시간에 정의되어 있지 않습니다.

첫 번째 질문은이 작업을 수행하는 다른 방법일까요? (이 확장 기능을 만드는 것입니까?) 아마도 이미 알고있는 plt-scheme과 비슷한 것이 있거나 어떤 식 으로든 잘못하고 있습니다.

첫 번째 질문에 대한 대답에 관계없이 매크로의 값 목록에 변수 목록을 바인딩하려는 경우 어떻게해야합니까?

편집 : 나는 당신이 달성하기 위해 노력하고 있다는 것입니다,하지만 내 추측이 오른쪽에가는 것이 무엇인지 모르는

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

답변

4

: 엘리의 응답 매크로와 결합 이제 다음과 같습니다 방향 :

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

것은이 syntax-e이 구문 객체를 "풀다"하고 보유하고 무엇을 제공하는 데 사용됩니다 -하지만 실제 내용은 당신을 놀라게 할 수 있습니다. 예를 들어, (foo . (bar))(foo bar)과 약간 다른 내용을 갖습니다. 따라서 일반적으로 syntax-case을 사용하여 패턴 일치를 수행하면 이 훨씬 많습니다. 더 쉽습니다. 더 쉬울뿐만 아니라, 코드를 사용하는 대신 오류가있을 때 감각적 인 오류 메시지를 제공합니다.

+0

감사합니다. 도움이되었으며 내 문제를 해결하는 데 도움이되었습니다. 완전성을 위해서 내가 expander를 만들지는 않았지만 목록을 취하는 람다가있는 매크로로 확장되는 매크로와리스트 요소를 매크로 매개 변수에 바인딩하고 싶다면? – Slartibartfast

+0

패턴 일치 작업을 사용하여 매크로를 작성하는 경우가 대부분입니다. 그러나 때때로 (좋은 오류 메시지와 같은 문제가있는 고급 매크로를 작성하는 경우 더 자주) 목록으로 변환해야합니다. 이를 위해'(syntax-> list # '(stuff ...))'와 같은 것을 사용할 수 있습니다 - 괄호로 묶은 구문 객체를 취하여 구문 객체 목록으로 변환합니다. –