Subject: Re: Small read macro issue
From: Erik Naggum <erik@naggum.no>
Date: 07 Oct 2002 15:50:56 +0000
Newsgroups: comp.lang.lisp
Message-ID: <3242994656390587@naggum.no>

* Adam Warner
| I'm just a little stuck on how to turn this syntax:
| 
| (function-name[some text]"more text")
| 
| Into this syntax:
| 
| (function-name :options "[some text]" "more text")

  That is the wrong goal.

| This allows me to distinguish whether an initial optional string has been
| input.

  So you need a mechanism to distinguish them, not an answer to what you
  are asking for.

| Otherwise there is no way to distinguish between these situations:
| 
| (function-name "options" "text1" "text2" ...)
| (function-name "text1" "text2" ...)
| 
| (Note: I am unaware of any way to attach a particular type to the initial
| optional string so that it can be tested for as different to a regular
| string).

  A wrapper class.  The solution is so close you have probably overlooked it.

(defclass warner-option ()
  ((option :type string :reader warner-option :initarg :option)))

;; useful for debugging
(defmethod print-object ((option warner-option) stream)
  (print-unreadable-object (option stream :type t)
    (prin1 (warner-option option) stream)))

(defun option-reader (in char)
  (declare (ignore char))
  (prog1
      (make-instance 'warner-option
        :option (with-output-to-string (out)
                  (peek-char #\] (make-echo-stream in out))))
    (read-char in)))

#| ;; or if you really want the [] with the string:
(defun option-reader (in char)
  (make-instance 'warner-option
    :option (with-output-to-string (out)
              (unread-char char in)
              (with-open-stream (in (make-echo-stream in out))
                (peek-char #\] in)
                (read-char in)))))
|#

(set-macro-character #\[ 'option-reader)

  Now, reading this:

(function-name[some text]"more text")

  causes this to be returned:

(function-name #<warner-option "some text"> "more text")

  You can now distinguish the option string from other strings.

-- 
Erik Naggum, Oslo, Norway

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.