“JRM’s Syntax-rules Primer for the Merely Eccentric” メモ(その7) scheme-eval
続きです。最後の scheme-eval 、
The obligatory hack.
The following is a small scheme interpreter written as a syntax-rules macro. It is incredibly slow.
いつものやつ、とか、いつものやんなきゃなんないやつ、といったところでしょうか。
(scheme-eval ((Y (lambda (fac) (lambda (n) (if (sero? n) '(()) (mulz n (fac (zub1 n))))))) '(() () ()))) ;;-> (quote (() () () () () ()))
“The Little Schemer” に出てくる 6. Shadows の章の関数群と Y 関数を使って階乗が動いたところ。すごい動いた、というシンプルすぎる正直な感想です。
initial-environment に sero? 等の関数を置いておきたいので、 lambda form が動くようにしました。
... (define-syntax meval (syntax-rules (if lambda quote) ((meval k () env) (return k ())) ((meval k (if pred cons alt) env) (macro-if (meval pred env) (meval k cons env) (meval k alt env))) ((meval k (lambda names body) env) (return k (closure names body env))) ((meval k (quote object) env) (return k object)) ((meval k (operator . operands) env) (meval-list ((mapply k env)) () (operator . operands) env)) ((meval k whatever env) (macro-if (is-symbol? whatever) (mlookup k whatever env) (return k whatever))))) ... (define-syntax mapply (syntax-rules (closure lambda) ((mapply k _env ((closure names body env) . operands)) (macro-call k (! (meval body (! (extend-environment env names operands)))))) ((mapply k env ((lambda names body) . operands)) (macro-call k (! (meval body (! (extend-environment env names operands)))))) ((mapply k _env (operator . operands)) (macro-if (is-symbol? operator) (operator k . operands) '(non symbol application: operator))))) ...