Damien Kick <dkixk@earthlink.net> wrote:
+---------------
| Rob Warnock wrote:
| > O.k., here's a partial repost from what I wrote two weeks ago.
| > First a utility function from my standard personal toolbox:
| >
| > (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)))
|
| I'm not sure if this feeling I'm feeling is awe, fear, or nausea.
+---------------
Come on, CL isn't Scheme, you know!! Neither fear nor nausea is called
for. I do lots of hardware debugging and need to be able to show co-workers
dumps they can read... and none of them read Lisp but thay *all* read C.
Hence a "0" readmacro [so #x123 can be typed in as 0x123] and a "~/0x/"
FORMAT function so when I'm peeking & poking hardware things look like
a C or Tcl programmer expects them to... mostly:
$ opfr
opfr> deflex foo "abcde"
FOO
opfr> d32 foo
0x48039998: 0x0000002a 0x00000014 0x64636261 0x00000065
0x480399a8: 0x4803999f 0x28f0000b 0x4803999f 0x48039993
0x480399b8: 0x4803999f 0x28f0000b 0x4803996f 0x480399bb
0x480399c8: 0x48bb1f97 0x480399c3 0x480399cb 0x480399db
opfr>
Which, being decoded, is:
+-- CMUCL's heap type tag for SIMPLE-BASE-STRING
| +-- (LENGTH "abcde") as a FIXNUM
| | [Hint: What is (ASH #x14 -2)?
| | ___ The string ___
| | / [Little-Endian] \
0x48039998: 0x0000002a 0x00000014 0x64636261 0x00000065
Now let's get *really* nasty!! ;-} ;-}
opfr> code-char (r8 (+ 0x48039998 10))
#\c
opfr> w8 (+ 0x48039998 10) (char-code #\C) (char-code #\D)
hwtool> foo
"abCDe"
opfr>
-Rob
[1] OPFR == "Outer-Parenthesis-Free REPL", a trivial wrapper
around a CL REPL that gives it a Tcl-like flavor as long
as you're only typing pre-defined functions, variables,
and literals. And, yes, once you have any sub-expressions
the underlying Lisp shows through. Turns out not to be a
biggy, as long as the top-level is paren-free. [I have written
of the phenomenon at length previously. Google is your friend.]
[2] Yes, I know I'm illegally modifying a literal. It's just a
quick example. But if you like, replace the first line with:
deflex foo (copy-seq "abcde")
[3] Here's the D32 function [slightly trimmed]:
(defun d32 (addr &optional (len #x40) (print-addr addr))
...[a bunch of error-checking & argument coercion elided,
following which ADDR is now an 8-byte-aligned memory address]...
(loop for i from 0 by 16 below len do
(format t "~2/0x/:" (+ print-addr i))
(loop for j from i by 4 below (min len (+ i 16)) do
(format t " ~/0x/" (r32 (+ addr j))))
(format t "~%"))
(values)) ; suppress ugly "NIL"
Yes, the "~2/0x/" could be written as "~(0x~2,'0x~)" and the
"~/0x/" as ~(0x~8,'0x~)", but I type a lot of one-off hex-output
FORMATs at the REPL, too, and "~/0x/" is just easier.
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607