Next: 発展問題
Up: ソフトウェア特論 講義資料 Scheme コンパイラ処理系
Previous: 10.6 クロージャの確認
実際のscheme処理系では,tは,#t, nilは,#f という表記が使われま
す.これらの表記を入力するとそれぞれt, nilとして扱われるようにするため
に,Common Lispのリードマクロを再定義する機能により実装する方法が考え
られます.
まず,
Schemeの組み込み関数readが
通常のLispの通常のread関数を呼び出すのではなく,
scheme-readというこれから定義する関数を
呼び出すように,初期化用テーブルを次のように変更します.
(defparameter *scheme-procs*
'(+ - * /
abs sqrt sin cos atan
= < > <= >=
cons car cdr not append list
member
(read scheme-read) random name!
(null? null) (eq? eq)
(equal? equal) (eqv? eql)
(compile scheme-compile)
(exit scheme-exit)
(number? numberp)
(even? evenp) (odd? oddp)
(write prin1) (display princ)
(newline terpri)))
通常の状態で使っているリードマクロは,copy-readtable
でコピーすることができます.
リードテーブルは,利用可能な全文字ごとに
読み込み方を定義している関数を定義する関数を
登録してあるものです.
この表の中で,#で始まり,その次に続く文字に
対応する関数を置き換える手続きとして,
set-dispatch-macro-characterという関数が
用意されています.
新しく置き換えを行ったリードテーブルを
利用して通常のread手続きを行うには,
大域変数の*readtable*をその新しいリードテーブルに
局所的に置き換えて実行するということで
可能となります.その局所的置き換えには,
letを使うことができます.letから抜ければ
通常のリードテーブルを利用することになります.
(defvar *scheme-readtable* (copy-readtable))
(defun scheme-read
(&optional (stream *standard-input*))
(let ((*readtable* *scheme-readtable*))
(read stream)))
(set-dispatch-macro-character #\# #\t
#'(lambda (&rest ignore) t)
*scheme-readtable*)
(set-dispatch-macro-character #\# #\f
#'(lambda (&rest ignore) nil)
*scheme-readtable*)
generated through LaTeX2HTML. M.Inaba 平成18年5月6日