anchor.diff:  (in-package destr-match)
   
   ;; TODO
  -;; [x] MAKE THE PACKAGE NAME MATCH THE SYSTEM NAME
  -;; [x] neat switch macro
  -;; [ ] fill out the README with examples and documentation
  -;; [ ] sublists?
  -;; [x] make special parsing for single inside test and key
  -;; [x] make switch (list) raw forms, so everything still works
  +;; [w] fill out the README with examples and documentation
  +;; [w] sublists
   ;; [ ] modify match so clause names without arguments are bindings
  -;; [ ] full literal value matching, using quotes for symbols?
  -;; [ ] fix indentation and maybe line length
  +;; [?] full literal value matching, using quotes for symbols
  +;; [w] fix indentation and maybe line length
  +;; [w] single/multiple modes
  +;; [w] make the variables update during matching
  +;; [?] scan for free symbols in normal expressions, like (member foo '(bar baz)) 
  +;;       would need some way of detecting already-bound local variables? 
  +;; [?] optimize matching more
  +;; [ ] another layer of expansion so you can overload macro names
   
   (defparameter destr-match-clauses (make-hash-table :test #'equalp))
   (defparameter matching-style 'symbol) ;; symbol, string, case-sensitive, regex, symbol-regex
  +(defparameter single-mode t)
   
   (defmacro def-match-clause (name ll &rest rest)
      `(setf (gethash ,(string name) destr-match-clauses) (lambda ,ll ,@rest)))
  
positive.code: 
  (defun test-single (var rest end)
     (if end
         `(when (and (car list) (funcall ,(second var) (car list)))
                (setf ,(second (first var)) (car list))
                (not (cdr list)))
         `(when (and (car list) (funcall ,(second var) (car list)))
                (setf ,(second (first var)) (car list))
                (let ((list (cdr list)))
                      (match ,rest)))))
  
  (def-match-clause test (var rest end)
     (if (and (listp (first var)) (symbol-eq (car (first var)) 'single))
         (test-single var rest end)
     (if end
        `(when (and list (funcall ,(second var) list)) (setf ,(first var) list) t)
         (with-gensyms (v x w r loop succeed fail end)
           `(let ((,v (list (car list))) (,x (cdr list)) (,w nil) (,r nil))
                  (tagbody
                    ,loop
                       (when (not ,x) (go ,fail))
                       (setf ,w (let ((list ,x)) (match ,rest)))
                       (when (and (eq ,w t) (funcall ,(second var) ,v)) (go ,succeed))
                       (appendf ,v (list (car ,x)))
                       (setf ,x (cdr ,x))
                       (go ,loop)
                    ,fail
                       (setf ,(car var) nil)
                       (setf ,r nil)
                       (go ,end)
                    ,succeed
                       (setf ,(car var) ,v)
                       (setf ,r ,w)
                    ,end)
                  ,r)))))
  
  (defun key-single (var rest end)
     (if end
  
negative.code:       (otherwise       (error "something went very wrong"))))
  
  (defun generate-match-code (exp end)
    `(when (and list ,(match-test (car exp)))
          ,(if end 't
             `(let ((list (cdr list)))
                    (match ,(cdr exp))))))
  
  (defun generate-atom-code (exp end)
    `(when (and list (equalp ,(car exp) (car list)))
          ,(if end 't
             `(let ((list (cdr list)))
                    (match ,(cdr exp))))))
  
  ;; here be dragons
  (defun generate-bind-body (sym rest type &optional fun)
     (if single-mode
         nil
         (with-gensyms (x w r f loop succeed fail end)
           `(let ((,x (cdr list)) (,w nil) (,r nil))
                  (setf ,sym (list (car list)))
                  (tagbody
                    ,loop
                        (when (not ,x) (go ,fail))
                        (setf ,w (let ((list ,x)) (match ,rest)))
                       ,(case type
                           (normal `(when (eq ,w t) (go ,succeed)))
                           (test   `(when (and (eq ,w t) (funcall ,fun ,sym)) (go ,succeed)))
                           (key    `(let ((,f (funcall ,fun ,sym)))
                                          (when (and (eq ,w t) ,f)
                                                (setf ,sym ,f) (go ,succeed)))))
                        (appendf ,sym (list (car ,x)))
                        (setf ,x (cdr ,x))
                        (go ,loop)
                    ,fail
                        (setf ,sym nil)
                        (setf ,r nil)
                        (go ,end)
                    ,succeed
                        (setf ,r ,w)
                    ,end)
                 ,r))))
  
  (defun generate-bind-code (exp end)
     (if end
        `(when list (setf ,(car exp) list) t)
         (generate-bind-body (car exp) (cdr exp) 'normal)))
  
  (defmacro match (exp)
     (let ((end-of-chain? (not (cdr exp))))
  