ls-read and ls-read-from-string handles empty input
authorDavid Vázquez <davazp@gmail.com>
Thu, 25 Apr 2013 14:52:04 +0000 (15:52 +0100)
committerDavid Vázquez <davazp@gmail.com>
Thu, 25 Apr 2013 14:52:04 +0000 (15:52 +0100)
Add EOF-ERROR-P and EOF-VALUE arguments.

It fixes #18

ecmalisp.lisp
src/read.lisp

index eae3ab6..855d813 100644 (file)
@@ -55,8 +55,9 @@
            (in (make-string-stream source)))
       (format t "Compiling ~a...~%" filename)
       (loop
-         for x = (ls-read in)
-         until (eq x *eof*)
+         with eof-mark = (gensym)
+         for x = (ls-read in nil eof-mark)
+         until (eq x eof-mark)
          for compilation = (ls-compile-toplevel x)
          when (plusp (length compilation))
          do (write-string compilation out)))))
index bbd2586..39aa7f5 100644 (file)
        nil)
       ((char= ch #\.)
        (%read-char stream)
-       (prog1 (ls-read stream)
+       (prog1 (ls-read-1 stream)
          (skip-whitespaces-and-comments stream)
          (unless (char= (%read-char stream) #\))
            (error "')' was expected."))))
       (t
-       (cons (ls-read stream) (%read-list stream))))))
+       (cons (ls-read-1 stream) (%read-list stream))))))
 
 (defun read-string (stream)
   (let ((string "")
   (%read-char stream)
   (ecase (%read-char stream)
     (#\'
-     (list 'function (ls-read stream)))
+     (list 'function (ls-read-1 stream)))
     (#\( (list-to-vector (%read-list stream)))
     (#\: (make-symbol (string-upcase (read-until stream #'terminalp))))
     (#\\
      (let ((feature (read-until stream #'terminalp)))
        (cond
          ((string= feature "common-lisp")
-          (ls-read stream)              ;ignore
-          (ls-read stream))
+          (ls-read-1 stream)              ;ignore
+          (ls-read-1 stream))
          ((string= feature "ecmalisp")
-          (ls-read stream))
+          (ls-read-1 stream))
          (t
           (error "Unknown reader form.")))))))
 
       (error "junk detected."))))
 
 (defvar *eof* (gensym))
-(defun ls-read (stream)
+(defun ls-read-1 (stream)
   (skip-whitespaces-and-comments stream)
   (let ((ch (%peek-char stream)))
     (cond
        (%read-list stream))
       ((char= ch #\')
        (%read-char stream)
-       (list 'quote (ls-read stream)))
+       (list 'quote (ls-read-1 stream)))
       ((char= ch #\`)
        (%read-char stream)
-       (list 'backquote (ls-read stream)))
+       (list 'backquote (ls-read-1 stream)))
       ((char= ch #\")
        (%read-char stream)
        (read-string stream))
       ((char= ch #\,)
        (%read-char stream)
        (if (eql (%peek-char stream) #\@)
-           (progn (%read-char stream) (list 'unquote-splicing (ls-read stream)))
-           (list 'unquote (ls-read stream))))
+           (progn (%read-char stream) (list 'unquote-splicing (ls-read-1 stream)))
+           (list 'unquote (ls-read-1 stream))))
       ((char= ch #\#)
        (read-sharp stream))
       (t
         (or (values (!parse-integer string nil))
             (read-symbol string)))))))
 
-(defun ls-read-from-string (string)
-  (ls-read (make-string-stream string)))
+(defun ls-read (stream &optional (eof-error-p t) eof-value)
+  (let ((x (ls-read-1 stream)))
+    (if (eq x *eof*)
+        (if eof-error-p (error "EOF") eof-value)
+        x)))
+
+(defun ls-read-from-string (string &optional (eof-error-p t) eof-value)
+  (ls-read (make-string-stream string) eof-error-p eof-value))