CL: READ-Versendungen basierend auf der lesbaren Tabelle an CL: * READTABLE * zum Zeitpunkt des Aufrufs von READ. Unter der Haube erstellt ENABLE-INTERPOL-SYNTAX eine neue lesbare Tabelle mit der Einstellung CL: * READTABLE *, um sie zu speichern und den alten Wert von CL zu speichern: * READTABLE *. DISABLE-INTERPOL-SYNTAX löscht die vorherige Tabelle und setzt CL: * READTABLE *, um sie erneut zu halten. Minimal Ihre ursprüngliche Setup ändern, können Sie für das Verhalten, das Sie durch die folgenden wollten arrangieren:
(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))))
Der Aufruf der Syntax deaktivieren überall nach dem defvar werden konnten platziert und Lese- und eval wird immer noch funktionieren, aber wenn Sie möchten direkt die Interpol-Syntax in die Datei eingeben, die zwischen den Aktivierungs- und Deaktivierungsaufrufen eingefügt werden muss. Zu diesem letztgenannten Zweck ist es von Bedeutung, dass die Interpol-Aufrufe zu EVAL-WHEN erweitert werden, aus dem gleichen Grund, aus dem es notwendig ist, dass Ihr Aufruf REQUIRE innerhalb eines EVAL-WHENs ist; Das heißt, die Effekte müssen bereits geschehen sein, wenn die letzteren Formulare READ sind.
CL-INTERPOL Schnittstelle abstrahiert, was geschieht, also werde ich Ihnen zeigen, wie Sie manuell erstellen könnte und ändern 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)