CL: ĐỌC công văn dựa trên ràng buộc có thể đọc được tới CL: * READTABLE * tại thời điểm cuộc gọi đến READ chạy. Dưới mui xe ENABLE-INTERPOL-SYNTAX đang tạo ra một readtable mới, thiết lập CL: * READTABLE * để giữ nó, và stashing giá trị cũ của CL: * READTABLE *. DISABLE-INTERPOL-SYNTAX không hủy bỏ cài đặt có thể đọc trước đó và thiết lập CL: * READTABLE * để giữ lại nó. Tối thiểu thay đổi thiết lập ban đầu của bạn, bạn có thể sắp xếp cho hành vi mà bạn muốn bằng cách sau:
(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))))
Cuộc gọi để vô hiệu hóa cú pháp có thể được đặt ở bất cứ đâu sau khi defvar và đọc-và-eval sẽ vẫn làm việc, nhưng nếu bạn muốn nhập trực tiếp cú pháp interpol vào tệp mà cú pháp sẽ phải được đặt giữa các cuộc gọi bật và tắt. Với mục đích thứ hai, điều quan trọng là interpol gọi mở rộng thành EVAL-WHENs, vì cùng một lý do là cần thiết cho cuộc gọi của bạn đến REQUIRE để ở trong EVAL-WHEN; đó là, các hiệu ứng cần phải đã xảy ra khi các dạng sau được ĐỌC. giao diện
CL-INTERPOL của tóm tắt những gì đang xảy ra, vì vậy tôi sẽ chỉ cho bạn cách bạn tự có thể tạo và thay đổi một 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)
Nguồn
2013-09-02 19:37:50