2011-08-09 2 views
1

이것은 작동하는 것처럼 보입니다. 매크로가 확장 된 횟수에 따라 연속적인 정수로 확장되는 매크로입니다.로컬 상태를 유지하는 매크로를 작성하는 방법은 무엇입니까?

;; Library (test macro-state) 
(library 
(test macro-state) 
(export get-count incr-count) 
(import (rnrs)) 

(define *count* 0) 
(define (get-count) *count*) 
(define (incr-count) (set! *count* (+ *count* 1))) 

) 

;; Program 
(import (rnrs) (for (test macro-state) expand)) 

(define-syntax m 
    (lambda (x) 
    (syntax-case x() 
     ((m) (begin (incr-count) (datum->syntax #'m (get-count))))))) 

(write (list (m) (m) (m))) 
(newline) 
;; prints (1 2 3) 

그러나 매크로 상태 *count* 및 매크로 m 자체가 다른 모듈에 있기 때문에 그것은 나에게 서투른입니다. r6rs에서이 작업을 수행하는 더 좋은 방법이 있습니까? 두 모듈을 통해 구현을 분할하지 않는 것이 더 바람직합니까?

편집

이 예는 단지 하나의 매크로하지만 나는 분명히 있는지 확인해야한다 현실에서 나는 여러 매크로 상태를 공유해야 할 때 작동하는 방법을 찾고 있어요

.

매크로 변압기 상태가 지방 만들 수

답변

5

:

(define-syntax m 
    (let() 
    (define *count* 0) 
    (define (get-count) *count*) 
    (define (incr-count) (set! *count* (+ *count* 1))) 
    (lambda (x) 
     (syntax-case x() 
     ((m) (begin (incr-count) (datum->syntax #'m (get-count)))))))) 

편집 추가 :

(begin-for-syntax 
    (define *count* 0) 
    (define (get-count) *count*) 
    (define (incr-count) (set! *count* (+ *count* 1)))) 
(define-syntax m 
    (lambda (x) 
    (syntax-case x() 
     ((m) (begin (incr-count) (datum->syntax #'m (get-count))))))) 

그러나 나는 생각하지 않는다 :Racket, 당신은이 작업을 수행 할 수 있습니다 R6RS에는 begin-for-syntax에 해당하는 것이 있습니다.

+0

예 게시 한 후에 생각했습니다. 하지만 여러 매크로가 상태를 공유하도록하려면 해당 메소드가 일반화되어 있습니까? – john

+0

@john, no, 그리고 나는 R6RS에서 도움이 될만한 것을 모른다. 내 편집 된 답변을 참조하십시오. –

관련 문제