2

@this を「this」に変換するリーダー マクロを作成しようとしています。これは私が現在持っているものです:

(defun string-reader (stream char)
   (declare (ignore char))
   (format nil "\"~a\"" (read-line stream t nil t))   
)    
(set-macro-character #\@ #'string-reader )

問題は、@this の後に改行を入れる必要があることです。私も (read) で試してみましたが、それは設定されていない変数 test を返すだけです。@ 記号の後の文字数をハードコードすることはできません。何文字になるか分からないからです。これを修正する方法はありますか?

編集: read-char と peek-char をループして、#)、#\space、または #\Newline に到達するまで読み取る唯一の方法ですか?

4

1 に答える 1

3

使用readしてみて、返されるものを確認できます。

(defun string-reader (stream char)
   (declare (ignore char))
   (let ((this (let ((*readtable* (copy-readtable)))
                 (setf (readtable-case *readtable*) :preserve)
                 (read stream t nil t))))
     (etypecase this
       (string this)
       (symbol (symbol-name this)))))

(set-macro-character #\@ #'string-reader)

上記では and は許可されますが、 は許可@Thisされ@"This"ません@333

このバージョンは、空白まで文字列を読み取るだけです:

(defun read-as-string-until-whitespace (stream)
  (with-output-to-string (out-stream)
    (loop for next = (peek-char nil stream t nil t)
          until (member next '(#\space #\newline #\tab))
          do (write-char (read-char stream t nil t) out-stream))))

(defun string-reader (stream char)
   (declare (ignore char))
   (read-as-string-until-whitespace stream))

(set-macro-character #\@ #'string-reader)

例:

CL-USER 21 > @this
"this"

CL-USER 22 > @42
"42"

CL-USER 23 > @FooBar
"FooBar"
于 2015-06-19T17:23:43.397 に答える