Pascal J. Bourguignon <pjb@informatimago.com> wrote:
+---------------
| billc <billclem@gmail.com> writes:
| > Here's the "official" meeting notice:
| > Topic: 0x20 Years of Lisp Systems, a Personal Journey
|
| #x20
|
| Or else you will have to write quite some reader macros...
+---------------
Here's the one I use:
;;; SET-ZERO-X-READER -- Provide C-style hex numbers, e.g., 0x1234.
(defun set-zero-x-reader (&optional (enable t))
(flet ((zero-x-reader (stream char)
(declare (ignore char))
;; Note that we lie about RECURSIVE-P to avoid EOF error signal.
(let ((c (peek-char nil stream nil nil nil)))
(cond
((null c)
0) ; EOF. Just return the 0.
((char-equal c #\x) ; "0x"?
(read-char stream t nil t) ; Eat the "x"
(let ((*read-base* #x10))
(read stream t nil t))) ; and read rest in hex.
((digit-char-p c *read-base*) ; Normal number?
(read stream t nil t)) ; Yes, just read.
((char-equal c #\.) ; "0.xyz" is number, too.
(read stream t nil t))
((alpha-char-p c) ; Funny symbol? Sorry.
(error "Can't handle token (#\0 ~s ...)" c))
(t ; Else prob. terminator
0))))) ; just return zero.
(if enable
(set-macro-character #\0 #'zero-x-reader t)
(set-syntax-from-char #\0 #\1)))) ; Revert to standard.
It has a couple of bugs[1], but it's generally solid enough that I
leave it enabled by default in the REPL, which makes it *much* easier
to cut & paste stuff from C environments.[2]
-Rob
[1] For example, it doesn't support symbols starting with "0",
which breaks the LTk socket protocol to its backend server,
so I have to disable it when using LTk.
[2] I have also previously mentioned the inverse, a FORMAT function
named |0X|, which does C-style hex output:
(defun \0x (stream arg colon-p at-sign-p &optional mincol padchar)
"Hexadecimal numeric printing for use with the FORMAT ~/.../ directive.
Outputs ARG to STREAM as \"~(0x~mincol,padX~)\" [default \"~(0x~8,'0X~)\"].
If COLON-P, the entire output will be capitalized instead of lowercased.
If AT-SIGN-P is true, the \"0x\" prefix will be suppressed."
(let* ((fmt1 "~~~:[~;:@~](~:[0x~;~]~~~:[8~;~:*~a~],'~:[0~;~:*~a~]x~~)")
(fmt2 (format nil fmt1 colon-p at-sign-p mincol padchar)))
(format stream fmt2 arg)))
Example:
(format t "~4/0x/~%" (+ 0x13 5))
0x0018
NIL
>
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607