Hold the saved values weakly.

This commit is contained in:
Eli Barzilay 2011-08-26 06:39:28 -04:00
parent cc82506be5
commit cda4479d1e
4 changed files with 24 additions and 5 deletions

View File

@ -87,6 +87,9 @@
4 4
-> «(list ^ ^^ ^^^ ^^^^)» -> «(list ^ ^^ ^^^ ^^^^)»
'(4 3 2 1) '(4 3 2 1)
-> «(collect-garbage)»
-> «^»
; ^: saved value #1 was garbage-collected [,bt for context]
-> «(module foo racket (define x 123))» -> «(module foo racket (define x 123))»
-> «,en foo» -> «,en foo»
'foo> «x» 'foo> «x»

View File

@ -49,7 +49,12 @@
[else (err "unknown name pattern for a saved-value reference")])) [else (err "unknown name pattern for a saved-value reference")]))
(unless (pair? saved) (err "no saved values, yet")) (unless (pair? saved) (err "no saved values, yet"))
(when (n . > . (length saved)) (err "no ~a saved values, yet" n)) (when (n . > . (length saved)) (err "no ~a saved values, yet" n))
#`'#,(list-ref saved (sub1 n))) ;; the values are either `#f', or a weak box holding the value
(define r
(let ([b (list-ref saved (sub1 n))])
(and b (or (weak-box-value b)
(err "saved value #~a was garbage-collected" n)))))
#`'#,r)
(syntax-case stx (set!) (syntax-case stx (set!)
[(set! id . xs) (raise-syntax-error 'set! "cannot set history reference")] [(set! id . xs) (raise-syntax-error 'set! "cannot set history reference")]
[(id . xs) (datum->syntax stx (cons (ref #'id) #'xs) stx)] [(id . xs) (datum->syntax stx (cons (ref #'id) #'xs) stx)]

View File

@ -1198,7 +1198,8 @@
;; saved interaction values (can be #f to disable saving) ;; saved interaction values (can be #f to disable saving)
(define saved-values (make-parameter '())) (define saved-values (make-parameter '()))
(define (save-values! xs) (define (save-values! xs)
(let ([xs (filter (λ (x) (not (void? x))) xs)]) ; don't save void values (let* ([xs (filter (λ (x) (not (void? x))) xs)] ; don't save void values
[xs (map (λ (x) (and x (make-weak-box x))) xs)]) ; save weakly
(unless (null? xs) (unless (null? xs)
;; the order is last, 2nd-to-last, ..., same from prev interactions ;; the order is last, 2nd-to-last, ..., same from prev interactions
;; the idea is that `^', `^^', etc refer to the values as displayed ;; the idea is that `^', `^^', etc refer to the values as displayed

View File

@ -451,9 +451,19 @@ The rationale for this is that @racketidfont{^} always refers to the
last @emph{printed} result, @racketidfont{^^} to the one before that, last @emph{printed} result, @racketidfont{^^} to the one before that,
etc. etc.
These bindings are made available only if they are not already defined, The bindings are made available only if they are not already defined.
and if they are not modified. This means that if you have code that This means that if you have code that uses these names, it will continue
uses these names, it will continue to work as usual. to work as usual.
The bindings are identifier macros that expand to the literal saved
values; so referring to a saved value that is missing (because not
enough values were shown) raises a syntax error. In addition, the
values are held in a @tech{weak reference}, so they can disappear after
a garbage-collection.
Note that this facility can be used to ``transfer'' values from one
namespace to another---but beware of struct values that might come from
a different instantiation of a module.
@; --------------------------------------------------------------------- @; ---------------------------------------------------------------------
@section{Hacking XREPL} @section{Hacking XREPL}