Skip to content

Commit

Permalink
waterhouse's bugfix for mutable pairs: http://arclanguage.org/item?id…
Browse files Browse the repository at this point in the history
  • Loading branch information
akkartik committed Feb 4, 2011
1 parent b36f223 commit cea8a4c
Showing 1 changed file with 19 additions and 30 deletions.
49 changes: 19 additions & 30 deletions ac.scm
Expand Up @@ -1262,42 +1262,31 @@
(x-set-cdr! x val)) (x-set-cdr! x val))
val)) val))


; decide at run-time whether the underlying mzscheme supports ; waterhouse's code to modify mzscheme-4's immutable pairs.
; set-car! and set-cdr!, since I can't figure out how to do it ; http://arclanguage.org/item?id=13616
; at compile time. (require racket/unsafe/ops)


(define (x-set-car! p v) (define (set-ca/dr! offset who p x)
(if (pair? p)
(unsafe-vector-set! p offset x)
(raise-type-error who "pair" p)))

(define (n-set-car! p x)
(set-ca/dr! -1 'set-car! p x))
(define (n-set-cdr! p x)
(set-ca/dr! 0 'set-cdr! p x))

(define x-set-car!
(let ((fn (namespace-variable-value 'set-car! #t (lambda () #f)))) (let ((fn (namespace-variable-value 'set-car! #t (lambda () #f))))
(if (procedure? fn) (if (procedure? fn)
(fn p v) fn
(n-set-car! p v)))) n-set-car!)))


(define (x-set-cdr! p v) (define x-set-cdr!
(let ((fn (namespace-variable-value 'set-cdr! #t (lambda () #f)))) (let ((fn (namespace-variable-value 'set-cdr! #t (lambda () #f))))
(if (procedure? fn) (if (procedure? fn)
(fn p v) fn
(n-set-cdr! p v)))) n-set-cdr!)))

; Eli's code to modify mzscheme-4's immutable pairs.

;; to avoid a malloc on every call, reuse a single pointer, but make
;; it thread-local to avoid races
(define ptr (make-thread-cell #f))
(define (get-ptr)
(or (thread-cell-ref ptr)
(let ([p (malloc _scheme 1)]) (thread-cell-set! ptr p) p)))

;; set a pointer to the cons cell, then dereference it as a pointer,
;; and bang the new value in the given offset
(define (set-ca/dr! offset who p x)
(if (pair? p)
(let ([p* (get-ptr)])
(ptr-set! p* _scheme p)
(ptr-set! (ptr-ref p* _pointer 0) _scheme offset x))
(raise-type-error who "pair" p)))

(define (n-set-car! p x) (set-ca/dr! 1 'set-car! p x))
(define (n-set-cdr! p x) (set-ca/dr! 2 'set-cdr! p x))


; When and if cdr of a string returned an actual (eq) tail, could ; When and if cdr of a string returned an actual (eq) tail, could
; say (if (string? x) (string-replace! x val 1) ...) in scdr, but ; say (if (string? x) (string-replace! x val 1) ...) in scdr, but
Expand Down

0 comments on commit cea8a4c

Please sign in to comment.