Macros 我可以区分字符串文字参数和计算结果为字符串的参数吗?

Macros 我可以区分字符串文字参数和计算结果为字符串的参数吗?,macros,common-lisp,argument-passing,Macros,Common Lisp,Argument Passing,我正在创建一种特定于领域的语言。其中一个宏调用如下所示: (我的宏foo(bar“baz”qux)yay) 按照我编写宏的方式,这里的第二个参数应该是一对括号内的字符串列表。因此,只要bar和qux计算为字符串,我的宏就可以工作。让我们假设它们以“bar”和“qux”的名称进行计算,我的宏将第二个参数视为“bar baz qux” 但现在我意识到我真的希望“baz”保留它的引用;我希望我的宏将第二个参数视为“bar\”baz\“qux”。这可能吗?在我的宏中,当我需要加回双引号时,我能告诉我什么

我正在创建一种特定于领域的语言。其中一个宏调用如下所示:

(我的宏foo(bar“baz”qux)yay)

按照我编写宏的方式,这里的第二个参数应该是一对括号内的字符串列表。因此,只要bar和qux计算为字符串,我的宏就可以工作。让我们假设它们以“bar”和“qux”的名称进行计算,我的宏将第二个参数视为“bar baz qux”

但现在我意识到我真的希望“baz”保留它的引用;我希望我的宏将第二个参数视为“bar\”baz\“qux”。这可能吗?在我的宏中,当我需要加回双引号时,我能告诉我什么时候可以按原样使用字符串吗


提前谢谢

要将第二个参数视为字符串,只需将其写入字符串即可,如下所示:

(defmacro my-macro (arg1 (&rest arg2) arg3)
  (list arg1 (write-to-string arg2 :case :downcase) arg3)) 

(macroexpand '(my-macro foo (bar "baz" qux) yay))

=>
(FOO”(bar“baz”qux)“YAY)

将符号FOO、列表(bar“baz”qux)和符号YAY作为参数传递给宏。如果要查看第二个参数中的任何元素是否为字符串,请在宏定义中使用类似于
stringp
的内容来测试该参数


您的宏完全控制评估在生成的宏扩展中的工作方式。它看到它的所有参数都未被评估。如果您想了解作为参数传递的未计算代码,请查看它。

宏可以在扩展时测试其参数的类型。例如,此宏将根据参数是否为字符串创建不同的代码:

(defmacro my-macro (arg) 
  (if (stringp arg)
     (format nil "\"~a\"" arg)
     `(format nil "~a" ,arg)))
测试:

=>
“baz\”

=>
“字符串”

请注意,如果参数不是字符串,则宏将展开为以下形式:

(macroexpand '(my-macro evals-to-a-string))

=>
(格式为nil”~a“evals-to-a-string)

,但我看得不正确:(defmacro my macro(arg);(if(stringp,arg)(格式为nil”~a\,arg)(格式为nil”~a“,arg))(我的宏“baz”)=>“baz\”(macroexpand(我的宏evals-to-a-string))=>“a-string”我希望第二个计算为“字符串”,不要返回执行stringp检查的代码,直接执行stringp检查。(defmacro my macro(arg)(if(stringp arg)arg…)@terje norderhaug唉,我希望bar和qux进行计算,“baz”保持一个带引号的字符串。此外,带引号的字符串可以出现在arg2中的任何位置。。。
(let ((evals-to-a-string "a string"))
  (my-macro evals-to-a-string))
(macroexpand '(my-macro evals-to-a-string))