includeというマクロを書いてみた。
別ファイルに書かれてあるS式を、ソースの中に埋め込むマクロだ。
loadと似ているが、呼び出した場所の環境で評価される点が違う。
include.scm
;; ファイルに書かれているS式を埋め込むマクロ。
;; 使い方: (include ファイル名)
;; ただし、ファイル名には文字列かトップレベルの変数しか指定できない
(defmacro include (fname)
(let ((read-all
(lambda (port)
(let lp ((e (read port)) (result (list)))
(if (eof-object? e) (reverse! result)
(lp (read port) (cons e result)))))))
`(begin ,@(call-with-input-file
(eval fname (interaction-environment))
(lambda (p) (read-all p))))))
適当なサンプルで動作確認
$ cat tmp2.scm # 埋め込むファイル
(display
(format "a=~A b=~A (foo a b) = ~A\n" a b (foo a b)))
(foo a b)
$ gosh
gosh> (load "./include.scm")
gosh> (define file "tmp2.scm")
gosh> (define foo +) (define a 10) (define b 20) ;; toplevel設定
gosh> (let ((foo *) (a 11)) (load file)) ;; loadの実行結果
=> a=10 b=20 (foo a b) = 30
#t
gosh> (let ((foo *) (a 11)) (include file)) ;; includeの実行結果
=> a=11 b=20 (foo a b) = 220
220
gosh> ^D
変数 foo,a,bについて、
loadの場合はトップレベルの定義で評価されているが、
includeでは、(let ...) バインドの値で評価されているのが確認できる。
0 件のコメント:
コメントを投稿