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 つのマクロにすぎませんが、実際には、複数のマクロが状態を共有する必要がある場合に機能する方法を探していることを明確にしておく必要があります。

4

1 に答える 1

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))))))))

編集して追加: Racketでは、次のこともできます。

(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)))))))

しかし、R6RS には に対応するものはないと思いますbegin-for-syntax

于 2011-08-09T16:35:38.447 に答える