anchor.diff:    (with-slots (string start end) context
       (destructuring-bind (min max body) (cdr form)
         (let* ((c (gensym (symbol-name :count-)))
  -             (e (gensym (symbol-name :end-)))
  +             (new-context
  +               (make-context 'string-context
  +                             :gensym t
  +                             :chain context))
  +             (e (slot-value new-context 'start))
                (le (gensym (symbol-name :last-end-)))
                (tmp (gensym (symbol-name :temp-)))
  -             (v (gensym (symbol-name :val-)))
  -             (new-context
  -              (make-instance 'string-context
  -                             :string string
  -                             :start e
  -                             :end end)))
  +             (v (gensym (symbol-name :val-))))
           (values
            `(do ((,c 0)
                  (,e ,start)
  
positive.code:  (name) -> `(funcall (car ,(lookup-rule name) string start end))
  |#
  
  (defmacro defrule (name &body parse-form &environment env)
    (assert (= (length parse-form) 1))
    `(defun ,name (string &optional (start 0) (end (length string)))
         ,(cpf (car parse-form) (make-instance 'string-context :string 'string :start 'start :end 'end) env)))
  
  ;; work on a protocol for defrule, allowing compile-time dispatch
  (defvar *parse-rules* (make-hash-table)
  
negative.code:       (pushback `(values ,endsym (cdr ,listsym))
                  last)
        `(block ,blocksym ,inner))))
  
  
  (defrule test-and0 (and "hi" (and)))
  
  