read: properly restore state when reading datum comments

This commit is contained in:
Peter McGoron 2024-09-27 12:26:26 -04:00
parent 5b609d4cdf
commit 0547488917
1 changed files with 20 additions and 8 deletions

View File

@ -91,6 +91,9 @@
(get-datum-label (get-datum-label
(lambda (label) (lambda (label)
(smap:search datum-labels label))) (smap:search datum-labels label)))
(clear-datum-labels!
(lambda ()
(set! datum-labels '())))
(dump-mutable (dump-mutable
(lambda () (lambda ()
(list datum-labels fold-case?))) (list datum-labels fold-case?)))
@ -133,6 +136,9 @@
((eq? op 'fold-case!) (set! fold-case? (car args))) ((eq? op 'fold-case!) (set! fold-case? (car args)))
((eq? op 'set-datum-label!) (apply set-datum-label! args)) ((eq? op 'set-datum-label!) (apply set-datum-label! args))
((eq? op 'get-datum-label) (apply get-datum-label args)) ((eq? op 'get-datum-label) (apply get-datum-label args))
((eq? op 'clear-datum-labels!) (apply clear-datum-labels! args))
((eq? op 'dump-mutable) (apply dump-mutable args))
((eq? op 'restore-mutable!) (apply restore-mutable! args))
(else (error 'read->port 'invalid (cons op args))))))) (else (error 'read->port 'invalid (cons op args)))))))
port)))) port))))
@ -582,12 +588,13 @@
;;; Reads the next toplevel datum, discards it, and then continues at the ;;; Reads the next toplevel datum, discards it, and then continues at the
;;; toplevel. ;;; toplevel.
;;; ;;;
;;; TODO: The R7RS reader can cause side-effects due to #!FOLD-CASE. This ;;; The R7RS reader can cause side-effects due to #!FOLD-CASE and datum
;;; must be supressed in datum comments. A method could be added to PORT ;;; labels. This must be supressed in datum comments.
;;; that saves and restores mutable state (besides stream position).
(define readtable:datum-comment (define readtable:datum-comment
(lambda (_ __ toplevel port) (lambda (_ __ toplevel port)
(let ((mutable (port 'dump-mutable)))
(readtable:next toplevel #f port) (readtable:next toplevel #f port)
(port 'restore-mutable! mutable))
(readtable:next toplevel #f port))) (readtable:next toplevel #f port)))
(define readtable:hash (define readtable:hash
@ -623,6 +630,14 @@
(list readtable:update #\; (list readtable:update #\;
(readtable:jump-discard readtable:read-to-newline))))) (readtable:jump-discard readtable:read-to-newline)))))
(define read/toplevel
(lambda (port)
;; Does each invocation of READ keep datum labels from previous reads?
;; (port 'clear-datum-labels!)
(readtable:next (readtable:top)
#f
port)))
(define intset:insert (set:insert (set:update integer<=>))) (define intset:insert (set:insert (set:update integer<=>)))
(define intset:in (set:in integer<=>)) (define intset:in (set:in integer<=>))
@ -681,10 +696,7 @@
(lambda () (lambda ()
(if (not (reader 'peek)) (if (not (reader 'peek))
#t #t
(let ((value (readtable:act (let ((value (read/toplevel reader)))
(readtable:top) (reader 'read)
#f
reader)))
(display (list "return" (uncycle value))) (display (list "return" (uncycle value)))
(newline) (newline)
(loop)))))) (loop))))))