~ chicken-core (chicken-5) b5c8d59e83b7c654e6f79dee91476470ac07b882
commit b5c8d59e83b7c654e6f79dee91476470ac07b882 Author: felix <felix@call-with-current-continuation.org> AuthorDate: Tue Mar 16 16:12:04 2010 +0100 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Tue Mar 16 16:12:04 2010 +0100 define-record-type allows using setters for modifier; added testcase diff --git a/chicken-syntax.scm b/chicken-syntax.scm index 8e15d715..67258488 100644 --- a/chicken-syntax.scm +++ b/chicken-syntax.scm @@ -900,10 +900,13 @@ (##sys#extend-macro-environment 'define-record-type - `((getter-with-setter . (##sys#primitive-alias 'getter-with-setter))) + `((getter-with-setter . ,(##sys#primitive-alias 'getter-with-setter))) (##sys#er-transformer (lambda (form r c) - (##sys#check-syntax 'define-record-type form '(_ variable #(variable 1) variable . _)) + (##sys#check-syntax + 'define-record-type + form + '(_ variable #(variable 1) variable . _)) (let* ((t (cadr form)) (conser (caddr form)) (pred (cadddr form)) @@ -930,21 +933,42 @@ ,@(let loop ([slots slots] [i 1]) (if (null? slots) '() - (let* ([slot (car slots)] - (setters (memq #:record-setters ##sys#features)) - (setr? (pair? (cddr slot))) - (getr `(,%lambda (,x) - (##core#check (##sys#check-structure ,x (,%quote ,t))) - (##sys#block-ref ,x ,i) ) ) ) - `(,@(if setr? - `((,%define (,(caddr slot) ,x ,y) - (##core#check (##sys#check-structure ,x (,%quote ,t))) - (##sys#block-set! ,x ,i ,y)) ) - '() ) - (,%define ,(cadr slot) - ,(if (and setr? setters) - `(,%getter-with-setter ,getr ,(caddr slot)) - getr) ) + (let* ((slot (car slots)) + (settable (pair? (cddr slot))) + (setr (and settable (caddr slot))) + (ssetter (and (pair? setr) + (pair? (cdr setr)) + (c 'setter (car setr)) + (cadr setr))) + (get `(,%lambda + (,x) + (##core#check + (##sys#check-structure + ,x + (,%quote ,t) + (,%quote ,(cadr slot)))) + (##sys#block-ref ,x ,i) ) ) + (set (and settable + `(,%lambda + (,x ,y) + (##core#check + (##sys#check-structure + ,x + (,%quote ,t) + (,%quote ,ssetter))) + (##sys#block-set! ,x ,i ,y)) ))) + `((,%define + ,(cadr slot) + ,(if (and ssetter (c ssetter (cadr slot))) + `(,%getter-with-setter ,get ,set) + get)) + ,@(if settable + (if ssetter + (if (not (c ssetter (cadr slot))) + `(((##sys#setter ##sys#setter) ,ssetter ,set)) + '()) + `((,%define ,setr ,set))) + '()) ,@(loop (cdr slots) (add1 i)) ) ) ) ) ) ) ) ) ) diff --git a/distribution/manifest b/distribution/manifest index 3aa8723b..ae8b04f6 100644 --- a/distribution/manifest +++ b/distribution/manifest @@ -167,6 +167,7 @@ tests/test.tex tests/slatex.sty tests/symbolgc-tests.scm tests/private-repository-test.scm +tests/records-and-setters-test.scm tweaks.scm utils.scm apply-hack.x86.S diff --git a/expand.scm b/expand.scm index 1df2b394..bd37221c 100644 --- a/expand.scm +++ b/expand.scm @@ -57,7 +57,7 @@ (no-procedure-checks))) (else)) -#;(begin +(begin (define-syntax dd (syntax-rules () ((_ . _) (void)))) (define-syntax dm (syntax-rules () ((_ . _) (void)))) (define-syntax dc (syntax-rules () ((_ . _) (void)))) ) diff --git a/manual/Non-standard macros and special forms b/manual/Non-standard macros and special forms index 96db2094..d6df43d2 100644 --- a/manual/Non-standard macros and special forms +++ b/manual/Non-standard macros and special forms @@ -397,6 +397,11 @@ and updated using {{(NAME-SLOTNAME-set!}} {{STRUCT}} {{VALUE)}}. SRFI-9 record types. For more information see the documentation for [[http://srfi.schemers.org/srfi-9/srfi-9.html|SRFI-9]]. +As an extension the {{MODIFIER}} may have the form {{(setter PROCEDURE)}}, +which will define a SRFI-17 setter-procedure for the given {{PROCEDURE}} +that sets the field value. Usually {{PROCEDURE}} has the same name +is {{ACCESSOR}} (but it doesn't have to). + ==== define-record-printer diff --git a/tests/dirty-macros.scm b/tests/dirty-macros.scm index 80fd6556..d6f9490b 100644 --- a/tests/dirty-macros.scm +++ b/tests/dirty-macros.scm @@ -1119,17 +1119,17 @@ ((lambda (v) (let* rest . bodies)) i)))) ; ((_ . args) (glet* (let let* letrec lambda) . args)))) -;(display (let* ((foo 2)) (list foo (mm "mm")))) +(display (let* ((foo 2)) (list foo (mm "mm")))) -; (display -; (let* ((foo 2) -; (i 3) -; (foo 4) -; (ft (lambda () (mm "mm"))) ; will capture binding of foo to 4 -; (foo 5) -; (ft1 (lambda (foo) (mm "mm"))) ; will capture the arg of ft1 -; (foo 6)) -; (list foo (mm "mm") (ft) (ft1 7) '(mm "mm")))) +(display + (let* ((foo 2) + (i 3) + (foo 4) + (ft (lambda () (mm "mm"))) ; will capture binding of foo to 4 + (foo 5) + (ft1 (lambda (foo) (mm "mm"))) ; will capture the arg of ft1 + (foo 6)) + (list foo (mm "mm") (ft) (ft1 7) '(mm "mm")))) (newline) ; ==> (6 6 4 7 (mm)) diff --git a/tests/records-and-setters-test.scm b/tests/records-and-setters-test.scm new file mode 100644 index 00000000..3840d7e3 --- /dev/null +++ b/tests/records-and-setters-test.scm @@ -0,0 +1,23 @@ +;;;; records-and-setters-test.scm + + +;;; define-record-type with setters + +(define-record-type foo + (make-foo x y z t) + foo? + (x get-x) + (y get-y set-y) + (z get-z (setter get-z)) + (t get-t (setter make-foo))) + +(let ((f (make-foo 1 2 3 4))) + (assert (foo? f)) + (assert (= 1 (get-x f))) + (assert (= 2 (get-y f))) + (set-y f 99) + (assert (= 99 (get-y f))) + (set! (get-z f) 100) + (assert (= 100 (get-z f))) + (set! (make-foo f) 1000) + (assert (= 1000 (get-t f)))) diff --git a/tests/runtests.sh b/tests/runtests.sh index e95fe19a..6edcfd61 100644 --- a/tests/runtests.sh +++ b/tests/runtests.sh @@ -70,6 +70,9 @@ $compile test-gc-hooks.scm echo "======================================== library tests ..." $interpret -s library-tests.scm +$interpret -s records-and-setters-test.scm +$compile records-and-setters-test.scm +./a.out echo "======================================== syntax tests ..." $interpret -s syntax-tests.scm @@ -211,6 +214,9 @@ echo "======================================== locative stress test ..." $compile locative-stress-test.scm ./a.out +echo "======================================== syntax-rules stress test ..." +time $interpret syntax-rule-stress-test.scm + echo "======================================== embedding (1) ..." $compile embedded1.c ./a.outTrap