0.8.12.3:
[sbcl.git] / src / code / reader.lisp
index afb6909..0f2df53 100644 (file)
                   +char-attr-whitespace+)
               (done-with-fast-read-char)
               char)))
-       ;; fundamental-stream
+       ;; CLOS stream
        (do ((attribute-table (character-attribute-table *readtable*))
-            (char (stream-read-char stream) (stream-read-char stream)))
+            (char (read-char stream nil :eof) (read-char stream nil :eof)))
            ((or (eq char :eof)
                 (/= (the fixnum (aref attribute-table (char-code char)))
                     +char-attr-whitespace+))
   (let ((*readtable* *standard-readtable*))
 
     (flet ((whitespaceify (char)
+            (set-cmt-entry char nil)
             (set-cat-entry char +char-attr-whitespace+)))
       (whitespaceify (code-char tab-char-code))
       (whitespaceify #\linefeed)
       (whitespaceify (code-char return-char-code)))
 
     (set-cat-entry #\\ +char-attr-escape+)
-    (set-cmt-entry #\\ #'read-token)
+    (set-cmt-entry #\\ nil)
 
     ;; Easy macro-character definitions are in this source file.
     (set-macro-character #\" #'read-string)
        ((= ichar #O200))
       (setq char (code-char ichar))
       (when (constituentp char *standard-readtable*)
-           (set-cat-entry char (get-secondary-attribute char))
-           (set-cmt-entry char nil)))))
+       (set-cat-entry char (get-secondary-attribute char))
+       (set-cmt-entry char nil)))))
 \f
 ;;;; implementation of the read buffer
 
                     (fast-read-char nil nil)))
              ((or (not char) (char= char #\newline))
               (done-with-fast-read-char))))
-       ;; FUNDAMENTAL-STREAM
-       (do ((char (stream-read-char stream) (stream-read-char stream)))
+       ;; CLOS stream
+       (do ((char (read-char stream nil :eof) (read-char stream nil :eof)))
            ((or (eq char :eof) (char= char #\newline))))))
   ;; Don't return anything.
   (values))
               (done-with-fast-read-char))
            (if (escapep char) (setq char (fast-read-char t)))
            (ouch-read-buffer char)))
-       ;; FUNDAMENTAL-STREAM
-       (do ((char (stream-read-char stream) (stream-read-char stream)))
+       ;; CLOS stream
+       (do ((char (read-char stream nil :eof) (read-char stream nil :eof)))
            ((or (eq char :eof) (char= char closech))
             (if (eq char :eof)
                 (error 'end-of-file :stream stream)))
          (when (escapep char)
-           (setq char (stream-read-char stream))
+           (setq char (read-char stream nil :eof))
            (if (eq char :eof)
                (error 'end-of-file :stream stream)))
          (ouch-read-buffer char))))
         +char-attr-delimiter+
         (if (digit-char-p ,char (max *read-base* 10))
             (if (digit-char-p ,char *read-base*)
-                +char-attr-constituent-digit+
-                +char-attr-constituent+)
+                (if (= att +char-attr-constituent-expt+)
+                    +char-attr-constituent-digit-or-expt+
+                    +char-attr-constituent-digit+)
+                +char-attr-constituent-decimal-digit+)
             att))))
 \f
 ;;;; token fetching
        (package-designator nil)
        (colons 0)
        (possibly-rational t)
+       (seen-digit-or-expt nil)
        (possibly-float t)
+       (was-possibly-float nil)
        (escapes ())
        (seen-multiple-escapes nil))
     (reset-read-buffer)
       (case (char-class3 char attribute-table)
        (#.+char-attr-constituent-sign+ (go SIGN))
        (#.+char-attr-constituent-digit+ (go LEFTDIGIT))
+       (#.+char-attr-constituent-digit-or-expt+
+        (setq seen-digit-or-expt t)
+        (go LEFTDIGIT))
+       (#.+char-attr-constituent-decimal-digit+ (go LEFTDECIMALDIGIT))
        (#.+char-attr-constituent-dot+ (go FRONTDOT))
        (#.+char-attr-escape+ (go ESCAPE))
        (#.+char-attr-package-delimiter+ (go COLON))
            possibly-float t)
       (case (char-class3 char attribute-table)
        (#.+char-attr-constituent-digit+ (go LEFTDIGIT))
+       (#.+char-attr-constituent-digit-or-expt+
+        (setq seen-digit-or-expt t)
+        (go LEFTDIGIT))
+       (#.+char-attr-constituent-decimal-digit+ (go LEFTDECIMALDIGIT))
        (#.+char-attr-constituent-dot+ (go SIGNDOT))
        (#.+char-attr-escape+ (go ESCAPE))
        (#.+char-attr-package-delimiter+ (go COLON))
       (ouch-read-buffer char)
       (setq char (read-char stream nil nil))
       (unless char (return (make-integer)))
+      (setq was-possibly-float possibly-float)
       (case (char-class3 char attribute-table)
        (#.+char-attr-constituent-digit+ (go LEFTDIGIT))
+       (#.+char-attr-constituent-decimal-digit+ (if possibly-float
+                                                    (go LEFTDECIMALDIGIT)
+                                                    (go SYMBOL)))
        (#.+char-attr-constituent-dot+ (if possibly-float
                                           (go MIDDLEDOT)
                                           (go SYMBOL)))
-       (#.+char-attr-constituent-expt+ (go EXPONENT))
+       (#.+char-attr-constituent-digit-or-expt+
+        (if (or seen-digit-or-expt (not was-possibly-float))
+            (progn (setq seen-digit-or-expt t) (go LEFTDIGIT))
+            (progn (setq seen-digit-or-expt t) (go LEFTDIGIT-OR-EXPT))))
+       (#.+char-attr-constituent-expt+
+        (if was-possibly-float
+            (go EXPONENT)
+            (go SYMBOL)))
+       (#.+char-attr-constituent-slash+ (if possibly-rational
+                                            (go RATIO)
+                                            (go SYMBOL)))
+       (#.+char-attr-delimiter+ (unread-char char stream)
+                                (return (make-integer)))
+       (#.+char-attr-escape+ (go ESCAPE))
+       (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
+       (#.+char-attr-package-delimiter+ (go COLON))
+       (t (go SYMBOL)))
+     LEFTDIGIT-OR-EXPT
+      (ouch-read-buffer char)
+      (setq char (read-char stream nil nil))
+      (unless char (return (make-integer)))
+      (case (char-class3 char attribute-table)
+       (#.+char-attr-constituent-digit+ (go LEFTDIGIT))
+       (#.+char-attr-constituent-decimal-digit+ (bug "impossible!"))
+       (#.+char-attr-constituent-dot+ (go SYMBOL))
+       (#.+char-attr-constituent-digit-or-expt+ (go LEFTDIGIT))
+       (#.+char-attr-constituent-expt+ (go SYMBOL))
+       (#.+char-attr-constituent-sign+ (go EXPTSIGN))
        (#.+char-attr-constituent-slash+ (if possibly-rational
                                             (go RATIO)
                                             (go SYMBOL)))
        (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
        (#.+char-attr-package-delimiter+ (go COLON))
        (t (go SYMBOL)))
+     LEFTDECIMALDIGIT ; saw "[sign] {decimal-digit}+"
+      (aver possibly-float)
+      (ouch-read-buffer char)
+      (setq char (read-char stream nil nil))
+      (unless char (go RETURN-SYMBOL))
+      (case (char-class char attribute-table)
+       (#.+char-attr-constituent-digit+ (go LEFTDECIMALDIGIT))
+       (#.+char-attr-constituent-dot+ (go MIDDLEDOT))
+       (#.+char-attr-constituent-expt+ (go EXPONENT))
+       (#.+char-attr-constituent-slash+ (aver (not possibly-rational))
+                                        (go SYMBOL))
+       (#.+char-attr-delimiter+ (unread-char char stream)
+                                (go RETURN-SYMBOL))
+       (#.+char-attr-escape+ (go ESCAPE))
+       (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
+       (#.+char-attr-package-delimiter+ (go COLON))
+       (t (go SYMBOL)))
      MIDDLEDOT ; saw "[sign] {digit}+ dot"
       (ouch-read-buffer char)
       (setq char (read-char stream nil nil))
        (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
        (#.+char-attr-package-delimiter+ (go COLON))
        (t (go SYMBOL)))
-     RIGHTDIGIT ; saw "[sign] {digit}* dot {digit}+"
+     RIGHTDIGIT ; saw "[sign] {decimal-digit}* dot {digit}+"
       (ouch-read-buffer char)
       (setq char (read-char stream nil nil))
       (unless char (return (make-float stream)))
       (ouch-read-buffer char)
       (setq char (read-char stream nil nil))
       (unless char (go RETURN-SYMBOL))
+      (setq possibly-float t)
       (case (char-class char attribute-table)
        (#.+char-attr-constituent-sign+ (go EXPTSIGN))
        (#.+char-attr-constituent-digit+ (go EXPTDIGIT))
                 (#.+char-attr-package-delimiter+ (done-with-fast-read-char)
                                                  (go COLON))
                 (t (go SYMBOL-LOOP)))))
-           ;; fundamental-stream
+           ;; CLOS stream
            (prog ()
             SYMBOL-LOOP
             (ouch-read-buffer char)
-            (setq char (stream-read-char stream))
+            (setq char (read-char stream nil :eof))
             (when (eq char :eof) (go RETURN-SYMBOL))
             (case (char-class char attribute-table)
               (#.+char-attr-escape+ (go ESCAPE))
-              (#.+char-attr-delimiter+ (stream-unread-char stream char)
+              (#.+char-attr-delimiter+ (unread-char char stream)
                            (go RETURN-SYMBOL))
               (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
               (#.+char-attr-package-delimiter+ (go COLON))
                                  (#\F 'single-float)
                                  (#\D 'double-float)
                                  (#\L 'long-float)))
-                 num)
-            ;; Raymond Toy writes: We need to watch out if the
-            ;; exponent is too small or too large. We add enough to
-            ;; EXPONENT to make it within range and scale NUMBER
-            ;; appropriately. This should avoid any unnecessary
-            ;; underflow or overflow problems.
-            (multiple-value-bind (min-expo max-expo)
-                ;; FIXME: These forms are broken w.r.t.
-                ;; cross-compilation portability, as the
-                ;; cross-compiler will call the host's LOG function
-                ;; while attempting to constant-fold. Maybe some sort
-                ;; of load-time-form magic could be used instead?
-                (case float-format
-                  ((short-float single-float)
-                   (values
-                    (log sb!xc:least-positive-normalized-single-float 10f0)
-                    (log sb!xc:most-positive-single-float 10f0)))
-                  ((double-float #!-long-float long-float)
-                   (values
-                    (log sb!xc:least-positive-normalized-double-float 10d0)
-                    (log sb!xc:most-positive-double-float 10d0)))
-                  #!+long-float
-                  (long-float
-                   (values
-                    (log sb!xc:least-positive-normalized-long-float 10l0)
-                    (log sb!xc:most-positive-long-float 10l0))))
-              (let ((correction (cond ((<= exponent min-expo)
-                                       (ceiling (- min-expo exponent)))
-                                      ((>= exponent max-expo)
-                                       (floor (- max-expo exponent)))
-                                      (t
-                                       0))))
-                (incf exponent correction)
-                (setf number (/ number (expt 10 correction)))
-                (setq num (make-float-aux number divisor float-format stream))
-                (setq num (* num (expt 10 exponent)))
-                (return-from make-float (if negative-fraction
-                                            (- num)
-                                            num))))))
-         ;; should never happen
+                 (result (make-float-aux (* (expt 10 exponent) number)
+                                         divisor float-format stream)))
+            (return-from make-float
+              (if negative-fraction (- result) result))))
          (t (bug "bad fallthrough in floating point reader")))))
 
 (defun make-float-aux (number divisor float-format stream)
               `(error 'simple-parse-error
                       :format-control ,format-control
                       :format-arguments (list string))))
-    (with-array-data ((string string)
+    (with-array-data ((string string :offset-var offset)
                      (start start)
                      (end (%check-vector-sequence-bounds string start end)))
       (let ((index (do ((i start (1+ i)))
                        found-digit t))
                 (junk-allowed (return nil))
                 ((whitespacep char)
-                 (do ((jndex (1+ index) (1+ jndex)))
-                     ((= jndex end))
-                   (declare (fixnum jndex))
-                   (unless (whitespacep (char string jndex))
+                  (loop
+                   (incf index)
+                   (when (= index end) (return))
+                   (unless (whitespacep (char string index))
                      (parse-error "junk in string ~S")))
                  (return nil))
                 (t
             (if junk-allowed
                 nil
                 (parse-error "no digits in string ~S")))
-        index)))))
+        (- index offset))))))
 \f
 ;;;; reader initialization code