2011-08-09 17 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でこれを行うより良い方法はありますか?2つのモジュールで実装を分割しない方がよいでしょうか?私はそれを明確に、この例では、ただ1つのマクロではあるが、現実には、私は複数のマクロは、状態を共有する必要があるときに働く方法を探していますことを確認する必要があり

EDIT

あなたがマクロ変換する状態をローカルにすることができ

答えて

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、いいえ、私はR6RSの助けになるものは何も知らない。私の編集された答えも見てください。 –

関連する問題