1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; indent-tabs-mode: nil -*-
6 (in-package :iolib.base
)
10 (defgeneric enable-reader-macro
* (name))
12 (defgeneric disable-reader-macro
* (name))
14 (defmacro enable-reader-macro
(name)
15 `(eval-when (:compile-toplevel
)
16 (enable-reader-macro* ,name
)))
18 (defmacro disable-reader-macro
(name)
19 `(eval-when (:compile-toplevel
)
20 (disable-reader-macro* ,name
)))
22 (defun save-old-readtable (symbol readtable
)
23 (setf (getf (symbol-plist symbol
) 'old-readtable
) readtable
))
25 (defun get-old-readtable (symbol)
26 (getf (symbol-plist symbol
) 'old-readtable
))
28 (defmethod enable-reader-macro* :before
((name symbol
))
29 (save-old-readtable name
*readtable
*)
30 (setf *readtable
* (copy-readtable)))
32 (defmethod disable-reader-macro* ((name symbol
))
33 (assert (readtablep (get-old-readtable name
)))
34 (setf *readtable
* (get-old-readtable name
))
35 (save-old-readtable name nil
))
37 (defmacro define-syntax
(name &body body
)
38 `(defmethod enable-reader-macro* ((name (eql ',name
)))
42 ;; Literal object dispatcher
44 (define-condition unknown-literal-syntax
(reader-error)
45 ((name :initarg
:name
:accessor unknown-literal-syntax-name
))
46 (:report
(lambda (s c
)
47 (format s
"Unknown literal read syntax: ~S"
48 (unknown-literal-syntax-name c
)))))
50 (defconstant +read-literal-dispatch-char
+ #\
#)
51 (defconstant +read-literal-sub-char
+ #\
/)
53 (defun read-literal-dispatcher (stream char arg
)
54 (declare (ignore char arg
))
55 (let* ((literal-syntax-name
56 (with-output-to-string (s)
57 (loop :for c
:= (read-char stream t nil t
)
58 :do
(if (char= c
+read-literal-sub-char
+)
62 (getf (symbol-plist (read-from-string literal-syntax-name
))
64 (if (functionp literal-reader
)
65 (funcall literal-reader stream
)
66 (error 'unknown-literal-syntax
68 :name literal-syntax-name
))))
70 (set-dispatch-macro-character +read-literal-dispatch-char
+
71 +read-literal-sub-char
+
72 'read-literal-dispatcher
)
74 (defmacro define-literal-reader
(name (stream) &body body
)
75 `(setf (getf (symbol-plist ',name
) 'read-literal-fn
)
76 (lambda (,stream
) ,@body
)))