Common Lisp syntax extensions with quasi-quote
Ever wanted to generate something where you have constant and dynamically generated parts interleaved? cl-quasi-quote provides a framework for such syntaxes and transformations, and also implements a few (e.g. XML and JavaScript) out of the box. But this small code fragment illustrates what the project is aiming at, and code speaks better than a million words anyway, so:
;; Note: 「 and 」 are two unicode characters installed on a reader in the QQT package ;; that unconditionally reads its body into a string. It comes pretty handy in the ;; testsuite, which is full of string quoting, to avoid the headache of escaping... (bind ((code-as-string 「<body ,(string-upcase "some runtime generated <escaped> text") `str("***<unescaped text 1>***") ;; let's mix in some JavaScript here, with an unquoted part: `js(print (+ 2 ,(+ 20 20)) `str("***<unescaped text 2>***"))>」)) (pprint/xml+js code-as-string t) (emit/xml+js code-as-string))
;; the generated code (somewhat formatted and lowercased for readability) (progn (write-string "<body> " *xml+js-stream*) (write-quasi-quoted-string (bind ((*transformation* [XML->String])) (bind ((*xml-indent-level* (+ *xml-indent-level* 1))) (transform-quasi-quoted-xml-to-quasi-quoted-string/element (string-upcase "some runtime generated <escaped> text")))) *xml+js-stream*) (write-string "***<unescaped text 1>*** <script> // <![CDATA[ print(2 + " *xml+js-stream*) (write-quasi-quoted-string (bind ((*transformation* [JS->String])) (bind ((*in-js-statement-context* nil) (*js-operator-precedence* 7) (*js-indent-level* (+ *js-indent-level* 0))) (transform-quasi-quoted-js-to-quasi-quoted-string (+ 20 20)))) *xml+js-stream*) (write-string ", ***<unescaped text 2>***) // ]]> </script> </body> " *xml+js-stream*) +void+)
;; the output of the generated code when run "<body> SOME RUNTIME GENERATED <ESCAPED> TEXT***<unescaped text 1>*** <script> // <![CDATA[ print(2 + 40, ***<unescaped text 2>***) // ]]> </script> </body> "Click there for more repl examples, or you can check out the unit tests in the darcs repo for even more gory details. This site is most probably lagging behind the code (as most handwritten documentations do).
For demonstrational (end experimentational) purposes we've created a CLOS class inspector using cl-quasi-quote and UCW.
You can browse the cl-quasi-quote darcs repository or get the tree with
darcs get --partial http://common-lisp.net/project/cl-quasi-quote/darcs/cl-quasi-quote
BSD / Public Domain