I’m trying to write a Lisp macro that writes a bunch of macros, but I’m having problems generating macro code that uses the splice operator (in build-bind) that expands inside expressions first.
(defmacro define-term-construct (name filter-p list-keywords)
(let* ((do-list-name (output-symbol "do-~a-list" name))
(with-name (output-symbol "with-~a" name))
(do-filter-name (output-symbol "do-~as" name)))
`(progn
(defmacro ,do-list-name
(ls (&key ,@(append list-keywords '(id operation))) &body body)
(with-gensyms (el)
`(loop-list (,el ,ls :id ,id :operation ,operation)
(let (XXX,@(build-bind ,,name ,el))
(when (,',filter-p ,el)
(,',with-name ,el
,@body)))))))))
After the first pass I want to get:
(define-term-construct some some-p (args name))
->
(PROGN
(DEFMACRO DO-SOME-LIST (LS (&KEY ARGS NAME ID OPERATION) &BODY BODY)
(WITH-GENSYMS (EL)
`(LOOP-LIST (,EL ,LS :ID ,ID :OPERATION ,OPERATION)
(LET (,@(BUILD-BIND ,SOME ,EL))
(WHEN (SOME-P ,EL)
(WITH-SOME ,EL
,@BODY)))))))
Any idea what quote/quasiquotes should I use to get the desired code?
The output that you say that you want want to get has unbalanced commas.
,@already balances the backquote, so you cannot have,SOMEand,EL. That’s two levels of unquoting/splicing inside only one level of backquoting.I suspect you want:
The
somesymbol comes in as an argument to the original macro and has to end up as a quoted symbol when passed to thebuild-bindfunction. TheELis evaluated straight. It’s just a local variable introduced by theWITH-GENSYMSbinding construct, and it is not in backquote context anymore because it is inside the splice.Transliterating that back to the the original outer macro’s backquote:
SOMEbecomes,name:The symbol is spliced in under the umbrella of a protecting quote which will make sure it is treated as a symbol and not a variable.
The
eldoes not need to be spliced in; it’s not variable material but a hard-coded feature of the template being generated. If you were to put,elit would look for anelvariable in thedefine-term-constructmacro’s scope, where no such thing exists.