anchor.diff:    (with-slots (string start end) context
       (destructuring-bind (min max body) (cdr form)
         (let* ((c (gensym (symbol-name :count-)))
  -             (new-context
  -               (make-context 'string-context
  -                             :gensym t
  -                             :chain context))
  -             (e (slot-value new-context 'start))
  +             (new-context (chain-context context))
  +             (retlist (chain-return-list new-context))
                (le (gensym (symbol-name :last-end-)))
  -             (tmp (gensym (symbol-name :temp-)))
                (v (gensym (symbol-name :val-))))
           (values
            `(do ((,c 0)
  -               (,e ,start)
  +               ,@(return-list-binding retlist context)
                  (,le ,(if (= 0 min)
                            start
                            nil))
  -               (,tmp nil)
                  (,v nil))
                 (,(if max
  -                    `(or (not ,e)
  +                    `(or (not ,(car retlist))
                            (>= ,c ,max))
  -                    `(not ,e))
  +                    `(not ,(car retlist)))
                  (when (>= ,c ,min)
                    (values ,le (reverse ,v))))
  -            (setf (values ,e ,tmp) ,(cpf body new-context env))
  -            (when ,e
  +            (setf (values ,@retlist) ,(cpf body new-context env))
  +            (when ,(car retlist)
                 (incf ,c)
  -              (setf ,le ,e)
  -              (push ,tmp ,v)))
  +              (setf ,le ,(car retlist))
  +              (push ,(second retlist) ,v)))
            t)))))
   
   (defrule test-repeat
  
positive.code:   (declare (ignore car))
    (unless (cdr form) ; style tweak, doesn't change runtime, mimics (cl:or)
      (return-from cpf-list nil))
    (with-slots (string start end) context
      (let* ((args (cdr form))
             (blocksym (gensym (symbol-name :or-)))
             (endsym (gensym (symbol-name :end-)))
             (valsym (gensym (symbol-name :val-)))
             (inner
              `(let* (,endsym ,valsym)))
             (last (last inner 1)))
        (dolist (f args)
          (pushback
           `(setf (values ,endsym ,valsym) ,(cpf f context env))
           last)
          (pushback
           `(when ,endsym
              (return-from ,blocksym (values ,endsym ,valsym)))
           last))
        `(block ,blocksym ,inner))))
  
  (defmethod cpf-list ((car (eql 'or>)) form context env)
    "return the rule that has the longest match"
    (declare (ignore car))
  
negative.code:                (string= prefix string :start2 start :end2 stop))
        (values stop prefix))))
  
  (defmethod cpf ((form string) (context string-context) env)
    (declare (ignore env))
    (values
     (with-slots (string start end) context
       `(starts-with ,string ,start ,end ,form))
     t))
  
  (defmethod cpf ((form string) (context array-context) env)
    (declare (ignore env))
    (values
     (with-slots (array start) context
       `(when (string= (aref ,array ,start) ,form)
          (values ,form (`+ ,start))))
     t))
  
  (defmethod cpf ((form character) (context string-context) env)
    (declare (ignore env))
    (values
     (with-slots (string start end) context
  