[quiz] Enhanced Strings in CL ?
Pascal Bourguignon
pjb at informatimago.com
Tue Nov 28 19:19:00 UTC 2006
Laurent PETIT writes:
> Hello Quizzers,
>
> I'm a newbie in Lisp (have already finished the ANSI Common Lisp book, made
> some tries with programming as well, and I'm searching the answer to this
> question I have : could it be possible to "enhance" the reader in order to
> have in lisp "enhanced strings".
>
> That is : by just doing something once at the beginning of a lisp file (some
> call, ...), being able to have all the strings replaced by another string
> (or another form).
>
> Something like this :
>
> ;;; beginning of file
>
> (enhanced-strings:start)
>
> ...
> ...
>
> (defun some-function (x y)
> "This returned string is an enhanced string and the value of x and y will
> be replaced 'a la ruby' : x=${x}, y =${y}")
>
> You see what I mean ....
>
> This could be an interesting quiz,
No, it's trivial.
(defpackage "ENHANCED-STRINGS"
(:USE "COMMON-LISP")
(:EXPORT "START"))
(in-package "ENHANCED-STRINGS")
(defun parse-enhanced-string (string)
(loop
:with chunks = '()
:with args = '()
:with start = 0
:for pos = (search "${" string :start2 start)
:for end = (and pos (search "}" string :start2 pos))
:while end
:do (progn
(push (subseq string start pos) chunks)
(multiple-value-bind (form next)
(read-from-string string t nil :start (+ 2 pos) :end end)
(loop :while (and (< next end)
(member (aref string next) '(#\space #\newline)))
:do (incf next))
(unless (= next end)
(error "Junk in ~S" (subseq string pos end)))
(push form args))
(setf start (1+ end)))
:finally (progn
(push (subseq string start) chunks)
(return (cons (format nil "~{~A~^~~A~}" (nreverse chunks))
(nreverse args))))))
(defun reader-macro--enhanced-string (stream dblquote)
(let ((*readtable* (copy-readtable nil)))
(unread-char dblquote stream)
`(format nil ,@(parse-enhanced-string (read stream t nil t)))))
(defun start ()
(set-macro-character #\" (function reader-macro--enhanced-string)))
(start)
'"This returned string is an enhanced string and the value of x and y will
be replaced 'a la ruby' : x=${(* 42 x)}, y =${y}"
-->
(format nil
"This returned string is an enhanced string and the value of x and y will
be replaced 'a la ruby' : x=~A, y =~A"
(* 42 x) y)
See also: http://www.cliki.net/cl-interpol
> but first of all, will an ANSI compliant
> implementation let redefine the reader to alter the meaning of strings ?
Yes.
> I know I can add macro characters, play with macro character dispatching
> functions, ... but what about "overriding" the reader to intercept strings
> and change them, as for the above example, with :
What about SET-MACRO-CHARACTER and SET-DISPATCH-MACRO-CHARACTER ?
Do you need instructions on how to search CLHS?
--
__Pascal Bourguignon__ http://www.informatimago.com/
Litter box not here.
You must have moved it again.
I'll poop in the sink.
More information about the Quiz
mailing list