make feature guard produce nothing on eof/closing bracket/paren
A dropped datum is replaced by whatever follows it, but what follows may be the end of the file or the paren closing the list we are in. Hand the token back to the caller instead: read-list closes its list with it and the toplevel loop stops. A `;' comment between a guard and the form it guards was also taken for the guarded datum, so the form stayed unconditional and the guard did nothing. Skip comments when reading the guard. comment-form? was defined three times over; it moves to utils.
This commit is contained in:
38
reader.scm
38
reader.scm
@@ -115,6 +115,21 @@
|
||||
((eq? tok dot-token) (error "Unexpected ."))
|
||||
(else tok))))
|
||||
|
||||
;;; A token that stands for a datum
|
||||
(define (datum-token? tok)
|
||||
(not (or (eof-object? tok)
|
||||
(eq? tok close-paren)
|
||||
(eq? tok close-bracket)
|
||||
(eq? tok dot-token))))
|
||||
|
||||
;;; next-token, sans the comments
|
||||
(define (next-code-token port)
|
||||
(let loop ()
|
||||
(let ((tok (next-token port)))
|
||||
(if (comment-form? tok)
|
||||
(loop)
|
||||
tok))))
|
||||
|
||||
;;; Read list elements up to close-paren or close-bracket,
|
||||
;;; honoring dotted-pair notation (a b . c)
|
||||
(define (read-list port closer)
|
||||
@@ -208,13 +223,24 @@
|
||||
(else (error "Malformed feature expression" test))))
|
||||
|
||||
;;; The #-/#+ preceded datum is always read -- there is no other way
|
||||
;;; to know where it ends -- and then either returned or dropped
|
||||
;;; to know where it ends -- and then either returned or dropped. What
|
||||
;;; follows a dropped datum is read in its place: `#+x #+y (a) (b)'
|
||||
;;; with only x is (b).
|
||||
;;;
|
||||
;;; That next thing may be nothing: the end of the file, or the
|
||||
;;; paren closing the list we are in
|
||||
(define (read-conditional port keep-when)
|
||||
(let ((keep (eq? keep-when (feature-true? (read-datum port)))))
|
||||
(if keep
|
||||
(read-datum port)
|
||||
(begin (read-datum port)
|
||||
(next-token port)))))
|
||||
(let* ((test (next-code-token port))
|
||||
(keep (begin
|
||||
(unless (datum-token? test)
|
||||
(error "Unexpected end of input in feature expression"))
|
||||
(eq? keep-when (feature-true? test))))
|
||||
(guarded (next-code-token port)))
|
||||
(cond
|
||||
(keep guarded)
|
||||
;; A datum was dropped, so the next one stands in for it
|
||||
((datum-token? guarded) (next-token port))
|
||||
(else guarded))))
|
||||
|
||||
;;; #t / #true / #f / #false. `val' is the boolean; consume any
|
||||
;;; trailing name characters and validate
|
||||
|
||||
Reference in New Issue
Block a user