summaryrefslogtreecommitdiff
path: root/util.lisp
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <matthias@benkard.de>2008-07-26 19:23:28 +0200
committerMatthias Andreas Benkard <matthias@benkard.de>2008-07-26 19:23:28 +0200
commit0f7abae8b9525d60685ae3b9ecc2fb4131c766a4 (patch)
tree252c9c9e8c211b2e96ce7a764eff36c579fa7e18 /util.lisp
parentac3c67818eaaf7e72e039bff93e4226f086b07e8 (diff)
Reader: Support quasiquotation.
Diffstat (limited to 'util.lisp')
-rw-r--r--util.lisp37
1 files changed, 37 insertions, 0 deletions
diff --git a/util.lisp b/util.lisp
index 50688a3..ca1b25a 100644
--- a/util.lisp
+++ b/util.lisp
@@ -134,3 +134,40 @@
(list 'quote (car this-clause))))
(cons 'progn (cdr this-clause))
(list* 'case object-sym rest)))))))
+
+(%defmacro* sys::quasiquote (object)
+ (if (not (consp object))
+ (list 'quote object)
+ (cond ((eq 'sys::unquote (car object)) (car (cdr object)))
+ ((eq 'sys::quasiquote (car object)) (list 'quote object))
+ ((and (consp (car object))
+ (eq 'sys::unquote-splicing (car (car object))))
+ (list 'append
+ (car (cdr (car object)))
+ (list 'sys::quasiquote (cdr object))))
+ (t (list 'cons
+ (list 'sys::quasiquote (car object))
+ (list 'sys::quasiquote (cdr object)))))))
+
+(%defun* list-eqp (list1 list2)
+ "Not really EQUALP (only works on trees of symbols)."
+ (if (and (consp list1) (consp list2))
+ (and (list-eqp (car list1) (car list2))
+ (list-eqp (cdr list1) (cdr list2)))
+ (eq list1 list2)))
+
+(%defun* macroexpand (object . rest)
+ (let* ((env (if rest (car rest) nil))
+ (expansion-1 (macroexpand-1 object env))
+ (expansion-2 (macroexpand-1 expansion-1 env)))
+ (if (list-eqp expansion-1 expansion-2)
+ expansion-1
+ (macroexpand expansion-2))))
+
+(%defun* macroexpand-all (object . rest)
+ (let* ((env (if rest (car rest) nil)))
+ (if (consp object)
+ (let ((expansion (macroexpand object env)))
+ (cons (macroexpand-all (car expansion))
+ (macroexpand-all (cdr expansion))))
+ object)))