Include backquote without simplifications
authorDavid Vazquez <davazp@gmail.com>
Sun, 16 Dec 2012 15:32:12 +0000 (15:32 +0000)
committerDavid Vazquez <davazp@gmail.com>
Sun, 16 Dec 2012 15:32:12 +0000 (15:32 +0000)
backquote.lisp [new file with mode: 0644]

diff --git a/backquote.lisp b/backquote.lisp
new file mode 100644 (file)
index 0000000..508fc3f
--- /dev/null
@@ -0,0 +1,52 @@
+;;; A little backquote implementation without optimizations of any
+;;; kind for lispstrack.
+
+(defun backquote-expand-1 (form)
+  (cond
+    ((symbolp form)
+     (list 'quote form))
+    ((atom form)
+     form)
+    ((eq (car form) 'unquote)
+     (car form))
+    ((eq (car form) 'backquote)
+     (backquote-expand-1 (backquote-expand-1 (cadr form))))
+    (t
+     (cons 'append
+           (mapcar (lambda (s)
+                     (cond
+                       ((and (listp s) (eq (car s) 'unquote))
+                        (list 'list (cadr s)))
+                       ((and (listp s) (eq (car s) 'unquote-splicing))
+                        (cadr s))
+                       (t
+                        (list 'list (backquote-expand-1 s)))))
+                   form)))))
+
+(defun backquote-expand (form)
+  (if (and (listp form) (eq (car form) 'backquote))
+      (backquote-expand-1 (cadr form))
+      form))
+
+(defmacro backquote (form)
+  (backquote-expand-1 form))
+
+;;; Tests. Compare backquote agains the backquote of the host Lisp.
+(macrolet ((test (form1 form2)
+             `(assert (equal ,form1 ,form2))))
+  (test (backquote (1 2 3 4))
+        `(1 2 3 4))
+  (test (backquote (1 2 (+ 3 4)))
+        `(1 2 (+ 3 4)))
+  (test (backquote (1 2 (unquote (+ 3 4))))
+        `(1 2 ,(+ 3 4)))
+  (test (backquote (1 2 (unquote-splicing '(3 4))))
+        `(1 2 ,@'(3 4)))
+  (test (backquote (backquote x))
+        ``x)
+  (let ((x 10))
+    (test `',x
+          (backquote (quote (unquote x)))))
+  (let ((x 10))
+    (test (eval ``(,,x))
+          (eval (backquote (backquote ((unquote (unquote x)))))))))