anchor.diff:      ("@" (expand-quote reader))
       (t (read-atom reader))))
   
  +(defun read-form-or-eof (reader context)
  +  (or (read-form reader)
  +      (error 'eof :context context)))
  +
   (defun read-str (string)
     (read-form (make-token-reader :tokens (tokenize string))))
  
positive.code:                                       ("@" "deref")))))
      (make-mal-list (list quote-sym (read-form reader)))))
  
  (defun read-mal-sequence (reader &optional (delimiter ")") (constructor 'list))
    ;; Consume the opening brace
    (consume reader)
    (let (forms)
      (loop
         for token = (peek reader)
         while (cond
                 ((null token) (error 'eof :context (if (string= delimiter ")")
                                                        "list"
                                                        "vector")))
                 ((string= token delimiter) (return))
                 (t (push (read-form reader) forms))))
      ;; Consume the closing brace
      (consume reader)
      (apply constructor (nreverse forms))))
  
  (defun read-hash-map (reader)
    ;; Consume the open brace
    (consume reader)
    (let (forms
          (hash-map (types:make-mal-value-hash-table)))
      (loop
         for token = (peek reader)
         while (cond
                 ((null token) (error 'eof :context "hash-map"))
                 ((string= token "}") (return))
                 (t (let ((key (read-form reader))
                          (value (read-form reader)))
                      (if (null value)
                          (error 'eof :context "hash-map")
                          (push (cons key value) forms))))))
      ;; Consume the closing brace
      (consume reader)
      ;; Construct the hash table
      (dolist (key-value (nreverse forms))
        (setf (genhash:hashref (car key-value) hash-map) (cdr key-value)))
      hash-map))
  
  (defun read-atom (reader)
    (let ((token (next reader)))
      (cond
        ((string= token "false")
         mal-false)
        ((string= token "true")
         mal-true)
        ((string= token "nil")
         mal-nil)
        ((char= (char token 0) #\")
         (make-mal-string (parse-string token)))
        ((char= (char token 0) #\:)
         (make-mal-keyword token))
        ((scan *number-re* token)
         (make-mal-number (read-from-string token)))
        (t (make-mal-symbol token)))))
  
  (defun read-form (reader)
    (switch ((peek reader) :test #'equal)
      (nil nil)
      ("(" (make-mal-list (read-mal-sequence reader ")" 'list)))
      ("[" (make-mal-vector (read-mal-sequence reader "]" 'vector)))
      ("{" (make-mal-hash-map (read-hash-map reader)))
      ("^" (read-form-with-meta reader))
      ("'" (expand-quote reader))
  
negative.code:   ((context :initarg :context :reader context))
    (:report (lambda (condition stream)
               (format stream
                       "EOF encountered while reading '~a'"
                       (context condition))))
    (:documentation "Error raised when EOF is encountered while reading."))
  
  