This repository has been archived by the owner on Dec 5, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Automatic commit at Mon May 27 12:00:01 MDT 2013
- Loading branch information
1 parent
6d6cf80
commit a735aa6
Showing
1 changed file
with
46 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#lang racket/base | ||
(require racket/list) | ||
|
||
(struct posn (x y) #:transparent) | ||
(struct 3posn posn (z) #:transparent #:mutable) | ||
|
||
(define (dynamic-duplicate s) | ||
(define-values (s-type skipped?) (struct-info s)) | ||
(when (or (not s-type) skipped?) | ||
(error 'dynamic-duplicate | ||
"Can't duplicate... structure not open")) | ||
|
||
(define ctor (struct-type-make-constructor s-type)) | ||
|
||
(apply ctor | ||
(reverse | ||
(let loop ([t s-type] [skipped? skipped?]) | ||
(cond | ||
[(and t (not skipped?)) | ||
(define-values (name this-count _auto | ||
this-ref mutator immutable-idxs | ||
super super-skipped?) | ||
(struct-type-info t)) | ||
(append (for/list ([i (in-range 0 this-count)]) | ||
(this-ref s (- (sub1 this-count) i))) | ||
(loop super super-skipped?))] | ||
[(and (not t) (not skipped?)) | ||
empty] | ||
[else | ||
(error 'dynamic-duplicate | ||
"Can't duplicate... parent structure not open")]))))) | ||
|
||
(module+ test | ||
(require rackunit) | ||
(define p1 (3posn 1 2 3)) | ||
(define p2 (dynamic-duplicate p1)) | ||
|
||
(set-3posn-z! p1 4) | ||
|
||
(check-equal? (posn-x p1) 1) | ||
(check-equal? (posn-y p1) 2) | ||
(check-equal? (3posn-z p1) 4) | ||
|
||
(check-equal? (posn-x p2) 1) | ||
(check-equal? (posn-y p2) 2) | ||
(check-equal? (3posn-z p2) 3)) |