Kaz Kylheku <kkylheku@gmail.com> wrote:
+---------------
| ["Followup-To:" header set to comp.lang.lisp.]
| On 2008-11-20, Rob Warnock <rpw3@rpw3.org> wrote:
| > (let* ((fmt1 "~~~:[~;:@~](~:[0x~;~]~~~:[8~;~:*~a~],'~:[0~;~:*~a~]x~~)")
| > (fmt2 (format nil fmt1 colon-p at-sign-p mincol padchar)))
| > (format stream fmt2 arg)))
|
| You might be interested in an S-exp to format string translator that I
| developed.
|
| Your string is a bit hard to understand; it took a while to reverse
| engineer it and render it to my syntax, but here goes: ...
...
| The output string is:
| "~~~:[~;@~](~:[0x~;~]~~~:[8~;~:*~A~],'~:[0~;~:*~A~]x~~)"
| ^
| \ here is a small difference from yours.
| You used a :; separator in conjunction with ~:[ which is useless.
| The :; separator is used to indicate a default case in enumerations.
| Booleans don't have a default case; it's just true and false.
| You should probaby avoid this construction in the interest of portability;
| the CLHS doesn't document the combination of ~:[ and ;:.
+---------------
Please look again!! *VERY CLOSELY!!* Here, I'll extract the relevant bit:
~:[~;:@~]
Please notice that I didn't *use* a "~:;" separator!! I used a "~;"
separator, exactly what is supposed to be used for boolean conditionals.
The ":" that is confusing you is a literal ":" *after* the "~;" that
is emitted (along with an "@" character) when the conditional is true.
For others trying to follow along here, note that the alternate
(false branch) is empty. Only the consequent (true branch) outputs
anything here, the string ":@". The purpose of this bit is to pass
the COLON-P argument to |0X| ["capitalize the output"] on to the
generated "~(" directive, that is, emit "~:@(" if COLON-P is true
and plain "~(" if not. I suppose could have replaced the whole ugly
"~:[~;:@~]" conditional FORMAT directive above with simply "~a", by
replacing the COLON-P argument in the first following FORMAT with:
(if colon-p "~:@(" "~(")
The ugly conditional FORMAT directive just pushes that IF down into
the FMT1 string.
-Rob
p.s. Yes, I'll freely admit that the format string in |0X| is
"hard to understand" (Kaz was being kind, actually!) -- it was
certainly hard for me to write (clearly "write once/read never"
code!!). But it only had to be written once, since the |0X| function
is buried deep in my UTILS package. In fact, I haven't ever needed
to read it again in the year and a half since it was first written,
until now.
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607