反引用字符串插值

时间:2015-06-12 16:15:12

标签: macros lisp common-lisp

是否可以使用lisp的宏进行字符串插值?

例如,我可以制作这样的宏:

(defmacro test (a) `",a")

这样(测试abc)将“abc”作为字符串返回?我可以通过引用它并将该引号转换为字符串来作弊,但这不适用于像“9:00”这样的参数(没有双引号)。

3 个答案:

答案 0 :(得分:3)

反对,无论是否在宏观中,都不会这样做:

[1]> (defmacro test (a) `",a")
TEST
[2]> (test oh-no)
",a"

您可以使用format,如下所示:

[3]> (defun interp (name) (format nil "Hi, my name is ~A" name))
INTERP
[4]> (interp "Steve")
"Hi, my name is Steve"

答案 1 :(得分:3)

Lisp宏对lisp读者已经读过的参数进行操作。因为宏不能改变它的参数读取方式,并且如果你传递一个参数,当你试图读取它时会发出错误信号,例如9:00中的(test 9:00),读者会在宏开始运行之前发出错误信号。

读者也可以自定义。不能让您以简单的方式阅读9:00 "9:00",但是例如,您可以编写一个简短的阅读器宏,将@9:00读为"9:00"或作为约会对象。

编辑:这样的事情:

(defvar *arguments-rt* (copy-readtable ()))

(defun timestring-reader (stream char &optional count)
  (declare (ignore char count))
  (with-output-to-string (s)
    (loop repeat 4 do (write-char (read-char stream) s))))

(set-macro-character #\@ #'timestring-reader () *arguments-rt*)

(let ((*readtable* *arguments-rt*))
  (let ((args "dinner @9:00"))
    (with-input-from-string (stream args)
      (loop for arg = (read stream () ())
            while arg collect arg))))

-> (DINNER "9:00")

答案 2 :(得分:2)

对于字符串插值,请参阅format。例如。 (format nil "~a" a)做你想做的事。在Practical Common Lisp中有一些format recipes

quasiquote和unquote 仅适用于列表,而不适用于其他序列。

宏是代码的转换..它不是运行时发生的事情。例如。如果你有(my-macro x)之类的代码,其中x在运行时将是一个字符串,宏只能看到符号。它无法知道它在扩展时的类型。