anchor.diff:               (progn ,@body)
                ,r))))
   
  -;; programmer options
  -;;  backtracking
  -;;  value-returning
  -;;  errors
  -
  -(defvar *settings* '(:backtracking nil :value-returning t :errors t))
  -
   ;; 'interpreted' parsers, for dynamic calling at runtime
   ;; used as a fallback and for prototyping new parsers
   (defparameter interpreted-parsers (make-hash-table :test #'equalp))
   
  -;; parsers that serve as the first level of compilation, 
  +;; parsers that serve as the first level of compilation,
   ;; generates code to be inserted by a macro
   (defparameter compiled-parsers (make-hash-table :test #'equalp))
   
  -(defmacro define-parser (name ll &rest body)
  +(defmacro define-internal-parser (name ll &rest body)
     `(setf (gethash ',name interpreted-parsers)
  -         (lambda ,ll ,@body)))
  +         (defun ,name ,ll ,@body)))
   
   (defmacro define-compiled-parser (name ll &rest body)
     `(setf (gethash ',name compiled-parsers)
            (lambda ,ll ,@body)))
   
  -(defun dynamic-run (exp)
  -  (aif (and (listp exp) (gethash (car exp) interpreted-parsers))
  -       (apply it (cdr exp))
  -       (error "unexpected form: ~a" exp)))
  +(defmacro run-parser (data)
  +	(if (and (listp data) (eq (car data) 'quote))
  +		 (compile-parser (second data))
  +		 (with-gensyms (foo)
  +			`(let ((,foo ,data))
  +				 (apply (car ,foo) (cdr ,foo))))))
   
   (defun compile-parser (exp)
     (aif (and (listp exp) (gethash (car exp) compiled-parsers))
          (apply it (cdr exp))
          (error "unexpected form: ~a" exp)))
   
  -(defmacro insert-compiled (exp)
  -   (compile-parser exp))
  -
   (defmacro parse (string form)
     `(let* ((*source* ,string)
  -          (*source-length* 
  +          (*source-length*
                ,(if (stringp string) (length string) '(length *source*)))
             (*index* 0))
  -          (dynamic-run ',form)))
  -
  -(defmacro compiled-parse (string form)
  -  `(let* ((*source* ,string)
  -          (*source-length* 
  -             ,(if (stringp string) (length string) '(length *source*)))
  -          (*index* 0))
  -          (insert-compiled ,form)))
  -
  -;; name -> (lambda-list body)
  +          (run-parser ,form)))
  +
   (defparameter user-parsers (make-hash-table :test #'equalp))
   
   (defmacro defparser (name ll &rest body)
     `(setf (gethash ',name user-parsers)
            (list ,ll ,body)))
   
  -;; choice   ~ in the matching operation, returns the first form that consumes input
  -;; any      ~ matches zero or more of the next form
  -;; many     ~ matches one or more of the next form
  -;; one-of   ~ matches one character from the given string
  -;; none-of  ~ matches only if none of the chars in the string match
  +;; chr      ~ matches a single character
  +;; str      ~ explicitly matches a string
  +;; choice   ~ returns the first parser that succeeds
  +;; seq      ~ matches each form sequentially
  +;; any      ~ matches zero or more of the form
  +;; many     ~ matches one or more of the form
   ;; times    ~ parses x occurances of y
   ;; try      ~ returns a parsing result, no effect on the normal parser stack
   ;; optional ~ tries x, parses it on success, succeeds either way
  -;; seq      ~ matches each form sequentially, returns a list of forms or nil
  -;; str      ~ explicitly matches a string
   ;; sep      ~ seperates by repeated matching. mostly magic
  +;; one-of   ~ matches one character from the given string
  +;; none-of  ~ matches only if none of the chars in the string match
  +;; range    ~ matches a character numerically in a given range
   
   (defmacro test-remaining (n)
     `(>= *source-length* (+ *index* ,n)))
   
  -;; char
  -
  -(define-parser chr (char)
  +;; chr
  +
  +(define-internal-parser chr (char)
      (if (test-remaining 1)
          (if (eql (char *source* *index*) char)
  -           (pass char 1)
  -           (fail (string char) nil))
  -       (fail (string char) nil)))
  +           (succeed char 1)
  +           (fail (string char)))
  +       (fail (string char))))
   
   (define-compiled-parser chr (char)
     (with-gensyms (genchar)
  
positive.code: 
  (declaim (inline error?))
  (defstruct (parser-error (:conc-name error-) (:predicate error?))
     type index args)
  
  (defmacro pass (value n)
     `(progn (incf *index* ,n) ,value))
  
  (declaim (inline fail))
  (defun fail (type args &optional (index *index*))
     (make-parser-error :type type :args args :index index))
  
  (defmacro on-success (exp &rest body)
     (with-gensyms (r)
  
negative.code: 
  ;; many
  
  (define-internal-parser many (p)
     (iter (for r = (run-parser p))
           (until (error? r))
           (collect r into result)
           (finally (return (or result (fail 'many))))))
  
  (define-compiled-parser many (p)
     (with-gensyms (result list)
        `(iter (for ,result = ,(compile-parser p))
               (until (error? ,result))
               (collect ,result into ,list)
               (finally (return (or ,list ,result))))))
  
  ;; choice
  
  (define-internal-parser choice (&rest parsers)
     (iter (for parser in parsers)
           (for parser-result = (run-parser parser))
           (on-success parser-result (leave parser-result))
           (finally (return (fail 'choice)))))
  
  (define-compiled-parser choice (p &rest rest)
  	(if rest
  	  (with-gensyms (result)
  		`(let ((,result ,(compile-parser p)))
  			(if (error? ,result)
  				,(compile-parser `(choice ,@rest))
  				,result)))	  
       (with-gensyms (result)
  		`(let ((,result ,(compile-parser p)))
  			(if (error? ,result)
  				 (fail 'choice)
  				,result)))))
  
  ;; times
  
  (define-internal-parser times (n parser)
     (iter (repeat n)
           (for parse-result = (run-parser parser))
           (on-failure parse-result (leave parse-result))
           (collect parse-result into list)
           (finally (return list))))
  
  (define-compiled-parser times (n parser)
     (iter (repeat n)
           (for parse-result = (run-parser parser))
           (on-failure parse-result (leave parse-result))
           (collect parse-result into list)
           (finally (return list))))
  
  ;; optional
  
  (define-internal-parser optional (parser)
     (if (error? (run-parser (try parser)))
         nil
         (run-parser parser)))
  
  