MIT Schemeでdefine-macroする
yuniのレガシーなビルドシステムと決別する最後の壁になっていたMIT Schemeも、define-macro
を手作りすることでサポートできた。というわけで、これで従来のビルドシステムから新しいビルドシステムに置き換えられる。。
新しいビルドシステムではLarceny、Vicare、picrin、 nmosh などいくつかの処理系のサポートを停止する。その代わりもっと別の処理系(主に非R6RS/R7RS処理系)をサポートする予定。nmoshを切るのは断腸の思いだけど、別の処理系をスクラッチで作る予定なのでそのための工数をどうしても空ける必要がある。
define-macro
を逆sc-macroで定義する
... 今検索したらそのものズバリなStack overflowが有った。。
(define-syntax define-macro (syntax-rules () ((define-macro (name . args) body ...) (define-syntax name (rsc-macro-transformer (let ((transformer (lambda args body ...))) (lambda (exp env) (apply transformer (cdr exp)))))))))
MIT Schemeにおける低レベルマクロは、chibi-schemeと同じく syntactic closure で、sc-macro-transformer
は、
- マクロが挿入したシンボル → マクロが定義された場所の意味で解釈される
make-syntactic-closure
を通したシンボル → (一般に)マクロが使われた場所の意味で解釈される
という性質がある。ここで使用している rsc-macro-transformer
は 逆 で、マクロが挿入したシンボルはマクロが使われた場所の意味で解釈される。これは define-macro
でやりたいことそのものと言える。
今回実装したものは、↑の実装に加えて、 define-syntax
のための特別対応を入れている:
(define-syntax define-macro (syntax-rules (define-syntax) ((_ (define-syntax name synrule) body ...) ;; Skip syntax-rules (begin)) ((_ (nam . args) body ...) (define-syntax nam (rsc-macro-transformer (let ((xformer (lambda args body ...))) (lambda (exp _) (apply xformer (cdr exp)))))))))
これは、yuniのランタイムが syntax-rules
を備えないScheme処理系のために define-syntax
をマクロで定義するコードを含んでいることによる。MIT SchemeはR5RS(R7RS)なので syntax-rules
は当然持っており、yuniのコードにある (define-macro (define-syntax ...) ...)
のコードは無視しなければならない。そうでないと define-macro
が define-syntax
に展開され、無限再帰してしまう。。
MIT SchemeがR7RSでないところ
MIT Schemeは真の values
を実装していない https://mjt.hatenadiary.com/entry/20170515/p1 以外に、yuniのテストケースで見つかったものとしては:
list-copy
がペア以外を受けつけない https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Construction-of-Lists.html#index-list_002dcopylog
が底を取らない https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Numerical-operations.html#index-log
というのが有った。流石に values
をエミュレートするのはパフォーマンスペナルティが大きすぎるけど、この辺はエミュレートした方が良いかもしれない。。
それ以前に、MIT SchemeのR7RSサポートは現状ライブラリパスを設定する方法が無く、yuniではR7RS処理系ではなく define-macro
処理系(yuniの用語でGeneric Scheme処理系)として扱っている。