CL:READへの呼び出しが実行されるときに、CL:* READTABLE *にバインドされた読み取り可能テーブルに基づいて、READが送出します。フードの下で、ENABLE-INTERPOL-SYNTAXは、CL:* READTABLE *を設定してそれを保持し、CL:* READTABLE *の古い値を隠す新しい読み取り可能テーブルを作成しています。 DISABLE-INTERPOL-SYNTAXは以前の読込み可能なテーブルをアンスタッシュし、CL:* READTABLE *を設定して再度保持します。 defvarの後にどこにでも配置することができる
(in-package :cl-user)
(eval-when (:compile-toplevel :load-toplevel :execute)
(require :cl-interpol))
(cl-interpol:enable-interpol-syntax)
(defvar *interpol-reader* *readtable*)
(cl-interpol:disable-interpol-syntax)
(defun read-and-eval (s)
(let ((*readtable* *interpol-reader*))
(eval (read-from-string s))))
コールを構文を無効にすると、読み取りと-evalのはまだ動作しますが、場合:最低限、あなたのオリジナルの設定を変更し、あなたは以下のことによりたかった行動を手配することができますファイルにinterpol構文を直接入力して、有効と無効の呼び出しの間に構文を配置する必要があります。その後者の目的のためには、REQUIREへの呼び出しがEVAL-WHEN内にある必要があるのと同じ理由で、補間呼び出しがEVAL-WHENに展開されることが重要です。つまり、後者の書式がREADのときに、その効果が既に発生している必要があります。
CL-インターポールのインターフェースは何が起こっているかを抽象化し、私はあなたが手動でreadtableを作成し、変更する場合がありますどのようにあなたが表示されます:
;; Create a fresh readtable with standard syntax
(defvar *not-readtable* (copy-readtable nil))
;; A simple reader function
(defun not-reader (stream char &optional count)
"Like ' but for (not ...) instead of (quote ...)"
(declare (ignore count char))
`(not ,(read stream t nil t)))
;; Mutate that readtable so that the dispatch character you want
;; calls the function you want
(set-macro-character #\! 'not-reader nil *not-readtable*)
;; Try it out
(let ((*readtable* *not-readtable*))
(read-from-string "(if !foo bar baz)"))
=>
(IF (NOT FOO)
BAR
BAZ)